9

所以...我曾经认为,当您访问一个文件但指定没有路径的名称(在我的情况下为 CAISLog.csv)时,.NET 会期望该文件与正在运行的 .exe 位于同一路径。

这在我逐步执行解决方案(C# .NET2.* VS2K5)时有效,但是当我以正常模式运行应用程序(由 Websphere MQ 触发器监视器启动并在后台作为网络服务运行)而不是访问文件时在 C:\WINDOWS\system32 中查找 .exe 的路径。如果它很重要父任务的 .exe 与我的应用程序在几乎相同的文件夹结构/路径中

我得到一个匹配的错误:“ System.UnauthorizedAccessException:访问路径 'C:\WINDOWS\system32\CAISLog.csv' 被拒绝。

我的解决方法是完全限定我的文件的位置。但是,我想了解的是“在 IO 期间仅指定文件名时,管理如何解析路径的 .NET 规则是什么?” 我觉得我错过了一些基本概念,这让我很烦恼。

编辑 - 我不确定它本身是否是 .NET 规则,但 Schmuli 似乎更清楚地解释了这个概念。我一定会在未来尝试 Rob Prouse 的建议,所以也对此 +1。

如果有人有一些重新措辞的建议,强调我并不真正关心找到我的 .exe 的路径 - 而只是不明白相对路径解析发生了什么(而且我可能仍然把我的术语搞砸了) ...

4

4 回答 4

12

当应用程序 (WinForms) 启动时,其中Environment.CurrentDirectory包含应用程序文件夹的路径(即包含 .exe 程序集的文件夹)。使用任何文件对话框,例如。OpenFileDialog,SaveFileDialog等将导致当前目录更改(如果选择了不同的文件夹)。

运行 Windows 服务时,其包含文件夹是 C:\Windows\System32,因为它是系统文件夹,它是实际运行 Windows 服务的系统(即操作系统)。

请注意,在大多数System.IO对象中指定相对路径将回退到使用该Environment.CurrentDirectory属性。

如前所述,有几种方法可以获取服务可执行文件的路径,使用Assembly.GetEntryAssembly()Assembly.GetExecutingAssembly()然后使用Location属性或CodeBase属性(请注意,这是可执行文件的文件路径,而不是目录)。

另一种选择是使用:

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

在服务的OnStart方法中进行调用,将其应用于整个应用程序。

于 2008-11-05T21:55:21.910 回答
9

它基于当前工作目录,该目录可能与您的应用程序所在的位置相同,也可能不同,尤其是从不同的程序或具有不同工作目录的快捷方式启动时。

与其硬编码路径,不如获取程序的路径并使用它。你可以用这样的东西来做到这一点

Assembly ass = Assembly.GetEntryAssembly();
string dir = Path.GetDirectoryName(ass.Location);
string filename = Path.Combine( dir, "CAISLog.csv" );

这假定条目程序集是您的文件所在的位置。如果没有,您可以将程序集更改为类似的东西;

Assembly ass = Assembly.GetAssembly( typeof( AClassInYourAssembly ) );
于 2008-11-05T20:13:37.713 回答
4

相对路径解析永远不会对启动可执行文件的路径起作用。它总是对进程的当前目录起作用,你不能真的期望它总是设置为 .exe 所在的目录。

如果您需要这种行为,请注意自己找出正确的路径,并为文件操作提供完全限定的路径。

于 2008-11-05T20:10:12.213 回答
-2

您可以使用它来指定与您的 exe @"..\CAISLog.csv" 相同的路径。请注意,双点指的是 .exe 所在位置的父目录。

温迪

于 2008-11-05T20:27:58.387 回答