背景
最近项目上要实现连接企业微信的接口,然后发送消息,并且是定时发送消息,所以针对这块做了研究并且实现了方案
What is windows服务
最常见的大家应该都是dos窗口或者是form窗口,而windows服务就是实现当你的服务开启,则他就开启,当你把他的服务关闭则他也就是关闭,通常只要我们开启之后,电脑不关机,那么他就一直运行着,它是可以长时间运行的可执行应用程序,他不需要界面,非常适合与在服务器上运行,
如何创建windows服务
安装服务服务
- 必须以管理员的身份运行
- 打开vs的dos界面
- 输入自己vs中Framwork的版本号,例如
- d:\Windows\Microsoft.NET\Framework\v4.0.30319 回车
- 找到自己的应该程序(在我们的项目中bin下的begun下有一个exe应用程序)
在dos中输入:
E:\TestApp\Winform\WinServiceTest\WinServiceTest\bin\Debug\XX.exe表示项目生成的exe文件位置这个时候打开服务你就会看见自己的服务了
代码编写
获取accesstoken
public static string getAccessToken()
{
//企业的唯一id
string appid = "不可以泄密哦";
//密包 ,。
string appsecret = "不可以泄密哦";
//实例化一个access_token
string access_token = null;
//传送的地址和id,还是密保
string url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + appid + "&corpsecret=" + appsecret;
string jsonReturn = "";
//用于发送和接受Http数据
//使用system.net命名空间
//他有一点跟我们普通的对象不一样,就是他不是用new不出来的对象,使用.Cretate()方法创建
HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(url);
//请求的方式为get类型
httprequest.Method = "GET";
//读取服务器返回的信息
HttpWebResponse response = (HttpWebResponse)httprequest.GetResponse();
using (Stream steam = response.GetResponseStream())
{
//我们使用stock表示把一个文本发送到机器中,而使用Encode发送给我们可以识别的数字
StreamReader reader = new StreamReader(steam, Encoding.GetEncoding("gb2312"));
//表示一次性的返回整个信息
jsonReturn = reader.ReadToEnd();
//关闭数据流
steam.Close();
}
JObject jo = JObject.Parse(jsonReturn);
access_token = jo["access_token"].ToString();
return access_token;
}
}
编写接口发
string AgentId = "1000003";
string postText = "{\"touser\" :\"@all\",\"toparty\" : \"@all\",\"totag\" : \"@all\",\"msgtype\" : \"text\",\"agentid\" : " + AgentId + ",\"text\" : {\"content\" : \"我是王大美人\n加油。\"},\"safe\":0}";
//转化为字节流的形式byte[],处了有utf-8的形式还有GB2312的形式,还有default形式,但是utf-8解决乱码问题
//达到95%,而default达到90%
Encoding encoding = Encoding.GetEncoding("utf-8");
//调用方法把字符串中的所有字符编码为一个字节序列
byte[] bytesToPost = encoding.GetBytes(postText);
//执行post提交方法,把地址和内容传输过去
string res = Post(url, bytesToPost);
//输出字符串,展现
Console.WriteLine(res);
}
post方式提交
private static string Post(string url, byte[] bytesToPost)
{
//判断我的链接地址字符串是否为空,他的空表示的是“ ”
//用这种方式写的好处是方便阅读,而且快上百万毫秒以上
if (String.IsNullOrEmpty(url))
return "url参数为空值";
//判断内容是否为空
if (bytesToPost == null)
return "post数据为空值";
string ResponseString = "";
//创建一个请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//如果存在太多数目的alive的http请求,大于你设置的,那么当你再次提交同样的http的request,调用GetResponse就会发生超时,所以我们设置为50
System.Net.ServicePointManager.DefaultConnectionLimit = 50;
//TCP中一个可以检测死链接的机制,可以不用false
request.KeepAlive = false;
//提交方式为post提交
request.Method = "POST";
//内容的类型
request.ContentType = "text/xml";//提交xml
//内容的长度,表示http的头
request.ContentLength = bytesToPost.Length;
//写入到internet中的Stream,用户传输
Stream writer = request.GetRequestStream();
//把当前的流写入字符序列,第一代表字节,第二是从0的位置开始,第三个是长度
writer.Write(bytesToPost, 0, bytesToPost.Length);
//来自internet的资源相应
HttpWebResponse HttpWebRespon = (HttpWebResponse)request.GetResponse();
//1要读取的流,2要转换为的字节编码,把指点的字节编码转换为制定的流
StreamReader myStreamReader = new StreamReader(HttpWebRespon.GetResponseStream(), Encoding.UTF8);
//从流的当前为值到流的最后字节的位置
ResponseString = myStreamReader.ReadToEnd();
myStreamReader.Close();
//清除流中所有的缓冲区
writer.Flush();
if (writer != null)
{
writer.Close();
}
if (request != null)
{
//取消对资源的相应
request.Abort();
}
return ResponseString;
}
windows服务代码
public partial class Service1 : ServiceBase
{
//定时器
System.Timers.Timer t = null;
public Service1()
{
InitializeComponent();
//启用暂停恢复
base.CanPauseAndContinue = true;
//每5秒执行一次
t = new System.Timers.Timer(5000);
//设置是执行一次(false)还是一直执行(true); 3600000
t.AutoReset = true;
//是否执行System.Timers.Timer.Elapsed事件;
t.Enabled = true;
//到达时间的时候执行事件(theout方法);
t.Elapsed += new System.Timers.ElapsedEventHandler(theout);
}
protected override void OnStart(string[] args)
{
string state = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "启动";
}
protected override void OnStop()
{
string state = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "停止";
}
public void theout(object source, System.Timers.ElapsedEventArgs e)
{
send.SendWechat();
}
展现成功
总结
这一次算是自己对自己的一个突破把!很开心实现这个功能!