【问题标题】:How to find windows service exe path如何找到windows服务exe路径
【发布时间】:2010-05-14 12:09:29
【问题描述】:

我有一个 Windows 服务,我需要创建目录来存储一些信息。目录路径必须相对于 windows 服务 exe 文件。 这个exe文件路径怎么获取?

【问题讨论】:

  • 我不是 Windows 开发人员,但您确定要这个吗?这些信息不属于用户的个人目录,还是属于LocalService的目录?
  • @Pekka 我不是 Unix 开发人员,但将文件存储在用户个人目录中的系统服务(守护进程)听起来简直是疯了。

标签: c# .net windows-services


【解决方案1】:

【讨论】:

  • 如果您使用其他帐户运行服务,此解决方案将无法正常工作...
  • 当我这样做时,对于作为本地系统运行的服务,它的计算结果为 c:\windows\system32
  • 对于安装程序,这指向 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ 而不是可执行文件
  • @Lectere 你能详细说明一下吗?我一直在使用这种方法,并且从来没有遇到过这个属性的问题,但我不想被客户环境弄得措手不及。它似乎适用于本地系统、本地服务、网络服务、我创建的随机本地用户......
  • 不起作用说明:由于未处理的异常,该进程已终止。异常信息:System.IO.FileNotFoundException:找不到配置文件“appsettings.json”并且不是可选的。物理路径是 'C:\WINDOWS\TEMP\.net\FreshIQAppMessagingService\zu4jbgzc.let AppDomain.CurrentDomain.BaseDirectory 作为 Windows 服务运行时返回 WINDOWS\TEMP 路径。
【解决方案2】:

提示:如果要查找已安装windows服务的启动路径,请从注册表中查看。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\ + ServiceName

有关于windows服务的键

【讨论】:

  • @user1034912 - 我认为它读起来很好(至少,我知道在我的工作系统上我可以读取 HKEY_LOCAL_MACHINE)。虽然写不出来。
【解决方案3】:

要获取服务路径,您可以使用管理对象。 参考:https://msdn.microsoft.com/en-us/library/system.management.managementobject(v=vs.110).aspx http://dotnetstep.blogspot.com/2009/06/get-windowservice-executable-path-in.html

using System.Management;
string ServiceName = "YourServiceName";
using (ManagementObject wmiService = new ManagementObject("Win32_Service.Name='"+ ServiceName +"'"))
                {
                    wmiService.Get();
                    string currentserviceExePath = wmiService["PathName"].ToString();
                    Console.WriteLine(wmiService["PathName"].ToString());
                }

【讨论】:

  • 不错的选择,谢谢!您是否有类似的方式来获取 win 服务配置路径?或者只是将“.config”添加到路径中?
  • @OlehUdovytskyi。您可以使用var config = System.Configuration.ConfigurationManager.OpenExeConfiguration(svcPath),然后检查config.HasFileconfig.FilePath 变量。
【解决方案4】:

与其使用相对于可执行文件的目录,因此需要管理员权限,不如使用通用的应用程序数据目录,它可以通过

访问
Environment.GetFolderPath(SpecialFolder.CommonApplicationData)

这样您的应用就不需要对其自己的安装目录进行写访问,这让您更加安全。

【讨论】:

  • 另外,在 Windows Vista 和 Windows 7 中,您无法写入程序文件夹,即使是管理员!
  • 您将如何解决以这种方式对同一服务或程序进行不同的、单独的安装,例如租户或不同的临时环境,而必须完全不知道彼此?我很想更多地使用这种方法,但会因此而退缩。
【解决方案5】:

试试这个

System.Reflection.Assembly.GetEntryAssembly().Location

【讨论】:

  • 在 ProjectInstaller AfterInstall 事件中不起作用,对象为空。
【解决方案6】:
string exe = Process.GetCurrentProcess().MainModule.FileName;
string path = Path.GetDirectoryName(exe); 

svchost.exe 是运行您在 system32 中的服务的可执行文件。因此我们需要找到进程正在运行的模块。

【讨论】:

  • 在 ProjectInstaller AfterInstall 事件中不起作用。需要 Windows 服务安装目录,而不是 system32。
【解决方案7】:

Windows 服务的默认目录是 System32 文件夹。但是,在您的服务中,您可以通过在 OnStart 中执行以下操作将当前目录更改为您在服务安装中指定的目录:

        // Define working directory (For a service, this is set to System)
        // This will allow us to reference the app.config if it is in the same directory as the exe
        Process pc = Process.GetCurrentProcess();
        Directory.SetCurrentDirectory(pc.MainModule.FileName.Substring(0, pc.MainModule.FileName.LastIndexOf(@"\")));

编辑:一个更简单的方法(但我还没有测试过):

System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);

【讨论】:

  • 在 ProjectInstaller AfterInstall 事件中不起作用,对象为空。
【解决方案8】:

这对我有用

Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);    

【讨论】:

    【解决方案9】:

    即使在默认为 system32 的 LocalSystem 帐户下运行,这也会返回正确的路径:

    System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
    

    【讨论】:

      【解决方案10】:

      如果您想访问 Program Files 文件夹或任何其他使用编程的文件夹,您应该使用以下代码,该代码提供特定文件夹的权限。

       private bool GrantAccess(string fullPath)
              {
                  DirectoryInfo dInfo = new DirectoryInfo(fullPath);
                  DirectorySecurity dSecurity = dInfo.GetAccessControl();
                  dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
                  dInfo.SetAccessControl(dSecurity);
                  return true;
              }
      

      【讨论】:

      • 如果这确实有效(我非常怀疑它会有效,但我没有方便检查的 Windows 机器),那么它将向任何人开放对程序文件目录的写访问 - 包括未经身份验证的用户。这是完全不负责任的,因为它打开了一英里宽的安全漏洞。
      • @Stewart 使用服务,如果文件位于 C 驱动器中,则无法使用文件夹路径直接写入文件。为此,您首先需要授予权限,然后在完成所有操作后,您需要收回所有权利。
      • 请不要这样做。糟糕的安全实践
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-14
      • 2011-02-02
      • 2021-08-18
      • 2012-10-12
      相关资源
      最近更新 更多