2014-02-19 43 views
2

我有一個Windows服務,用C#(.NET 4.5)編寫。此服務有一個user作用域設置,用於保存計時器變量。爲了調試服務,我需要更新這個變量,所以我需要知道服務的文件位於哪裏。因此,我加入該服務的OnStart()方法如下代碼:爲什麼Configuration.FilePath返回一個不存在的文件?

Logger.InfoFormat("user.config at \"{0}\"", ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath); 

什麼傾入我的日誌文件是以下路徑:

C:\Windows\system32\config\systemprofile\AppData\Local\company\service.exe_Url_randomcharacters\1.0.0.0\user.config 

但是當我嘗試打開該文件,它不存在。在Windows搜索之後,我發現實際文件位於:

C:\Windows\SysWOW64\config\systemprofile\AppData\Local\company\service.exe_Url_randomcharacters\1.0.0.0\user.config 

這是爲什麼?我假設一些32位/ 64位兼容性魔術,但是獲得實際路徑的正確代碼是什麼(如果有的話)?

其他信息,如果有幫助:該服務在Windows Server 2008 R2 64位機器上運行,並且通過installutil進行安裝。我不確定是否使用了32位或64位版本的installutil - 這是否會有所作爲?

回答

2

發生這種情況是因爲C:\ Windows \ system32是64位和32位進程的不同目錄。 32位進程在C:\ Windows \ system32中查看C:\ Windows \ SysWOW64的內容。這很瘋狂,但這就是Microsoft決定在許多應用程序中提供與硬編碼C:\ Windows \ system32的兼容性並允許爲32位和64位進程加載正確版本的.dlls(因此64位dll位於C:\ Windows \ system32和32位dll位於C:\ Windows \ SysWOW64)。
默認用於服務的本地系統帳戶具有C:\ Windows \ system32內的配置文件 - 因此32位和64位服務在%LOCALAPPDATA%中查看應用程序應存儲數據的不同文件。因此,例如,當您的64位服務執行32位進程時,子進程不會在%LOCALAPPDATA%中看到哪些父進程爲其準備的文件。

有幾個解決的這個:

  • ,你可以從不同的用戶啓動服務(服務/屬性/登錄/登錄身份:此帳戶) - 但在這種情況下,你必須提供密碼,如果密碼將被更改或過期,服務將無法啓動,直到密碼將更改爲服務。
  • 您可以使用其他位置來存儲數據,而不是%LOCALAPPDATA%,這也不總是可以接受的。
  • 您可以創建結點目錄與您的設置 - 這樣32位和64位應用程序會看到相同的目錄:
    • 運行「psexec.exe -i -s的cmd.exe」作爲管理員(PSEXEC是Sysinternal's PsTools一部分) - in將從系統帳戶打開命令提示符(這也是調試服務的好方法)
    • exec「mklink/J%SystemRoot%\ SysWOW64 \ config \ systemprofile \ AppData \ Local \ company%LOCALAPPADATA%\ company」

無解決方法是完美的,b他們提供了相對簡單的方法來處理這種瘋狂。

相關問題