从零开始编辑一个提醒下班服务
公司里的卷B越来越多了
1.创建一个企业微信机器人
按照提示的步骤来就行了
2.用C#部署一个定时服务
2.1 创建一个定时服务
工具 : VisualStudio 2019
2.1.1。创建一个基本的windows 服务
如果找不到的话用搜索功能找一下
2.1.2.找到Service1.cs,查看并编辑他的代码
添加如下代码
System.Timers.Timer timer1; //计时器
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args) //服务启动执行
{
timer1 = new System.Timers.Timer();
timer1.Interval = 3000; //定时执行事件间隔时间,单位毫秒
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);
timer1.Enabled = true;
}
protected override void OnStop() //服务停止执行
{
this.timer1.Enabled = false;
}
//定时执行事件
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//定时操作,之后在这里添加定时操作
}
2.1.3.添加window服务安装程序
进入Service1.cs 的【设计】页面(双击或者从右键菜单【查看设计器】皆可进入)
右键设计界面,从菜单中选择【添加安装程序】
解决方案中会出现ProjectInstaller.cs,右键进入【设计】界面
选择serviceProcessInstaller1,在【属性】窗口中设置【Account】属性设为【LocalSystem】
选择serviceInstaller1的StartType属性设为【Automatic】
ServiceName 可以设置为自己喜欢的名字
提示
如果找不到属性窗口的话,可以在工具栏的视图窗口中打开
2.1.5 添加安装服务后自启功能(可选)
编辑ProjectInstaller.cs 代码
public ProjectInstaller()
{
InitializeComponent();
this.Committed += new InstallEventHandler(ProjectInstaller_Committed);
}
private void ProjectInstaller_Committed(object sender, InstallEventArgs e)
{
//参数为服务的名字,ServiceName
System.ServiceProcess.ServiceController controller = new System.ServiceProcess.ServiceController("服务名称");
controller.Start();
}
2.1.6 生成并安装服务
运行VS的终端
通过命令 installutil <你生成的服务路径>.exe
安装服务
2.1.7 查看服务状态
控制面板–>管理工具–>服务
或者通过 Win + R 呼出运行窗口 通过services.msc 打开服务窗口
参考文章:https://developer.aliyun.com/article/334760
微软安装服务程序
2.2 将定时服务与企业微信机器人对接
2.2.1 添加发送消息功能
回到Service1 的代码编写窗口
添加如下代码
string url = "企业微信机器人给你的webhook地址";
/// 发送消息到企业微信机器人
private void SendMessage(string msg)
{
Dictionary<string, object> post = new Dictionary<string, object>();
post.Add("msgtype", "text");
Dictionary<string, string> text = new Dictionary<string, string>();
text.Add("content", msg);
post.Add("text", text);
string postData = JsonConvert.SerializeObject(post);
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
byte[] data = Encoding.UTF8.GetBytes(postData);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//获取响应内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
}
修改2.1.2 中 的定时执行事件
bool Mark; //添加标记,用来防止重复提醒
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Wednesday)
{
if (!(DateTime.Now.Hour == 17 && DateTime.Now.Minute == 30))
{
Mark = false;
return;
}
}
else
{
if (!(DateTime.Now.Hour == 18 && DateTime.Now.Minute == 30))
{
Mark = false;
return;
}
}
if (Mark)
{
return;
}
Mark = true;
SendMessage("到点下班了");
}
重新生成工程,并重启服务
效果:
2.2.1 添加发送图片功能
回到Service1 的代码编写窗口
添加如下代码
string url = "企业微信机器人给你的webhook地址";
private void SendPng(string filePath)
{
Dictionary<string, object> post = new Dictionary<string, object>();
post.Add("msgtype", "image");
string imgdata = GetFileBase64(filePath);
string md5 = GetMD5(filePath);
Dictionary<string, string> text = new Dictionary<string, string>();
text.Add("base64", imgdata);
text.Add("md5", md5);
post.Add("image", text);
string postData = JsonConvert.SerializeObject(post);
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
byte[] data = Encoding.UTF8.GetBytes(postData);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//获取响应内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
}
/// <summary>
/// 将文件转换为base64String
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns></returns>
public string GetFileBase64(string filePath)
{
filePath = filePath ?? throw new ArgumentException("文件路径错误");
try
{
using (FileStream fs = File.OpenRead(filePath))
{
return GetFileBase64(fs);
}
}
catch (Exception ex)
{
throw;
}
}
/// <summary>
/// 将文件转换为base64String
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public string GetFileBase64(Stream stream)
{
stream = stream ?? throw new ArgumentException("参数不能为空");
try
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
return Convert.ToBase64String(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
throw;
}
}
public string GetMD5(string filePath)
{
filePath = filePath ?? throw new ArgumentException("文件路径错误");
try
{
using (FileStream fs = File.OpenRead(filePath))
{
return GetFileMd5(fs);
}
}
catch (Exception ex)
{
throw;
}
}
/// <summary>
/// 计算文件的MD5值
/// 用做于缓存Key
/// </summary>
/// <param name="arg">类型只能为string or stream,否则将会抛出错误</param>
/// <returns>文件的MD5值</returns>
public string GetFileMd5(object arg)
{
MD5 md5Hash = MD5.Create();
byte[] data = null;
switch (arg)
{
case string str:
data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(str));
break;
case Stream stream:
data = md5Hash.ComputeHash(stream);
break;
case null:
throw new ArgumentException("参数不能为空");
default:
throw new ArgumentException("参数类型错误");
}
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
md5Hash.Dispose();
return sBuilder.ToString();
}
修改2.1.2 中 的定时执行事件
bool Mark; //添加标记,用来防止重复提醒
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Wednesday)
{
if (!(DateTime.Now.Hour == 17 && DateTime.Now.Minute == 30))
{
Mark = false;
return;
}
}
else
{
if (!(DateTime.Now.Hour == 18 && DateTime.Now.Minute == 30))
{
Mark = false;
return;
}
}
if (Mark)
{
return;
}
Mark = true;
SendPng("图片路径");
}
重新生成工程,并重启服务
效果:
参考文章:c# base64及MD5工具类