Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.Net Windows服务的相对路径问题。。?_.net_File Io_Windows Services_Relative Path - Fatal编程技术网

.Net Windows服务的相对路径问题。。?

.Net Windows服务的相对路径问题。。?,.net,file-io,windows-services,relative-path,.net,File Io,Windows Services,Relative Path,我有一个windows服务,它正在尝试从应用程序目录访问xml文件 Windows服务安装目录:C:\Services\MyService\MyService.exe xml文件的路径:C:\Services\MyService\MyService.xml 我正在尝试使用以下代码访问该文件 using (FileStream stream = new FileStream("MyService.xml", FileMode.Open, FileAccess.Read)) {

我有一个windows服务,它正在尝试从应用程序目录访问xml文件

Windows服务安装目录:C:\Services\MyService\MyService.exe
xml文件的路径:C:\Services\MyService\MyService.xml

我正在尝试使用以下代码访问该文件

using (FileStream stream = new FileStream("MyService.xml", FileMode.Open, FileAccess.Read))
  {
         //Read file           
  }
我得到以下错误

“找不到文件:C:\WINDOWS\system32\MyService.xml”


我的服务正在使用本地系统帐户运行,我不想使用绝对路径

您需要找到服务程序集的路径,如下所示:

static readonly string assemblyPath = 
    Path.GetDirectoryName(typeof(MyClass).Assembly.Location);

using (FileStream stream = File.OpenRead(Path.Combine(assemblyPath, "MyService.xml"))

当启动Windows服务时,当前目录就是系统目录,正如您所发现的那样。用于将相对路径解析为绝对路径的是当前目录,而不是应用程序(服务)目录。(如果要确认,请检查
环境.CurrentDirectory
变量。)

以下帮助器方法可能在此处派上用场:

public static string GetAppRelativePath(string path)
{
    return Path.Combine(Path.GetDirectoryName(
        Assembly.GetEntryAssembly().Location), path);
}
然后您可以将其用作:

using (FileStream stream = new FileStream(Utilities.GetAppRelativePath(
    "MyService.xml"), FileMode.Open, FileAccess.Read))
{
    // Read file
}

然后,路径将根据需要解析为
C:\Services\MyService\MyService.xml

下面的链接提供了一个优雅的解决方案

因为我的服务同时以控制台/服务的形式运行,所以我刚才调用了

Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory) 
在将其作为服务运行之前,例如

static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
                RunAsService();
            }
            else
            {
                RunAsConsole();
            }
        }

在这种情况下,使用
位置
比使用
代码库
更可靠。。。有关信息,请参阅MSDN文档。另一个问题是,您正在使用
typeof(MyClass).Assembly
获取程序的主程序集<代码>汇编。GetEntryAssembly()同样更可靠。@Noldorin#2:相反。不管是谁调用他的程序集,他的代码都应该可以工作。我想你没有抓住要点。您不知道该代码将在哪里定义。从语义上讲,我们感兴趣的不是类的定义位置,而是操作系统首先为程序加载的程序集。我不这么认为。他的代码位于已安装到特定位置的程序集中。不管他的程序集是如何执行的,他都希望查看该位置。路径是否解析为C:\Services\MyService\MyService.xml,这是必需的?我认为这只是一个打字错误。@Waleed:对不起,你说得对。它解析为正确的路径,我只是写了错误的“正确路径”。)GetAbsolutePath(string relativePath)可能是一个更好的方法名。这正是我想要的。非常感谢。还救了我的命你可以在名单上再添一条