如何使用C#查找Windows服务的安装目录?

19

我相信使用InstallUtil.exe安装的Windows服务,其工作目录为C:\winnt(或类似)。是否有任何方法可以在安装时访问或捕获服务最初安装的目录?目前,我正在手动将其输入到app.exe.config文件中,但那是非常手动且感觉像是一种hack。

是否有编程方式,在运行时或安装时确定服务的安装位置?

5个回答

34

您可以使用反射来获取正在执行的程序集的位置。这是一个简单的例程,使用反射将工作目录设置为执行程序集的位置:

String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
path = System.IO.Path.GetDirectoryName(path);
Directory.SetCurrentDirectory(path);

1
这不会返回 C:\Windows\system32 吗? - ProfK
@ProfK,不是的,它提供了执行程序集的位置。这将是运行的程序实际可执行文件所在的目录。 - Steve Wranovsky
我的错。我发现我的服务在寻找 C:\Windows\system32 中的 app.config,并且认为它的位置就在那里。 - ProfK

7

您是指需要包含程序集的目录吗?如果是,那很容易:使用Assembly.Location

我不会尝试更改进程的工作目录 - 如果确实允许这样做,我不会感到惊讶,因为这可能会产生不良影响。


谢谢,Jon。你是对的,问题表述不太准确,所以我已经修改了它。 - endian
所以Jon,是否已经确认一旦服务被安装和/或运行,就不想更改其工作文件夹,还是有一种方法可以在服务安装期间设置工作文件夹,以便您可以使用相对路径而不是绝对路径访问文件/文件夹? 我看到我的服务也出现了同样的问题,它基本上是作为测试/调试的exe编写的,然后定义一个单一符号并编译将其编译为服务,但它始终在%SYSTEMROOT%\System32之外运行... - LarryF
@LarryF:我不知道有任何方法可以更改服务使用的工作目录。这并不意味着没有办法这样做,但我不知道其中的方法。 - Jon Skeet

5

我之前不知道Directory.SetCurrentDirectory方法,通常我会这样做:

Environment.CurrentDirectory = System.AppDomain.CurrentDomain.BaseDirectory;

4
尽管有些晚了,但这可能会对某些人有所帮助。我通过使用AppDomain.CurrentDomain.BaseDirectory解决了这个问题。
string someFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\Resources\SomeResource.xml";

AppDomain.CurrentDomain.BaseDirectory可以提供Windows服务实际安装的目录,而不是C:\Windows\system32\路径。

后来我看到@Ramon已经发布了相同的解决方案。


2

InstallUtil.exe 在安装时调用您的应用程序的 ServiceInstaller.Install() 方法。

覆盖它,将其添加到项目的 Installers 列表中,并获取所需的任何信息。


谢谢。Jon和Steve的运行时方法实际上更适合我需要做的事情。 - endian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接