如何为使用Visual Studio创建的Windows服务创建安装程序?
答案 0 :(得分:191)
在服务项目中,执行以下操作:
现在您需要制作一个安装项目。最好的办法是使用设置向导。
右键单击您的解决方案并添加新项目:添加>新项目>设置和部署项目>设置向导
一个。对于不同版本的Visual Studio,这可能略有不同。 湾Visual Studio 2010位于:安装模板>其他项目类型>设置和部署> Visual Studio安装程序
在第二步中选择“为Windows应用程序创建安装程序。”
接下来编辑安装程序以确保包含正确的输出。
您可以通过右键单击解决方案中的Installer项目来编辑安装程序输出名称,然后选择“属性”。将“输出文件名:”更改为您想要的任何内容。通过选择安装程序项目并查看属性窗口,您可以编辑Product Name
,Title
,Manufacturer
等...
接下来构建安装程序,它将生成一个MSI和一个setup.exe。选择您要用于部署服务的任何一个。
答案 1 :(得分:47)
我按照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;
}
答案 2 :(得分:21)
Nor Kelsey和Brendan解决方案在Visual Studio 2015社区中对我不起作用。
以下是我使用安装程序创建服务的简要步骤:
->
新 ->
< KBD>项目 双击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
/i
更改为/u
)答案 3 :(得分:9)
对于VS2017,您需要添加&#34; Microsoft Visual Studio 2017安装程序项目&#34; VS扩展。这将为您提供其他Visual Studio Installer项目模板。 https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview
要安装Windows服务,您可以添加新的设置向导类型项目,并按照Kelsey的回答https://stackoverflow.com/a/9021107/1040040
中的步骤进行操作答案 4 :(得分:1)
Windows Installer社区将InstallUtil类(ServiceInstaller)视为反模式。这是一个脆弱的过程,重新发明轮子,忽略了Windows Installer内置的服务支持这一事实。
Visual Studio部署项目(在Visual Studio的下一版本中也未得到高度重视和弃用)没有对服务的本机支持。但是他们可以使用合并模块。所以我将看看这篇博客文章,了解如何使用Windows Installer XML创建合并模块,该模块可以表达服务,然后在VDPROJ解决方案中使用该合并模块。
Augmenting InstallShield using Windows Installer XML - Windows Services
答案 5 :(得分:1)
我知道这是一个旧线程,但是我只想加上2美分。我一直讨厌您在VS中管理服务项目的方式。这就是为什么我多年来使用Topshelf的原因。退后一步,不要创建服务项目,而是创建控制台项目,然后向其中添加Topshelf。这很简单。