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的最后两个参数去修改。


发布评论