1. Description 用于该服务的简短描述。 2. DisplayName 显示在服务列表中的显示名称。
3. ServiceName 服务的名称,系统使用该名称唯一标识该服务,不能和已有的服务冲突。 4. StartType 表示服务的启动方式,可以是自动、手动、禁用。
Description DisplayName ServiceName 服务冲突。 StartType
用于该服务的简短描述。 显示在服务列表中的显示名称。
服务的名称,系统使用该名称唯一标识该服务,不能和已有的表示服务的启动方式,可以是自动、手动、禁用。
设置完毕后,生成 USBCleaner,得到一个 EXE 文件:
接下来就是在项目 USBViewer 中对 USBCleaner.exe 进行安装调用了。
如果是手动进行安装,可以使用 .Net 框架提供的工具:InstallUtil.exe 程序,对于 .Net Framework 4.0 来说,它一般位于:
[csharp] view plain copy print?
1. SystemRoot%\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe
SystemRoot%\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe
使用 /u 或 /uninstall 来卸载服务,不加参数则是安装服务。但是要在程序中自动执行安装和卸载服务,就需要使用 .Net 框架提供的 TransactedInstaller 类,它提供了的作用就是InstallUtil.exe 服务安装工具所提供的功能。
为了代码更好的组织,我将检测服务运行和安装的代码统一放在 USBViewer 项目的 ServiceHelper.cs 文件中。代码首先添加对以下两个命名空间的引用:
[csharp] view plain copy print?
1. using System.Configuration.Install;
2. using System.ServiceProcess;
using System.Configuration.Install; using System.ServiceProcess;
引用 System.Configuration.Install 的目的是使用 TransactedInstaller 类,该类的作用是以事务的方式对服务进行安装或卸载,要么安装或卸载成功,要么回到安装前的状态。在进行操作前常规对服务进行一下检测,看服务是否已经存在,这里使用了 ServiceController 类对服务名进行轮询,只要查找到具有指定名称的服务,就可以知道服务已经存在了。
[csharp] view plain copy print?
1. ///
2. /// 检测服务是否安装。 3. ///
4. ///
6. private static bool IsWindowsServiceInstalled(string serviceName) 7. {
8. ServiceController[] services = ServiceController.GetServices(); 9. foreach (ServiceController service in services) 10. {
11. if (service.ServiceName == serviceName) 12. return true; 13. }
14. return false; 15. }
///
/// 检测服务是否安装。 ///
/// 要查询的服务名。
///
private static bool IsWindowsServiceInstalled(string serviceName) {
ServiceController[] services = ServiceController.GetServices(); foreach (ServiceController service in services) {
if (service.ServiceName == serviceName) return true; }
return false; }
安装服务则按以下方式调用 TransactedInstaller 类:
[csharp] view plain copy print?
1. string[] cmdline = {};
2. TransactedInstaller transactedInstaller = new TransactedInstaller(); 3. AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileNa
me, cmdline);
4. transactedInstaller.Installers.Add(assemblyInstaller);
5. transactedInstaller.Install(new System.Collections.Hashtable());
string[] cmdline = {};
TransactedInstaller transactedInstaller = new TransactedInstaller(); AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
transactedInstaller.Installers.Add(assemblyInstaller);
transactedInstaller.Install(new System.Collections.Hashtable());
注意 Install 方法需要一个 IDictionary 接口类型的变量来保存安装状态,这里使用了哈希表。卸载服务和安装服务时类似,不过是调用 Uninstall 方法,而且可以不用提供保存状态的变量。
[csharp] view plain copy print?
1. transactedInstaller.Uninstall(null);
transactedInstaller.Uninstall(null);
在安装和卸载前,不要忘记对要安装和卸载的服务文件进行检测,确保该文件确实存在。
[csharp] view plain copy print?
1. // 检测相应的服务文件是否存在。
2. string serviceFileName = Path.Combine(Application.StartupPath, \
r.exe\
3. if (File.Exists(serviceFileName) == false) 4. return false;
// 检测相应的服务文件是否存在。
string serviceFileName = Path.Combine(Application.StartupPath, \
if (File.Exists(serviceFileName) == false) return false;
第四节 运行测试
对项目 USBViewer 进行编译,得到一个 EXE 文件:
因为在删除过程中要安装系统服务,运行本程序,需要系统管理员权限,这在 Windows XP 和 Windows Server 2003 等操作系统上,需要以管理员账户登录系统后使用。在 Windows Vista 或 Windows 7 以上的操作系统,由于 UAC (用户账户控制)的问题,可能程序无法运行,毕竟Windows Vista 以上的系统对系统安全性做了进一步增加,对注册表等敏感数据的操作做了进一步的限制,要使得程序能够正常运行,一个方法可以通过右键单击程序,在“兼容性”选项卡,选择“以管理员身份运行本程序”。
或者在每次运行程序时,单击右键选择“以管理员身份运行”。
另外一种方法是使用 app.manifest 文件的方式,把程序运行所需要的权限事先声明,这样就可以避免 Windows UAC 的控制阻拦问题了。具体方法是:在项目 USBViewer 右键单击,选择“属性”-“安全性”,勾选“启用 ClickOnce 安全设置”,
这时会自动为项目添加一个 app.manifest 文件(在项目的 Property 文件夹下),打开该文件,找到
[csharp] view plain copy print?
1. ecutionlevel>