2024年1月21日发(作者:)

如何用c# 开发系统服务

最近用.net开发了个隔时执行的小应用程序,登录MSDTC,放到服务器,运转良好,退出远程桌面,事情出来了,那个可爱的程序不运作了,然后我就搞了个任务计划,做了下,以为完事了,过了一些时间,发现不对劲,还是停止执行程序了,上去一看,又停止了,这时候我不得不重新考虑设置,还是写个系统服务就去吧,写上一段代码先写个服务再说。

using System;

using tions;

using entModel;

using stics;

using eProcess;

using l;

namespace eDST

{

// 应用程序

public class MyFirstService : eBase

{

public MyFirstService()

{

seAndContinue = true;

tdown = true;

dleSessionChangeEvent = false;

eName = "MyFirstService";

}

protected override void OnStart(string[] args){

}

protected override void OnStop(){

}

protected override void OnContinue(){

}

//启动

public static void Main()

{

ServiceBase[] servicesToRun = new ServiceBase[] {new MyFirstService()};

(servicesToRun);

}

}

//安装

[RunInstaller(true)]

public class ProjectInstaller : ler

{

private ServiceProcessInstaller myServiceProcessInstaller;

private ServiceInstaller myServiceInstaller;

public ProjectInstaller()

{

iceProcessInstaller = new ServiceProcessInstaller();

iceInstaller = new ServiceInstaller();

// 安装

// 用户名 和 密码

t = ystem;

me = null;

rd = null;

// 服务名称,这样可以在net stop XX 里面使用了

// 启动类型

eName = "MyFirstService";

ype = tic;

// 加入

ge(new Installer[] {iceProcessInstaller,

iceInstaller});

}

}

}

其中在启动的代码中我们可以执行:

protected override void OnStart(string[] args){

StreamWriter sw=new StreamWriter(@"E:",true);

("rn另一条数据");

();

t( args );

}

或者创建另一条线程执行其他程序。

1、编译

csc

2、安装

installutil

3、启动服务

net start MyFirstService

4、停止服务

net stop MyFirstService

5、卸载

installutil /u

上次我专门说明了如何用c# 开发系统服务,由于很多时候这个工具用起来还是有点繁琐,一直想着用c#代码自己完成启动服务,删除服务的操作。这就需要调用.NET的DllImport,主要是调用这个dll来实现。

关于的接口,有兴趣的可以查。我这里就写出实现的C#代码。

using System;

using pServices;

namespace MyServiceInstaller

{

class ServiceInstaller

{

public static string AppPath{get{return tDirectory;}}

#region Private Variables

//private string _servicePath;

//private string _serviceName;

//private string _serviceDisplayName;

#endregion Private Variables

#region DLLImport

[DllImport("")]

public static extern IntPtr OpenSCManager(string lpMachineName,string lpSCDB, int

scParameter);

[DllImport("")]

public static extern IntPtr CreateService(IntPtr SC_HANDLE,string lpSvcName,string

lpDisplayName,

int dwDesiredAccess,int dwServiceType,int dwStartType,int dwErrorControl,string lpPathName,

string lpLoadOrderGroup,int lpdwTagId,string lpDependencies,string lpServiceStartName,string

lpPassword);

[DllImport("")]

public static extern void CloseServiceHandle(IntPtr SCHANDLE);

[DllImport("")]

public static extern int StartService(IntPtr SVHANDLE,int dwNumServiceArgs,string

lpServiceArgVectors);

[DllImport("",SetLastError=true)]

public static extern IntPtr OpenService(IntPtr SCHANDLE,string lpSvcName,int

dwNumServiceArgs);

[DllImport("")]

public static extern int DeleteService(IntPtr SVHANDLE);

[DllImport("")]

public static extern int GetLastError();

#endregion DLLImport

///

/// 应用程序入口.

///

[STAThread]

static void Main(string[] args)

{

int ExeId = (args==null)?0:0;

if(args!=null && >0){

if(se(args[0],out ExeId)){

;

}

}

string svcName= "DSIService";

ServiceInstaller c = new ServiceInstaller();

if(ExeId==1){

string svcPath;

string svcDispName;

//服务程序的路径

svcPath = e(AppPath,"");

svcDispName="DSIService";

ine("执行的路径是{0}",svcPath);

ine("创建的结果是{0}",lService(svcPath, svcName,

svcDispName));

}else if(ExeId==2){

ine("卸载的结果是{0}",allService(svcName));

}else{

ine("你要干什么?{0}","installutil /u ");

}

}

///

/// 安装和运行

///

/// 程序路径.

/// 服务名

/// 服务显示名称.

/// 服务安装是否成功.

public bool InstallService(string svcPath, string svcName, string svcDispName)

{

#region Constants declaration.

int SC_MANAGER_CREATE_SERVICE = 0x0002;

int SERVICE_WIN32_OWN_PROCESS = 0x00000010;

//int SERVICE_DEMAND_START = 0x00000003;

int SERVICE_ERROR_NORMAL = 0x00000001;

int STANDARD_RIGHTS_REQUIRED = 0xF0000;

int SERVICE_QUERY_CONFIG = 0x0001;

int SERVICE_CHANGE_CONFIG = 0x0002;

int SERVICE_QUERY_STATUS = 0x0004;

int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;

int SERVICE_START =0x0010;

int SERVICE_STOP =0x0020;

int SERVICE_PAUSE_CONTINUE =0x0040;

int SERVICE_INTERROGATE =0x0080;

int SERVICE_USER_DEFINED_CONTROL =0x0100;

int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |

SERVICE_QUERY_CONFIG |

SERVICE_CHANGE_CONFIG |

SERVICE_QUERY_STATUS |

SERVICE_ENUMERATE_DEPENDENTS |

SERVICE_START |

SERVICE_STOP |

SERVICE_PAUSE_CONTINUE |

SERVICE_INTERROGATE |

SERVICE_USER_DEFINED_CONTROL);

int SERVICE_AUTO_START = 0x00000002;

#endregion Constants declaration.

try

{

IntPtr sc_handle = OpenSCManager(null,null,SC_MANAGER_CREATE_SERVICE);

if (sc_32() != 0)

{

IntPtr sv_handle =

CreateService(sc_handle,svcName,svcDispName,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,

SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,svcPath,null,0,null,null,null);

if(sv_32() ==0)

{

CloseServiceHandle(sc_handle);

return false;

}

else

{

//试尝启动服务

int i = StartService(sv_handle,0,null);

if(i==0)

{

return false;

}

CloseServiceHandle(sc_handle);

return true;

}

}

else

return false;

}

catch(Exception e)

{

throw e;

}

}

///

/// 反安装服务.

///

/// 服务名.

public bool UnInstallService(string svcName){

int GENERIC_WRITE = 0x40000000;

IntPtr sc_hndl = OpenSCManager(null,null,GENERIC_WRITE);

if(sc_32() !=0){

int DELETE = 0x10000;

IntPtr svc_hndl = OpenService(sc_hndl,svcName,DELETE);

if(svc_32() !=0){

int i = DeleteService(svc_hndl);

if (i != 0){

CloseServiceHandle(sc_hndl);

return true;

}else{

CloseServiceHandle(sc_hndl);

return false;

}

}else

return false;

}

else

return false;

}

};

}

其中启动服务的是InstallService,删除服务的是UnInstallService,这里面有几个事情要说明。

第一:在真正执行的代码中

public static string AppPath{get{return tDirectory;}}

这段是执行的目录,当服务开始执行的时候,都是在系统目录。

第二:删除服务的UnInstallService这是个消极删除,如果执行过后,刷新,服务还在列表中,但是状态会被标记为禁用,其实已经被删除。

其他没什么好说的,如果需要用户名和密码登录,就在CreateService的最后两个参数去修改。