关于C#创建windows服务的测试与总结

 关于C#创建windows服务的测试与总结。.NET中安装服务很麻烦,即要创建Service,又要创建ServiceInstall,最后还要弄一堆命令来安装和卸载。

今天给大家提供一种方式(经过测试),直接使用这样的程序来安装/卸载服务,并且可以让一个exe即能直接运行也可以安装为windows服务(运行exe文件时需要以管理员身份运行,卸载服务也需要管理员身份,否则可能会报错,并且在程序中直接运行服务时可能会报错,建议运行exe文件)。

修改管理员身份:

用SC命令 添加或删除windows服务提示OpenSCManager 失败5 拒绝访问;在安装命令行中安装 windowsOpenSCManager 失败5 的错误,原因是当前用户的权限不足,需要做的是在注册表:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA 的值改为0把这个值改成0,这样在自己的电脑上操作才是真正的administration,然后重启。

创建C#服务的普通方法: https://blog.sina.com.cn/s/blog_6d5459990102uymo.html ,下面是改进过程。

首先我们创建一个Windows应用程序,(我创建的是控制台程序,WinForm也一样)

\

接下来在项目中添加一个Windows服务类

\

\

然后双击“MainService.cs”,在上面点右键“打开代码”

\

这里面写服务的具体实现,以下是我写的示例代码

partial class MainService : ServiceBase

{

public MainService()

{

InitializeComponent();

}

protected override void OnStart(string[] args)

{

// TODO: 在此处添加代码以启动服务。

System.IO.File.AppendAllText("D:\\log.txt", "服务已启动……" + DateTime.Now.ToString());

}

protected override void OnStop()

{

// TODO: 在此处添加代码以执行停止服务所需的关闭操作。

System.IO.File.AppendAllText("D:\\log.txt", "服务已停止……" + DateTime.Now.ToString());

}

}

然后我们改程序入口Main方法,让其在启动时识别是Windows应用程序还是Windows服务,如果是应用程序就执行应用程序的代码,如果是服务就执行MainService的代码

如果是服务,我给了一个"s"参数,如果有这个参数就证明是Windows服务,然后启动MainService

static void Main(string[] args)

{

//如果传递了"s"参数就启动服务

if (args.Length > 0 && args[0] == "s")

{

//启动服务的代码,可以从其它地方拷贝

ServiceBase[] ServicesToRun;

ServicesToRun = new ServiceBase[]

{

new MainService(),

};

ServiceBase.Run(ServicesToRun);

}

else

{}

然后,我们再实现应用程序的功能,就是上面的else语句块,应用程序的功能就是安装/卸载服务,可以用windows自带的sc命令来进行安装和卸载,具体代码如下:

Console.WriteLine("这是Windows应用程序");

Console.WriteLine("请选择,[1]安装服务 [2]卸载服务 [3]退出");

var rs = int.Parse(Console.ReadLine());

switch (rs)

{

case 1:

//取当前可执行文件路径,加上"s"参数,证明是从windows服务启动该程序

var path = Process.GetCurrentProcess().MainModule.FileName + " s";

Process.Start("sc", "create myserver binpath= \"" + path + "\" displayName= 我的服务 start= auto");

Console.WriteLine("安装成功");

Console.Read();

break;

case 2:

Process.Start("sc", "delete myserver");

Console.WriteLine("卸载成功");

Console.Read();

break;

case 3: break;

}

这样我们就实现了一个即是可执行程序又是Windows服务的应用程序

Main方法完整代码如下

static void Main(string[] args)

{

if (args.Length > 0 && args[0] == "s")

{

ServiceBase[] ServicesToRun;

ServicesToRun = new ServiceBase[]

{

new MainService(),

};

ServiceBase.Run(ServicesToRun);

}

else

{

Console.WriteLine("这是Windows应用程序");

Console.WriteLine("请选择,[1]安装服务 [2]卸载服务 [3]退出");

var rs = int.Parse(Console.ReadLine());

switch (rs)

{

case 1:

//取当前可执行文件路径,加上"s"参数,证明是从windows服务启动该程序

var path = Process.GetCurrentProcess().MainModule.FileName + " s";

Process.Start("sc", "create myserver binpath= \"" + path + "\" displayName= 我的服务 start= auto");

Console.WriteLine("安装成功");

Console.Read();

break;

case 2:

Process.Start("sc", "delete myserver");

Console.WriteLine("卸载成功");

Console.Read();

break;

case 3: break;

}

}

}

至此,程序已基本写完,接下来我们测试一下

直接双击ServiceOrApp.exe

\

输入 1

\

提示安装成功,然后运行“services.msc"打开服务管理器

\

可以发现我们的服务已安装成功,然后右键启动服务

\

成功启动

\

然后去D盘看看log.txt

\

说明服务执行正常

我们再停止服务

\

成功停止后再看看D盘的log.txt文件

看到以上内容,说明服务启动和停止都没问题(C#回车换行使用“\r\n”)

然后我们再试一下卸载服务(需要停止服务运行),还是双击ServiceOrApp.exe,选择2

\

提示卸载成功,然后再运行“services.msc"打开服务管理器

\

刷新后可以看到已经没有”我的服务“了,已成功卸载

这里安装和卸载主要运用了windows的sc命令,然后使用启动参数来判断是服务还是程序以执行不同的代码

C#windows service服务安装、注册、判断服务是否存在、是否启动

#region 安装服务

private void InstallService(IDictionary stateSaver, string filepath)

{

try

{

ServiceController service = new ServiceController("ServiceName");

if (!ServiceIsExisted("ServiceName"))

{

//Install Service

AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();

myAssemblyInstaller.UseNewContext = true;

myAssemblyInstaller.Path = filepath;

myAssemblyInstaller.Install(stateSaver);

myAssemblyInstaller.Commit(stateSaver);

myAssemblyInstaller.Dispose();

//--Start Service

service.Start();

}

else

{

if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)

{

service.Start();

}

}

}

catch (Exception ex)

{

MessageBox.Show("安装服务失败!");

}

}

#endregion

#region 卸载windows服务

private void UnInstallService(string filepath)

{

try

{ if (ServiceIsExisted("ServiceName"))

{

//UnInstall Service

AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();

myAssemblyInstaller.UseNewContext = true;

myAssemblyInstaller.Path = filepath;

myAssemblyInstaller.Uninstall(null);

myAssemblyInstaller.Dispose();

}

}

catch (Exception ex)

{

MessageBox.Show("卸载服务失败!");

}

}

#endregion

#region 判断window服务是否存在

private boolServiceIsExisted(string serviceName)

{

ServiceController[] services = ServiceController.GetServices();

foreach (ServiceController s in services)

{

if (s.ServiceName == serviceName)

{

return true;

}

}

return false;

}

#endregion

#region 判断window服务是否启动

public static bool IsServiceStart(string serviceName)

{

ServiceController psc = new ServiceController(serviceName);

bool bStartStatus = false;

try

{

if (!psc.Status.Equals(ServiceControllerStatus.Stopped))

{

bStartStatus = true;

}

return bStartStatus;

}

catch (Exception ex)

{

throw new Exception(ex.Message);

}

}

#endregion

#region 启动服务

private bool StartService(string serviceName)

{

bool flag = true;

if (ServiceIsExisted(serviceName))

{

System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);

if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)

{

service.Start();

for (int i = 0; i < 60; i++)

{

service.Refresh();

System.Threading.Thread.Sleep(1000);

if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)

{

break;

}

if (i == 59)

{

flag = false;

}

}

}

}

return flag;

}

#endregion

#region 停止服务

private bool StopService(string serviceName)

{

bool flag = true;

if (ServiceIsExisted(serviceName))

{

System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);

if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)

{

service.Stop();

for (int i = 0; i < 60; i++)

{ www.2cto.com

service.Refresh();

System.Threading.Thread.Sleep(1000);

if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)

{

break;

}

if (i == 59)

{

flag = false;

}

}

}

}

return flag;

}

#endregion

#endregion

猜你喜欢

转载自blog.csdn.net/lxrj2008/article/details/81316469