Dot-Net

定義應保存 user.config 文件的自定義路徑?

  • July 1, 2014

例如,如果我將編譯的應用程序重命名為 from myapp.exeapp.exe那麼當我執行重命名的執行檔時,會在此路徑中生成一個新的使用者設置文件夾:

C:\Users\{User}\AppData\Local\{CompanyName}\{ExecutableName}_Url_{SystemGUID or something strange}

所以我鬆開了所有保存的設置。

那麼我如何解決這個問題,在VBNET WinForms我自己的位置定義來儲存user.config文件,或者使用 applicationsettings 基礎設施的任何其他解決方案?(不保存系統資料庫或其他東西上的設置)

PS:我讀過這篇 SO 文章,這是一個有點不同的問題,但無論如何我不理解所謂的解決方案我可以控制 .NET 使用者設置的位置以避免失去應用程序升級的設置嗎?

來自回答您問題的連結的更多資訊和花絮:

您引用的“systemGUID 或其他內容”實際上是兩件事的雜湊(參考MSDN My.Settings):

<eid> is the URL, StrongName, or Path, based on the evidence available to hash.  
<hash> is a SHA1 hash of evidence gathered from the CurrentDomain, 
   in the following order of preference: 
   - StrongName 
   - URL If neither of these is available, use the .exe path.

如果沒有 StrongName,您的位置會因路徑而異,這就是您描述的問題。由於 eid 和 hash 都將使用 StrongName 作為 hash(es),即使他們將其移動到其他地方或安裝新版本,完整路徑也應該保持不變。使用 StrongName 時,憑據來自應用程序,並且雜湊值不會更改,並且永遠不會使用最後的方法(exe 路徑)。這回答了您的基本問題:使用強名稱並且路徑不會改變。

新版本/版本將為設置的每個版本在該文件夾下創建一個子文件夾樹。連結中提到的Upgrade方法(顯然)有助於從以前的版本導入設置。Settings但是,EXE 名稱的更改將導致 AppDomain.FriendlyName(第三個元素)發生更改。


隔離儲存是另一種選擇,它不像最初看起來那麼難,但具有類似的行為。使用 Iso,您無需指定文件夾,因為它只是在一個不起眼的位置(如Users\<User>\Isolated Storage\zhxytg\dhfyres\. 如果您使用 ClickOnce(因此,這是另一個可行的解決方案),該位置對於所有版本的應用程序都可以保持相同,即使您重命名它。

我認為您必須使用 ClickOnce (StrongName 作為 MSDN 中沒有出現的替代品)來獲得應用程序級別的證據。ProgramData\AllUsers作為附帶的好處,使用 ISO,即使在最高安全性下,非管理員使用者也可以至少使用 W7讀取/寫入共享文件(如許可證或應用程序套件的共享設置)。應用程序的雜湊允許它寫入該路徑,因此它可以做一些我們通常不能做的事情。

如果您不使用 ClickOnce,您仍然可以在每次安裝和讀取/寫入時獲得一個穩定的文件夾AllUsers。新安裝(到不同的文件夾)將導致不同的雜湊和文件位置;與更改文件名相同。即使您設法將舊位置儲存在某處,新安裝也可能無權訪問舊文件(未嘗試過)。

ISO 刪除了 EXEName 的變化,但它不使用 My.Settings。相反,您使用IsolatedFileStreamsIsolatedStorageFile對象創建。而且您必須接管組織和管理各種設置的值和名稱。使用的隔離儲存類型(應用程序/使用者)取決於可用的憑據。

獨立儲存有它的位置,但對於設置來說似乎有點矯枉過正。


您提到您通常只將 MySettings 用於瑣碎的應用程序。因此,一個 StrongName 只是為了穩定設置路徑似乎是矯枉過正。ISO 非常有趣,但有一些更簡單的東西。這第三個選項屬於or other things您不想要的,但非常靈活。

圍繞序列化建構您自己的設置類。對於簡單的設置,這些可能不僅僅是一組名稱-值對 {LastPath = “…..”; FormLeft = x; FormTop = y …}。將這些保存在Dictionary(Of String, String)or中Dictionary(Of enumSettings, String),然後序列化(保存)整個容器:

Dim bf As New BinaryFormatter
Using fs As New FileStream(myFile, FileMode.OpenOrCreate)
   bf.Serialize(fs, _UserOpts)   
End Using

取回這些值同樣簡單。對於需要保存許多類型的更複雜的項目,例如 Integer、Date、Array、ArrayList、List(of T) 等,請為它們創建一個 UserOptions 類並對其進行序列

請注意,您將文件流傳遞給序列化程序,因此您可以完全控制名稱和位置,例如C:\Users\<username>\AppData\Local\<Company>\<Product>\Settings.bin 位置不會因版本、文化、程序集等而改變。它將保留在您放置的位置。

當您嘗試對 Point、Size 和 Font 等類型進行序列化時,這確實會失去動力,因為無法直接序列化對象。特別是,使用 ProtoBuff 有多個選項可以將這些轉換為動態或預先可序列化的東西。

我想您也可以使用ConfigurationManager.OpenExeConfiguration方法從特定位置打開配置文件。

希望我有所幫助!

引用自:https://stackoverflow.com/questions/20120457