【发布时间】:2016-02-25 00:14:20
【问题描述】:
我正在寻找一种方法来为我正在开发的这个 Windows 服务创建和/或添加安装程序。要求是不能有 3rd-party 材料(InstallShield、InstallUtil.exe、WiX 等);它必须严格从 C# 中完成,并且我必须在安装服务之前将参数传递给服务。
我基本上只是在编写一个服务来监视用户指定的文件夹及其子目录,以进行特定的更改。我已经构建了服务及其安装程序,但我需要能够将服务分发到客户端的计算机,而我的服务唯一需要的就是安装期间的文件夹路径。
我在 SO 和 Goog 上进行了全面搜索,但我发现很少能帮助我建立自己的设置,所以如果有人可以在这里提供教程或指向当前存在的链接,请帮助我关于如何在没有任何第三方东西的情况下构建自己的安装程序的完整教程,这太棒了。
这是我的通用代码拆分成各自的文件:
程序.cs:
using System.ServiceProcess;
namespace MyService
{
static class Program
{
static void Main( string[] args )
{
ServiceBase.Run( new MyService( args ) );
}
}
}
MyService.cs:
using System;
using System.IO;
using System.ServiceProcess;
namespace MyService
{
public partial class MyService : ServiceBase
{
public MyService( string[] args )
{
InitializeComponent();
this.ServiceName = "MyService";
this.AutoLog = this.CanHandlePowerEvent =
this.CanHandleSessionChangedEvent = this.CanPauseAndContinue = false;
this.CanStop = this.CanShutdown = true;
}
protected override void OnStart( string[] args )
{
FileSystemWatcher watcher = new FileSystemWatcher(/*'watcher' arguments*/)
{ IncludeSubdirectories = true /*, Set NotifyFilters*/};
watcher.Changed += ( sender, e ) => { /*Handle the event*/; };
watcher.EnableRaisingEvents = true;
base.OnStart( args );
}
protected override void OnStop()
{
watcher.Dispose();
base.OnStop();
}
protected override void OnShutdown()
{
watcher.Dispose();
base.OnShutdown();
}
}
}
ProjectInstaller.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
namespace MyService
{
[RunInstaller( true )]
public partial class ProjectInstaller : Installer
{
public ProjectInstaller()
{
InitializeComponent();
EventLogInstaller eventLogInstaller =
this.Installers.Cast<Installer>().First
( installer => installer is EventLogInstaller ) as EventLogInstaller;
if( eventLogInstaller != null )
eventLogInstaller.Log = "MyService";
this.Installers.Add( new ServiceProcessInstaller()
{ Username = null, Password = null } );
this.Installers.Add( new ServiceInstaller()
{ StartType = ServiceStartMode.Automatic } );
}
protected override void OnAfterInstall( IDictionary savedState )
{
base.OnAfterInstall( savedState );
using( ServiceController controller = new ServiceController
( this.serviceInstaller1.ServiceName, Environment.MachineName ) )
{ controller.Start(); }
}
}
}
我希望客户端能够只双击设置文件,然后打开一个窗口,询问他们希望服务监视的顶级目录路径。显然,我需要为它构建一个带有目录浏览器功能的 GUI,我可以很容易地做到这一点,但我不知道如何将它们整合在一起。那么,有人可以告诉我如何将这三个文件或构建它们的可执行文件添加到安装程序中,以便我可以获取路径,将其传递给服务(我将从命令行执行,但我也已经知道如何做这部分),并在我客户的机器上启动并运行它?
【问题讨论】:
-
为什么不使用像 Wix 或 InstallShield 这样的技术?这就是它们存在的原因,以帮助打包并为您提供具有专业外观的安装程序。
-
@JohnKoerner 我不想使用这样的东西有几个原因。 1:我想知道它在幕后是如何运作的。也许有一天我会创建自己的一个或包含类似的功能。 2:我不需要那种强大的东西;我只是为一个非常特殊的东西创建了一个 rinkydink 小服务。 3:这是我必须依赖的更多技术,a)可能存在安全漏洞,b)最终可能会过时。了解自己如何去做比依赖别人去做更有意义。那么为什么不现在就学习呢?
-
Wix 是 open source (MS-RL),因此您可以使用该代码来了解安装程序的工作原理。 Wix 构建了一个 MSI,MSI 中有一些基本操作可以执行安装服务和在添加/删除程序中注册您的产品等操作。另一个优点是您可以引导安装程序以确保在开始安装之前安装正确版本的 .net。如果您自己滚动,则需要自己处理所有这些。
-
谢谢,@JohnKoerner。我会看看它,看看它是否可以帮助我。同时,如果您遇到与我在帖子中描述的内容类似的情况,请在此处回复。
标签: .net c#-4.0 visual-studio-2012 service deployment