如何使用Visual Studio为.net Windows Service创build安装程序
如何为使用Visual Studio创build的Windows服务创build安装程序?
在服务项目中执行以下操作:
- 在解决scheme资源pipe理器中双击您的服务.cs文件。 它应该提出一个灰色的屏幕,并谈论从工具箱中拖动的东西。
- 然后右键单击灰色区域并select添加安装程序。 这会将安装程序项目文件添加到您的项目中。
- 然后你将在ProjectInstaller.cs(serviceProcessInstaller1和serviceInstaller1)的devise视图中有两个组件。 然后,您应该根据需要设置属性,例如服务名称和应该运行的用户。
现在你需要做一个设置项目。 最好的办法是使用安装向导。
-
右键单击您的解决scheme并添加一个新项目:添加>新build项目>安装和部署项目>安装向导
一个。 对于不同版本的Visual Studio,这可能会有所不同。 湾 Visual Studio 2010位于:安装模板>其他项目types>安装和部署> Visual Studio安装程序
-
在第二步中,select“为Windows应用程序创build安装程序”。
- 在第3步中,select“主输出来自…”
- 点击完成。
接下来编辑您的安装程序以确保包含正确的输出。
- 右键单击解决scheme资源pipe理器中的安装项目。
- select视图>自定义操作。 (在VS2008中,它可能是查看>编辑器>自定义操作)
- 右键单击“自定义操作”树中的“安装”操作,然后select“添加自定义操作…”
- 在“在项目中select项目”对话框中,select应用程序文件夹,然后单击确定。
- 单击确定以select“主输出来自…”选项。 应该创build一个新的节点。
- 对提交,回滚和卸载操作重复步骤4 – 5。
您可以通过右键单击解决scheme中的安装程序项目来编辑安装程序输出名称,然后select“属性”。 将“输出文件名称:”更改为任何你想要的。 通过select安装程序项目,并查看属性窗口,您可以编辑Product Name
, Title
, Manufacturer
等…
接下来构build你的安装程序,它会产生一个MSI和一个setup.exe。 select你想用来部署你的服务。
我遵循Kelsey的第一套步骤来将安装程序类添加到我的服务项目中,而不是创build一个MSI或setup.exe安装程序,我使服务自我安装/卸载。 以下是我可以用作起点的一项服务的示例代码。
public static int Main(string[] args) { if (System.Environment.UserInteractive) { // we only care about the first two characters string arg = args[0].ToLowerInvariant().Substring(0, 2); switch (arg) { case "/i": // install return InstallService(); case "/u": // uninstall return UninstallService(); default: // unknown option Console.WriteLine("Argument not recognized: {0}", args[0]); Console.WriteLine(string.Empty); DisplayUsage(); return 1; } } else { // run as a standard service as we weren't started by a user ServiceBase.Run(new CSMessageQueueService()); } return 0; } private static int InstallService() { var service = new MyService(); try { // perform specific install steps for our queue service. service.InstallService(); // install the service with the Windows Service Control Manager (SCM) ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); } catch (Exception ex) { if (ex.InnerException != null && ex.InnerException.GetType() == typeof(Win32Exception)) { Win32Exception wex = (Win32Exception)ex.InnerException; Console.WriteLine("Error(0x{0:X}): Service already installed!", wex.ErrorCode); return wex.ErrorCode; } else { Console.WriteLine(ex.ToString()); return -1; } } return 0; } private static int UninstallService() { var service = new MyQueueService(); try { // perform specific uninstall steps for our queue service service.UninstallService(); // uninstall the service from the Windows Service Control Manager (SCM) ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); } catch (Exception ex) { if (ex.InnerException.GetType() == typeof(Win32Exception)) { Win32Exception wex = (Win32Exception)ex.InnerException; Console.WriteLine("Error(0x{0:X}): Service not installed!", wex.ErrorCode); return wex.ErrorCode; } else { Console.WriteLine(ex.ToString()); return -1; } } return 0; }
在Visual Studio 2015社区中也不是Kelsey,也不是Brendan解决scheme。 以下是我如何使用安装程序创build服务的步骤:
- 运行VS,File-> New-> Project
- select.NET Framework 4,在“search安装的模板”中键入“服务”
- select“Windows服务”。 types名称和位置。 按OK。
- 双击Service1.cs,在devise器中右键单击并select“添加安装程序”
- 双击ProjectInstaller.cs。 对于serviceProcessInstaller1打开属性选项卡,并将“帐户”属性值更改为“本地服务”。 对于serviceInstaller1更改“ServiceName”并将“StartType”设置为“自动”。
-
双击serviceInstaller1。 VS创build'serviceInstaller1_AfterInstall'事件。 编写代码:
private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e) { using (System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName)) { sc.Start(); } }
-
构build解决scheme 右键单击项目,然后select“在文件资源pipe理器中打开文件夹”。 转到bin \ Debug。
- 用文本创buildinstall.bat:
::::::::::::::::::::::::::::::::::::::::: ::自动检查并获得pipe理员权限 ::::::::::::::::::::::::::::::::::::::::: @echoclosures CLS 回声。 ECHO ============================= ECHO运行pipe理shell ECHO ============================= :checkPrivileges NET FILE 1> NUL 2> NUL 如果'%errorlevel%'=='0'(goto gotPrivileges)else(goto getPrivileges) :getPrivileges 如果'%1'=='ELEV'(shift&goto gotPrivileges) 回声。 ECHO ********************************** ECHO为特权升级调用UAC ECHO ********************************** setlocal DisableDelayedExpansion 设置“batchPath =%〜0” setlocal EnableDelayedExpansion ECHO Set UAC = CreateObject ^(“Shell.Application”^)>“%temp%\ OEgetPrivileges.vbs” ECHO UAC.ShellExecute“!batchPath!”,“ELEV”,“”,“runas”,1 >>“%temp%\ OEgetPrivileges.vbs” “%temp%\ OEgetPrivileges.vbs” 退出/ B :gotPrivileges :::::::::::::::::::::::::::: :开始 :::::::::::::::::::::::::::: setlocal&pushd。 cd / d%〜dp0 %windir%\ Microsoft.NET \ Framework \ v4.0.30319 \ InstallUtil / i“WindowsService1.exe” 暂停
- 创builduninstall.bat文件(在u盘/ i中改变为/ u)
- 要安装并启动服务运行install.bat,要停止并卸载运行uninstall.bat
InstallUtil类(ServiceInstaller)被Windows Installer社区视为反模式。 这是一个脆弱的过程,忽略了Windows安装程序内置的对服务的支持。
Visual Studio部署项目(在Visual Studio的下一个版本中也不被高度重视和弃用)没有对服务的本地支持。 但是他们可以使用合并模块。 所以我想看一下这篇博客文章,了解如何使用Windows Installer XML创build一个合并模块来expression服务,然后在VDPROJ解决scheme中使用合并模块。
使用Windows安装程序XML扩充InstallShield – Windows服务
IsWiX Windows服务教程
IsWiX Windows服务video