Swi*_*ers 92 windows windows-installer windows-services installutil
所以我们已经制作了一个Windows服务来将数据提供给我们的客户端应用程序,一切都很顺利.客户端提出了一个有趣的配置请求,该请求要求在同一服务器上运行此服务的两个实例,并将其配置为指向不同的数据库.
到目前为止,我还没有能够实现这一点,并希望我的同事stackoverflow成员可以提供一些提示,为什么.
目前的设置:
我已经设置了包含windows服务的项目,从现在开始我们称之为AppService,以及处理自定义安装步骤的ProjectInstaller.cs文件,根据App.config中的键设置服务名称,如此:
this.serviceInstaller1.ServiceName = Util.ServiceName;
this.serviceInstaller1.DisplayName = Util.ServiceName;
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Util只是一个静态类,可以从配置文件中加载服务名称.
从这里开始,我尝试了两种不同的方法来安装这两种服务,并且都以相同的方式失败.
第一种方法是简单地安装服务的第一个副本,复制已安装的目录并重命名,然后在修改应用程序配置后运行以下命令以更改所需的服务名称:
InstallUtil.exe /i AppService.exe
Run Code Online (Sandbox Code Playgroud)
当这不起作用时,我尝试创建第二个安装程序项目,编辑配置文件并构建第二个安装程序.当我运行安装程序时它工作正常,但服务没有显示在services.msc中,所以我针对第二个安装的代码库运行了上一个命令.
两次我都收到了InstallUtil的以下输出(仅限相关部分):
运行事务安装.
开始安装的安装阶段.
安装服务App Service Two ... Service App Service 2已成功安装.在日志应用程序中创建EventLog源App Service二...
安装阶段发生异常.System.NullReferenceException:未将对象引用设置为对象的实例.
安装的回滚阶段正在开始.
将事件日志还原到源App Service 2的先前状态.服务应用程序服务2正在从系统中删除...服务应用程序服务2已成功从系统中删除.
回滚阶段成功完成.
事务处理安装已完成.安装失败,并且已执行回滚.
对于冗长的帖子感到抱歉,想确保有足够的相关信息.到目前为止已经难倒我的部分是,它指出该服务的安装成功完成和它关系到创建的NullReferenceException异常似乎得到抛出的事件日志源之后.因此,如果有人知道我做错了什么或有更好的方法,那将非常感激.
jam*_*vey 81
你试过sc/service controller util吗?类型
sc create
Run Code Online (Sandbox Code Playgroud)
在命令行,它将为您提供帮助条目.我想我过去为Subversion做过这个,并将本文作为参考:
http://svn.apache.org/repos/asf/subversion/trunk/notes/windows-service.txt
Mar*_*man 19
您可以通过执行以下操作来运行同一服务的多个版本:
1)将Service可执行文件和config复制到其自己的文件夹中.
2)将Install.Exe复制到服务可执行文件夹(来自.net framework文件夹)
3)在服务可执行文件夹中创建一个名为Install.exe.config的配置文件,其中包含以下内容(唯一服务名称):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ServiceName" value="The Service Name"/>
<add key="DisplayName" value="The Service Display Name"/>
</appSettings>
</configuration>
Run Code Online (Sandbox Code Playgroud)
4)创建批处理文件以安装具有以下内容的服务:
REM Install
InstallUtil.exe YourService.exe
pause
Run Code Online (Sandbox Code Playgroud)
5)在那里,创建一个卸载批处理文件
REM Uninstall
InstallUtil.exe -u YourService.exe
pause
Run Code Online (Sandbox Code Playgroud)
编辑:
请注意,如果我错过了什么,这里是ServiceInstaller类(根据需要调整):
using System.Configuration;
namespace Made4Print
{
partial class ServiceInstaller
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.ServiceProcess.ServiceInstaller FileProcessingServiceInstaller;
private System.ServiceProcess.ServiceProcessInstaller FileProcessingServiceProcessInstaller;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.FileProcessingServiceInstaller = new System.ServiceProcess.ServiceInstaller();
this.FileProcessingServiceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
//
// FileProcessingServiceInstaller
//
this.FileProcessingServiceInstaller.ServiceName = ServiceName;
this.FileProcessingServiceInstaller.DisplayName = DisplayName;
//
// FileProcessingServiceProcessInstaller
//
this.FileProcessingServiceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.FileProcessingServiceProcessInstaller.Password = null;
this.FileProcessingServiceProcessInstaller.Username = null;
//
// ServiceInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.FileProcessingServiceInstaller, this.FileProcessingServiceProcessInstaller });
}
#endregion
private string ServiceName
{
get
{
return (ConfigurationManager.AppSettings["ServiceName"] == null ? "Made4PrintFileProcessingService" : ConfigurationManager.AppSettings["ServiceName"].ToString());
}
}
private string DisplayName
{
get
{
return (ConfigurationManager.AppSettings["DisplayName"] == null ? "Made4Print File Processing Service" : ConfigurationManager.AppSettings["DisplayName"].ToString());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 18
sc create [servicename] binpath= [path to your exe]
Run Code Online (Sandbox Code Playgroud)
这个解决方案对我有用.
Jon*_*ney 10
老问题,我知道,但我很幸运使用InstallUtil.exe上的/ servicename选项.我没有看到它在内置帮助中列出.
InstallUtil.exe /servicename="My Service" MyService.exe
Run Code Online (Sandbox Code Playgroud)
我不完全确定我在哪里读到这个,但我从那以后就没见过.因人而异.
另一种快捷方式指定自定义值ServiceName,并DisplayName使用installutil命令行参数.
在您的ProjectInstaller类中覆盖虚拟方法Install(IDictionary stateSaver)和Uninstall(IDictionary savedState)
public override void Install(System.Collections.IDictionary stateSaver)
{
GetCustomServiceName();
base.Install(stateSaver);
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
GetCustomServiceName();
base.Uninstall(savedState);
}
//Retrieve custom service name from installutil command line parameters
private void GetCustomServiceName()
{
string customServiceName = Context.Parameters["servicename"];
if (!string.IsNullOrEmpty(customServiceName))
{
serviceInstaller1.ServiceName = customServiceName;
serviceInstaller1.DisplayName = customServiceName;
}
}
Run Code Online (Sandbox Code Playgroud)installutil使用/servicename参数添加自定义名称来安装服务:
installutil.exe /servicename="CustomServiceName" "c:\pathToService\SrvcExecutable.exe"
Run Code Online (Sandbox Code Playgroud)请注意,如果未/servicename在命令行中指定,将安装ServiceInstaller属性/ config中指定的ServiceName和DisplayName值的服务.
在使用我们的自动部署软件频繁安装/卸载并排Windows服务时,我没有太多运气,但我最终想出了以下内容,它允许我传入一个参数来指定后缀到命令行上的服务名称.它还允许设计师正常运行,并且可以根据需要轻松调整以覆盖整个名称.
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
protected override void OnBeforeInstall(IDictionary savedState)
{
base.OnBeforeInstall(savedState);
SetNames();
}
protected override void OnBeforeUninstall(IDictionary savedState)
{
base.OnBeforeUninstall(savedState);
SetNames();
}
private void SetNames()
{
this.serviceInstaller1.DisplayName = AddSuffix(this.serviceInstaller1.DisplayName);
this.serviceInstaller1.ServiceName = AddSuffix(this.serviceInstaller1.ServiceName);
}
private string AddSuffix(string originalName)
{
if (!String.IsNullOrWhiteSpace(this.Context.Parameters["ServiceSuffix"]))
return originalName + " - " + this.Context.Parameters["ServiceSuffix"];
else
return originalName;
}
}
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,我可以执行以下操作:如果我已将服务称为"Awesome Service",那么我可以按如下方式安装服务的UAT版本:
InstallUtil.exe /ServiceSuffix="UAT" MyService.exe
这将创建名为"Awesome Service - UAT"的服务.我们使用它来运行在一台机器上并行运行的相同服务的DEVINT,TESTING和ACCEPTANCE版本.每个版本都有自己的一组文件/配置 - 我没有尝试过这个来安装指向同一组文件的多个服务.
注意:您必须使用相同的/ServiceSuffix参数来卸载服务,因此您要执行以下操作来卸载:
InstallUtil.exe /u /ServiceSuffix="UAT" MyService.exe