最近项目需要,需要定时获取天气资料往数据数库内写入数据,所以就考虑到了.net内的window服务。以前没有这方面的需求,所以基本没怎么接触过。所以也借这次机会好好补充下这方面的知识,以备以后工作之需。
关于winds服务的介绍,这里有一篇文章介绍得很清楚:http://blog.csdn.net/yysyangyangyangshan/article/details/7295739,但这里的具体步骤讲述不是很清楚,所以现用具体的方式再讲述下windows服务的开发与安装事项。
开发环境:Win7 32位;工具:visualstudio2010。 因为win7自带的就有.net环境,算是偷一下懒吧。因为无论是手动安装或程序安装都要用到。一个目录(默认C盘为操作系统的情况):C:\Windows\Microsoft.NET\Framework,如果你的代码是.net2.0:C:\Windows\Microsoft.NET\Framework\v2.0.50727;4.0:C:\Windows\Microsoft.NET\Framework\v4.0.30319。 下面看一下代码: 一、创建windows服务 如图新建一个Windows服务 进入程序如图 空白服务如下
- public partial class Service1 : ServiceBase
- {
- System.Threading.Timer recordTimer;
-
-
- public Service1()
- {
- InitializeComponent();
- }
-
-
- protected override void OnStart(string[] args)
- {
- }
-
-
- protected override void OnStop()
- {
- }
- }
public partial class Service1 : ServiceBase
{
System.Threading.Timer recordTimer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
只要在OnStart里完成你的功能代码即可。本例中我们做一个定时向本地文件写记录的功能。 如图 创建一个类,用户写文件,
- public class FileOpetation
- {
-
-
-
-
-
- public static void SaveRecord(string content)
- {
- if (string.IsNullOrEmpty(content))
- {
- return;
- }
-
-
- FileStream fileStream = null;
-
-
- StreamWriter streamWriter = null;
-
-
- try
- {
- string path = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, string.Format("{0:yyyyMMdd}", DateTime.Now));
-
-
- using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
- {
- using (streamWriter = new StreamWriter(fileStream))
- {
- streamWriter.Write(content);
-
-
- if (streamWriter != null)
- {
- streamWriter.Close();
- }
- }
-
-
- if (fileStream != null)
- {
- fileStream.Close();
- }
- }
- }
- catch { }
- }
- }
public class FileOpetation
{
/// <summary>
/// 保存至本地文件
/// </summary>
/// <param name="ETMID"></param>
/// <param name="content"></param>
public static void SaveRecord(string content)
{
if (string.IsNullOrEmpty(content))
{
return;
}
FileStream fileStream = null;
StreamWriter streamWriter = null;
try
{
string path = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, string.Format("{0:yyyyMMdd}", DateTime.Now));
using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
{
using (streamWriter = new StreamWriter(fileStream))
{
streamWriter.Write(content);
if (streamWriter != null)
{
streamWriter.Close();
}
}
if (fileStream != null)
{
fileStream.Close();
}
}
}
catch { }
}
}
那么在Service1中调用,
- public partial class Service1 : ServiceBase
- {
- System.Threading.Timer recordTimer;
-
-
- public Service1()
- {
- InitializeComponent();
- }
-
-
- protected override void OnStart(string[] args)
- {
- IntialSaveRecord();
- }
-
-
- protected override void OnStop()
- {
- if (recordTimer != null)
- {
- recordTimer.Dispose();
- }
- }
-
-
- private void IntialSaveRecord()
- {
- TimerCallback timerCallback = new TimerCallback(CallbackTask);
-
-
- AutoResetEvent autoEvent = new AutoResetEvent(false);
-
-
- recordTimer = new System.Threading.Timer(timerCallback, autoEvent, 10000, 60000 * 10);
- }
-
-
- private void CallbackTask(Object stateInfo)
- {
- FileOpetation.SaveRecord(string.Format(@"当前记录时间:{0},状况:程序运行正常!", DateTime.Now));
- }
- }
public partial class Service1 : ServiceBase
{
System.Threading.Timer recordTimer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
IntialSaveRecord();
}
protected override void OnStop()
{
if (recordTimer != null)
{
recordTimer.Dispose();
}
}
private void IntialSaveRecord()
{
TimerCallback timerCallback = new TimerCallback(CallbackTask);
AutoResetEvent autoEvent = new AutoResetEvent(false);
recordTimer = new System.Threading.Timer(timerCallback, autoEvent, 10000, 60000 * 10);
}
private void CallbackTask(Object stateInfo)
{
FileOpetation.SaveRecord(string.Format(@"当前记录时间:{0},状况:程序运行正常!", DateTime.Now));
}
}
这样服务算是写的差不多了,下面添加一个安装类,用于安装。 如图,在service1上右键-添加安装程序, 如图,添加一个安装程序, 如图,添加完成后, 设置相应的属性,给serviceInstaller1设置属性,主要是描述信息。如图, 给serviceProcessInstaller1设置,主要是account。一般选localsystem,如图, 这样服务已经写好了。那么如何添加到windows服务里面去呢。除了之前说过的用CMD,InstallUtil.exe和服务的exe文件进行手动添加。这些可以用代码来实现的。当然主要过程都是一样的。代码实现也是使用dos命令来完成的。 二、代码安装Windows服务 上面写好的服务,最终生成的是一个exe文件。如图, 安装程序安装时需要用到这个exe的路径,所以方便起见,将这个生成的exe文件拷贝至安装程序的运行目录下。
安装代码,
class Program
{
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string sysDisk = System.Environment.SystemDirectory.Substring(0,3);
string dotNetPath = sysDisk + @"WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe";//因为当前用的是4.0的环境
string serviceEXEPath = Application.StartupPath+@"\MyFirstWindowsService.exe";//把服务的exe程序拷贝到了当前运行目录下,所以用此路径
string serviceInstallCommand = string.Format(@"{0} {1}", dotNetPath, serviceEXEPath);//安装服务时使用的dos命令
string serviceUninstallCommand = string.Format(@"{0} -U {1}", dotNetPath, serviceEXEPath);//卸载服务时使用的dos命令
try
{
if (File.Exists(dotNetPath))
{
string[] cmd = new string[] { serviceUninstallCommand };
string ss = Cmd(cmd);
CloseProcess("cmd.exe");
}
}
catch
{
}
Thread.Sleep(1000);
try
{
if (File.Exists(dotNetPath))
{
string[] cmd = new string[] { serviceInstallCommand };
string ss = Cmd(cmd);
CloseProcess("cmd.exe");
}
}
catch
{
}
try
{
Thread.Sleep(3000);
ServiceController sc = new ServiceController("MyFirstWindowsService");
if (sc != null && (sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
(sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
sc.Start();
}
sc.Refresh();
}
catch
{
}
}
/// <summary>
/// 运行CMD命令
/// </summary>
/// <param name="cmd">命令</param>
/// <returns></returns>
public static string Cmd(string[] cmd)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.AutoFlush = true;
for (int i = 0; i < cmd.Length; i++)
{
p.StandardInput.WriteLine(cmd[i].ToString());
}
p.StandardInput.WriteLine("exit");
string strRst = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
return strRst;
}
/// <summary>
/// 关闭进程
/// </summary>
/// <param name="ProcName">进程名称</param>
/// <returns></returns>
public static bool CloseProcess(string ProcName)
{
bool result = false;
System.Collections.ArrayList procList = new System.Collections.ArrayList();
string tempName = "";
int begpos;
int endpos;
foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
{
tempName = thisProc.ToString();
begpos = tempName.IndexOf("(") + 1;
endpos = tempName.IndexOf(")");
tempName = tempName.Substring(begpos, endpos - begpos);
procList.Add(tempName);
if (tempName == ProcName)
{
if (!thisProc.CloseMainWindow())
thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程
result = true;
}
}
return result;
}
}
这段代码其实可以放在项目中的某个地方,或单独执行程序中,只好设置好dotNetPath和serviceEXEPath路径就可以了。
运行完后,如图, 再在安装目录下看记录的文件,
这样,一个windows服务安装成功了。
代码下载:http://download.csdn.net/detail/yysyangyangyangshan/6032671
原文地址:http://blog.csdn.net/yysyangyangyangshan/article/details/10515035
再另加windows服务的具体安装步骤:
安装服务
点击 开始,运行中输入cmd,获取命令提示符
win7需要已管理员的身份启动,否则无法安装
-
2
输入 cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 回车
切换当前目录,此处需要注意的是,在C:\Windows\Microsoft.NET\Framework目录下有很多类似版本,具体去哪个目录要看项目的运行环境,例 如果是.net framework2.0则需要输入 cd C:\Windows\Microsoft.NET\Framework\v2.0.50727
-
3
输入 InstallUtil.exe E:\TestApp\Winform\WinServiceTest\WinServiceTest\bin\Debug\WinServiceTest.exe 回车
说明:E:\TestApp\Winform\WinServiceTest\WinServiceTest\bin\Debug\WinServiceTest.exe表示项目生成的exe文件位置
-
4
END
百度经验:jingyan.baidu.com
卸载服务
-
1
卸载很简单,打开cmd, 直接输入 sc delete WinServiceTest便可
其他安装方式:
装Winfows服务首先要添加安装程序,添加安装程序步骤如下:
1、将Windows服务程序切换到设计视图, 右击设计视图选择“添加安装程序”
2、切换到刚被添加的ProjectInstaller的设计视图
一般设置如下:
设置serviceInstaller1组件的属性: 1) ServiceName = 服务名称 2) StartType = Automatic ,即自动 设置serviceProcessInstaller1组件的属性 1) Account = LocalSystem,账户一般设置为本地系统
3、生成解决方案
安装服务:
方法一、使用DOS命令安装window服务
1、在服务所在的文件夹下的bin\debug文件夹下找到.exe文件(例如WindowsService1.exe)
将此文件拷贝到你想安装的文件夹中。
2、进入DOS界面
(VS2008-->Visual Studio Tools-->Visual Studio 2008 命令提示)来进入DOS,直接用cmd可能有些命令找不到;
3、输入
方法二、使用安装项目安装windows服务
个人比较推荐这个方法,选择目录安装更灵活,而且不用在DOS环境下运行。
因为本人比较懒,直接给出别人总结的地址
http://blog.csdn.net/dyzcode/article/details/6981547
注意,以后每次服务项目有更改的时候,需要编译服务后,在安装项目中刷新依赖项!!!
方法三、
在ProjectInstaller.cs的后台代码中添加安装服务和卸载服务的代码
- public override void Install(System.Collections.IDictionary stateSaver)
- {
- Microsoft.Win32.RegistryKey system,
-
- currentControlSet,
-
- services,
-
- service,
-
- config;
-
- try
- {
-
- base.Install(stateSaver);
-
-
- system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
-
- currentControlSet = system.OpenSubKey("CurrentControlSet");
-
- services = currentControlSet.OpenSubKey("Services");
-
- service = services.OpenSubKey(conServiceName, true);
-
- service.SetValue("Description", "<span style="font-family: KaiTi_GB2312;">描述语言</span>");
-
- config = service.CreateSubKey("Parameters");
- }
- catch (Exception e)
- {
- Console.WriteLine("An exception was thrown during service installation:\n" + e.ToString());
- }
- }
-
- public override void Uninstall(System.Collections.IDictionary savedState)
- {
- Microsoft.Win32.RegistryKey system,
- currentControlSet,
- services,
- service;
-
- try
- {
-
- system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
- currentControlSet = system.OpenSubKey("CurrentControlSet");
- services = currentControlSet.OpenSubKey("Services");
- service = services.OpenSubKey(conServiceName, true);
-
- service.DeleteSubKeyTree("Parameters");
-
- }
- catch (Exception e)
- {
- Console.WriteLine("Exception encountered while uninstalling service:\n" + e.ToString());
- }
- finally
- {
-
- base.Uninstall(savedState);
- }
- }
/// <summary>
/// 安装服务
/// </summary>
/// <param name="stateSaver"></param>
public override void Install(System.Collections.IDictionary stateSaver)
{
Microsoft.Win32.RegistryKey system,
//HKEY_LOCAL_MACHINE\Services\CurrentControlSet
currentControlSet,
//...\Services
services,
//...\<Service Name>
service,
//...\Parameters - this is where you can put service-specific configuration
config;
try
{
//Let the project installer do its job
base.Install(stateSaver);
//Open the HKEY_LOCAL_MACHINE\SYSTEM key
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
//Open CurrentControlSet
currentControlSet = system.OpenSubKey("CurrentControlSet");
//Go to the services key
services = currentControlSet.OpenSubKey("Services");
//Open the key for your service, and allow writing
service = services.OpenSubKey(conServiceName, true);
//Add your service's description as a REG_SZ value named "Description"
service.SetValue("Description", "描述语言");
//(Optional) Add some custom information your service will use...
config = service.CreateSubKey("Parameters");
}
catch (Exception e)
{
Console.WriteLine("An exception was thrown during service installation:\n" + e.ToString());
}
}
/// <summary>
/// 卸载服务
/// </summary>
/// <param name="savedState"></param>
public override void Uninstall(System.Collections.IDictionary savedState)
{
Microsoft.Win32.RegistryKey system,
currentControlSet,
services,
service;
try
{
//Drill down to the service key and open it with write permission
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
currentControlSet = system.OpenSubKey("CurrentControlSet");
services = currentControlSet.OpenSubKey("Services");
service = services.OpenSubKey(conServiceName, true);
//Delete any keys you created during installation (or that your service created)
service.DeleteSubKeyTree("Parameters");
//...
}
catch (Exception e)
{
Console.WriteLine("Exception encountered while uninstalling service:\n" + e.ToString());
}
finally
{
//Let the project installer do its job
base.Uninstall(savedState);
}
}
代码添加完成后
添加window service安装的批处理命令
1)在项目添加一个文本文件,更名为install.bat,编辑文件的内容如下:
@echo off C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe -i "WindowsService1.exe" @pause
2)在项目添加一个文本文件,更名为uninstall.bat,编辑文件的内容如下
@echo off C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe -u "WindowsService1.exe" @pause
说明:上面绿色字体为服务名称
编译完成后将debug的文件拷贝到想安装的目录下,点击install.bat即完成安装。
|
请发表评论