2011-07-25 71 views
3

我正在編寫一個C#Windows應用程序來爲遺留應用程序更新.ini文件。我沒有遺留應用程序的來源,所以我無法修改它。無法修改c: windows目錄中的.ini文件

傳統應用程序將設置存儲在C:\ Windows中的INI文件中。這個位置不能改變。

要修改我一直在使用這些Windows功能INI設置:

[DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString")] 
private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName); 

[DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileString")] 
private static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName); 

上述功能似乎並沒有修改INI文件,但後續調用「GetPrivateProfileString」顯示正確的/修改值。

此外,我甚至嘗試使用System.IO類直接寫入INI文件。這似乎沒有修改INI文件。

如果我嘗試將文件複製到應用程序的目錄,然後編寫INI設置,則會寫入正確的值。如果我然後嘗試將此修改後的文件複製回C:\ Windows,原始INI文件似乎不會被修改。

似乎有一些類型的INI文件緩存發生在操作系統級別?

如果我使用文本編輯器手動編輯INI文件,則會更新INI文件。

至於建議在其他論壇上我也試着寫INI設置後,此代碼:

WritePrivateProfileString(null, null, null, filename); 

我的問題是繼承應用程序不拿起INI文件的更改(甚至在重新啓動後傳統應用程序)。

回答

4

在UAC下,沒有UAC清單的應用程序嘗試執行UAC防止操作時會受到虛擬化影響,這會寫入鏡像位置而不是受保護位置當您嘗試讀取時,如果鏡像位置中有文件,那麼您將獲得該文件。這樣,即使您的應用程序與當時的最佳做法相矛盾,您的應用程序也可以正常工作。

要找到鏡像位置,請打開Windows資源管理器添加到該文件夾​​,然後在工具欄中找到一個說明兼容性F的按鈕iles: UAC virtualization

也許這對於您來說已經足夠了 - 現在您知道在哪裏可以信任虛擬化並且該應用程序將正常工作。如果沒有,請考慮在應用程序上添加外部清單。清單說asInvoker將阻止虛擬化,寫入將失敗。如果應用程序有錯誤處理(如回落到另一個位置),這可能是好的。清單requireAdministrator將阻止虛擬化並且寫入將成功。但是,UAC同意可能會惹惱您的用戶。

(圖像,順便說一句,從我的博客文章,討論更多的關於虛擬化。http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx

我發現許多應用程序,以管理員身份跑單變到位後,我的設置我可以跑步而不提升。在這種情況下,訓練您的用戶以右鍵單擊,以管理員身份運行。

3

這從Vista開始,以提高安全性。如果應用程序嘗試寫入受保護的位置(如將ini文件寫入ProgramFiles下的應用程序文件夾或Windows文件夾,則應用程序對該文件的讀取和寫入將重定向到C:\ Users {username } \ AppData \ Local \ VirtualStore \

+0

當我通過文本編輯器保存INI文件時,它更新C:\ Windows \ XXX.ini文件。爲什麼這不會更新C:\ Users {用戶名} \ AppData \ Local \ VirtualStore \版本? – FattyPotatoes

+0

我認爲這可能是因爲重定向的UAC代碼知道應用程序是否是遺留的(pre vista),並且只有在應用程序是遺留的時才重定向。 – hatchet

+0

@FattyPotatoes它永遠不會更新兩個。我的猜測是你的文本編輯器正在運行提升 - 也許是因爲你提出了這個要求,或者是因爲你以管理員身份登錄(不僅僅是管理員組中的某個帳戶)。擡起的文本編輯器可以寫入該位置。 –