文章的目的为了记录.net mvc学习的经历。本职为嵌入式软件开发,公司安排开发文件系统,临时进行学习开发,系统上线3年未出没有大问题。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
嵌入式 .net mvc 开发(一)WEB搭建-CSDN博客
嵌入式 .net mvc 开发(二)网站快速搭建-CSDN博客
嵌入式 .net mvc 开发(三)网站内外网访问-CSDN博客
嵌入式 .net mvc 开发(四)工程结构、页面提交显示-CSDN博客
嵌入式 .net mvc 开发(五)常用代码快速开发-CSDN博客
推荐链接:
开源 java android app 开发(一)开发环境的搭建-CSDN博客
开源 java android app 开发(二)工程文件结构-CSDN博客
开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客
开源 java android app 开发(四)GUI界面重要组件-CSDN博客
开源 java android app 开发(五)文件和数据库存储-CSDN博客
开源 java android app 开发(六)多媒体使用-CSDN博客
开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客
开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客
开源 java android app 开发(九)后台之线程和服务-CSDN博客
开源 java android app 开发(十)广播机制-CSDN博客
开源 java android app 开发(十一)调试、发布-CSDN博客
开源 java android app 开发(十二)封库.aar-CSDN博客
在上个章节里,介绍常用代码,来开发速度,减少大家查找的时间。
本章的主要内容为特殊且可能用到的代码。
具体内容如下:
1.服务器上CMD控制台控制第三方程序运行的办法。
2.服务器周期任务编写。
3.服务器中使用搜狐SMTP邮箱发送邮件的办法。
一、服务器上第三方程序的运行,在有些时候我们需要用到第三方的程序,比如创建记事本,使用编译器编译代码等。这个时候要想让这些程序运行起来,通常需要用到控制台,这里就采用.bat脚本调用CMD控制来控制第三方程序。
1.1 以下为.net mvc源代码,该函数实现了工程根目录下运行.bat脚本的功能。
public bool batRun(string path)
{
// 指定批处理文件路径
//string batFilePath = Server.MapPath("~/Scripts/build_keil.bat");
;
string batFilePath = Server.MapPath("~/File/" + path);
// 创建进程启动信息
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = batFilePath,
WorkingDirectory = Path.GetDirectoryName(batFilePath),
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
// 启动进程
try
{
using (Process process = Process.Start(psi))
{
// 读取输出(可选)
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();
process.WaitForExit();
ViewBag.Message = "批处理执行完成。输出: " + output;
if (!string.IsNullOrEmpty(errors))
{
ViewBag.Error = "错误: " + errors;
}
else
{
return true;
}
}
}
catch (Exception ex)
{
ViewBag.Error = "执行批处理时出错: " + ex.Message;
}
return false;
}
1.2 以下代码为build_keil.bat代码,通过该代码调用了程序编译器keil,编译指定工程。
@echo off
chcp 65001 > nul
cd /d "%~dp0"
set UV_PATH="C:\Keil_v5\UV4\UV4.exe"
set PROJECT="C:\Users\Administrator\Desktop\CompileSys\CompileSys\File\Prj\Bldc_Hall\Project\keil\project.uvprojx"
set LOG_FILE="build_log.txt"
echo 正在编译 Keil 工程...
%UV_PATH% -b %PROJECT% -j0 -o %LOG_FILE%
if %errorlevel% equ 0 (
echo 编译成功!
) else (
echo 编译失败,请检查 %LOG_FILE%
)
timeout /t 2
二、定时处理代码,在服务器中通常是客户提交,才会触发服务器返回。但是经常服务器需要进行周期性的任务。
2.1 定义了一个名为 AutoTaskAttribute
的自定义属性类,用于实现基于反射的定时任务调度系统。
2.2 AutoTaskAttribute.cs的具体代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Web;
namespace SaleSystem_20221225.MyClass
{
/// <summary>
/// Author:BigLiang(lmw)
/// Date:2016-12-29
/// </summary>
[AttributeUsage(AttributeTargets.Class)]//表示此Attribute仅可以施加到类元素上
public class AutoTaskAttribute : Attribute
{
/// <summary>
/// 入口程序
/// </summary>
public string EnterMethod { get; set; }
/// <summary>
/// 执行间隔秒数(未设置或0 则只执行一次)
/// </summary>
public int IntervalSeconds { get; set; }
/// <summary>
/// 开始执行日期
/// </summary>
public string StartTime { get; set; }
//保留对Timer 的引用,避免回收
private static Dictionary<AutoTaskAttribute, System.Threading.Timer> timers = new Dictionary<AutoTaskAttribute, System.Threading.Timer>();
/// <summary>
/// Global.asax.cs 中调用
/// </summary>
public static void RegisterTask()
{
//异步执行该方法
new Task(() => StartAutoTask()).Start();
}
/// <summary>
/// 启动定时任务
/// </summary>
private static void StartAutoTask()
{
var types = Assembly.GetExecutingAssembly().ExportedTypes.Where(t => Attribute.IsDefined(t, typeof(AutoTaskAttribute))).ToList();
foreach (var t in types)
{
try
{
var att = (AutoTaskAttribute)Attribute.GetCustomAttribute(t, typeof(AutoTaskAttribute));
if (att != null)
{
if (string.IsNullOrWhiteSpace(att.EnterMethod))
{
throw new Exception("未指定任务入口!EnterMethod");
}
var ins = Activator.CreateInstance(t);
var method = t.GetMethod(att.EnterMethod);
if (att.IntervalSeconds > 0)
{
int duetime = 0; //计算延时时间
if (string.IsNullOrWhiteSpace(att.StartTime))
{
duetime = 1000;
}
else
{
var datetime = DateTime.Parse(att.StartTime);
if (DateTime.Now <= datetime)
{
duetime = (int)(datetime - DateTime.Now).TotalSeconds * 1000;
}
else
{
duetime = att.IntervalSeconds * 1000 - ((int)(DateTime.Now - datetime).TotalMilliseconds) % (att.IntervalSeconds * 1000);
}
}
timers.Add(att, new System.Threading.Timer((o) =>
{
method.Invoke(ins, null);
}, ins, duetime, att.IntervalSeconds * 1000));
}
else
{
method.Invoke(ins, null);
}
}
}
catch (Exception ex)
{
//LogHelper.Error(t.FullName + " 任务启动失败", ex);
Debug.WriteLine(t.FullName + " 任务启动失败", ex);
}
}
}
}
}
2.3 AutoTaskAttribute的使用办法,工程中的控制器代码都是针对页面提交的处理,只有在Global.asax是从服务器启动以后一直运行,所以应该在Global.asax进行使用。
定义"StartTask"函数,定时3600s,1小时
定义StartTask函数处理程序
三、服务器中使用搜狐SMTP邮箱发送邮件的办法。
public string sendEmail(string StrDate)
{
/*
try
{
*/
//发送者邮箱账户
string sendEmail = "XXX@sohu.com";
//发送者邮箱账户授权码
string code = "XXXX";//独立密码
//发件人地址
MailAddress from = new MailAddress(sendEmail);
MailMessage message = new MailMessage();
//收件人地址
message.To.Add("XXX@163.com");
message.To.Add("XXX@163.com");
message.To.Add("XXX@s163.com");
//标题
message.Subject = DateTime.Now.ToString("yyyy-MM-dd") + "送货单";
message.SubjectEncoding = Encoding.UTF8;
message.From = from;
//邮件内容
message.Body = "附件为当天送货单";
message.IsBodyHtml = true;
message.BodyEncoding = Encoding.UTF8;
string strFile = StrDate + ".xlsx";
message.Attachments.Add(new Attachment(@"G:\SaleS\" + strFile ));
//获取或设置此电子邮件的发送通知。
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
SmtpClient client = new SmtpClient();
client.EnableSsl = true;
client.Host = "smtp.sohu.com";//smtp服务器
client.Port = 25;//smtp端口
//发送者邮箱账户和授权码
client.Credentials = new NetworkCredential(sendEmail, code);
client.Send(message);
return "发送成功";
/*
}
catch (Exception e)
{
return e.ToString();
}
*/
}