如何使用Visual Studio为.net Windows服务创建安装程序
本文关键字:服务 创建 安装 程序 Windows net 何使用 Visual Studio | 更新日期: 2023-09-27 18:21:35
如何为使用Visual Studio创建的Windows服务创建安装程序?
在服务项目中执行以下操作:
- 在解决方案资源管理器中双击services.cs文件。它应该会显示一个全是灰色的屏幕,并谈论从工具箱中拖动东西
- 然后右键单击灰色区域并选择添加安装程序。这将向您的项目中添加一个安装程序项目文件
- 然后,ProjectInstaller.cs的设计视图中将有两个组件(serviceProcessInstaller1和serviceInstaller1)。然后,您应该根据需要设置属性,例如服务名称和应该作为其运行的用户
现在你需要做一个安装项目。最好使用安装向导。
-
右键单击解决方案并添加新项目:添加>新建项目>设置和部署项目>设置向导
a。对于不同版本的Visual Studio,这可能略有不同。b.Visual Studio 2010位于:安装模板>其他项目类型>设置和部署>Visual Studio安装程序
-
在第二步中,选择";为Windows应用程序创建安装程序"
-
在第3步中,选择";来自的主要输出"
-
单击"完成"。
接下来编辑安装程序以确保包含正确的输出。
- 右键单击解决方案资源管理器中的安装项目
- 选择"视图">自定义操作。(在VS2008中,它可能是"视图">"编辑器">"自定义操作")
- 右键单击"自定义操作"树中的"安装"操作,然后选择"添加自定义操作…"
- 在";选择项目中的项目";对话框中,选择"应用程序文件夹",然后单击"确定"
- 单击"确定"以选择";来自的主要输出"选项应该创建一个新节点
- 对提交、回滚和卸载操作重复步骤4-5
右键单击解决方案中的安装程序项目并选择"属性",可以编辑安装程序输出名称。将"输出文件名:"更改为您想要的任何名称。通过选择安装程序项目并查看属性窗口,您可以编辑Product Name
、Title
、Manufacturer
等…
下一步生成安装程序,它将生成MSI和setup.exe。选择要用于部署服务的任何一个。
我按照Kelsey的第一组步骤将安装程序类添加到我的服务项目中,但我没有创建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解决方案都不适用于我。
以下是我如何使用安装程序创建服务的简短步骤:
- 运行Visual Studio,转到文件
->
新建->
Project - 选择.NET Framework 4,在"搜索已安装的模板"中键入"服务"
- 选择"Windows服务"。键入名称和位置。按确定
- 双击Service1.cs,右键单击设计器并选择"添加安装程序"
- 双击ProjectInstaller.cs。对于serviceProcessInstaller1,打开"属性"选项卡,将"帐户"属性值更改为"LocalService"。对于serviceInstaller1,请更改"ServiceName"并将"StartType"设置为"Automatic"
-
双击serviceInstaller1。Visual Studio创建
serviceInstaller1_AfterInstall
事件。写入代码:private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e) { using (System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName)) { sc.Start(); } }
-
构建解决方案。右键单击项目并选择"在文件资源管理器中打开文件夹"。转到bin''Debug。
-
使用以下脚本创建install.bat:
::::::::::::::::::::::::::::::::::::::::: :: Automatically check & get admin rights ::::::::::::::::::::::::::::::::::::::::: @echo off CLS ECHO. ECHO ============================= ECHO Running Admin shell ECHO ============================= :checkPrivileges NET FILE 1>NUL 2>NUL if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges ) :getPrivileges if '%1'=='ELEV' (shift & goto gotPrivileges) ECHO. ECHO ************************************** ECHO Invoking UAC for Privilege Escalation ECHO ************************************** setlocal DisableDelayedExpansion set "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" exit /B :gotPrivileges :::::::::::::::::::::::::::: :START :::::::::::::::::::::::::::: setlocal & pushd . cd /d %~dp0 %windir%'Microsoft.NET'Framework'v4.0.30319'InstallUtil /i "WindowsService1.exe" pause
- 创建uninstall.bat文件(将最后一行
/i
更改为/u
) - 要安装并启动服务,请运行install.bat;要停止并卸载,请运行uninstall.bat
对于VS2017,您需要添加"Microsoft Visual Studio 2017安装程序项目"VS扩展。这将为您提供额外的Visual Studio安装程序项目模板。https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview
要安装windows服务,您可以添加一个新的安装向导类型的项目,并按照Kelsey的回答中的步骤进行操作https://stackoverflow.com/a/9021107/1040040
InstallUtil类(ServiceInstaller)被Windows Installer社区视为反模式。这是一个脆弱的、脱离过程的、重新发明的轮子,忽略了Windows安装程序对服务的内置支持这一事实。
Visual Studio部署项目(在下一版本的Visual Studio中也不受重视和反对)没有对服务的本机支持。但它们可以使用合并模块。因此,我想看看这篇博客文章,了解如何使用Windows Installer XML创建一个合并模块,该模块可以表达服务,然后在您的VDPROJ解决方案中使用该合并模块。
使用Windows Installer XML增强InstallShield-Windows服务
IsWiX Windows服务教程
IsWiX Windows服务视频