2008-11-05 71 views
7

所以......我曾經認爲,當你訪問一個文件,但指定名稱時沒有路徑(在我的情況下爲CAISLog.csv),那麼.NET會希望該文件駐留在與運行的.exe相同的路徑中。默認/相對路徑分辨率在.NET中如何工作?

當我踩着通過解決這個工程(C#.NET2。* VS2K5),但是當我運行在正常模式下的應用程序(由WebSphere MQ的觸發啓動監控&在後臺作爲網絡服務運行),而不是在C:\ WINDOWS \ system32中尋找.exe文件的路徑下訪問該文件。如果有問題父任務的.exe與我的應用幾乎處於相同的文件夾結構/路徑

我得到一個匹配錯誤:「System.UnauthorizedAccessException:訪問路徑'C:\ WINDOWS \ system32 \ CAISLog。 csv'被拒絕

我的解決方法是完全限定我的文件的位置。然而,我想了解的是「在IO期間僅指定文件名時,如何解決路徑解決問題的.NET規則是什麼?」我覺得我錯過了一些基本概念,並且它讓我感到不好。

編輯 - 我不確定它本身就是一個.NET規則,但Schmuli似乎是在更清楚地解釋這個概念。我一定會在未來嘗試羅伯·普勞斯的建議,所以也是如此。

如果任何人有強調我不是發現我的.exe文件的路徑真的照顧一些重新措辭的建議 - 而只是不明白髮生了什麼事情,相對路徑解析(我可能還是有我的terminology搞砸了)...

回答

10

當一個應用程序(的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方法調用,把它應用到整個應用程序。

4

相對路徑分辨率從來沒有工作對啓動可執行文件的路徑。它總是與進程的當前目錄相對應,並且您不能真正期望永遠將其設置爲.exe所在的目錄。

如果您需要該行爲,那麼請注意找出正確的路徑並且提供一個完全合格的文件操作路徑。

9

它基於當前工作目錄,它可能與您的應用程序所在的位置相同或不同,特別是如果從不同的程序或具有不同工作目錄的快捷方式啓動。

不是硬編碼路徑,而是獲取程序的路徑並使用它。你可以用這樣的東西來做到這一點

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

這假定入口程序集是你的文件的位置。如果不是的話,你可以改變組裝類似的東西;

Assembly ass = Assembly.GetAssembly(typeof(AClassInYourAssembly)); 
+2

如果我沒有記錯,Assembly.Location返回程序集的完整路徑,即包含文件名。所以你將不得不調用Path.GetDirectoryName(ass.Location)來實際獲取目錄。除此之外,答案爲+1。 – OregonGhost 2008-11-05 21:02:47

+0

謝謝你,Rob - 有幫助的東西,但我認爲Schmuli的回答給了我更多洞察什麼是困擾我的一般概念。 +1 – 2008-11-05 23:40:10

-2

您可以使用它來指定駐留在您的exe @「.. \ CAISLog.csv」相同路徑的路徑。請注意,雙點指向您的.exe所在位置的父目錄。

RWendi