我正在尝试自定义user.config
文件的位置。目前它与哈希和版本号一起存储
%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\
我希望它与应用程序的版本无关
%AppData%\[CompanyName]\[ProductName]\
这可以做到吗?怎么做?有什么影响?升级后用户会丢失以前版本的设置吗?
我想添加此引用的文本作为将来遇到此问题时的参考。假设您可以通过调用Upgrade指示 ApplicationSettings 基础结构从以前的版本复制设置:
Properties.Settings.Value.Upgrade();
来自客户端设置常见问题解答博客文章:(存档)
Q:为什么user.config路径中有版本号?如果我部署新版本的应用程序,用户不会丢失之前版本保存的所有设置吗?
答:user.config 路径对版本敏感的原因有两个。
(1) 支持应用程序不同版本的并行部署(例如,您可以使用 Clickonce 来做到这一点)。不同版本的应用程序可以保存不同的设置。
(2) 升级应用程序时,设置类可能已更改,可能与保存的内容不兼容,这可能会导致问题。
但是,我们可以轻松地将设置从应用程序的早期版本升级到最新版本。只需调用 ApplicationSettingsBase.Upgrade(),它就会从先前版本中检索与当前版本的类匹配的设置,并将它们存储在当前版本的 user.config 文件中。您还可以选择在设置类或提供程序实现中覆盖此行为。
问:好的,但我怎么知道何时调用升级?
答:好问题。在 Clickonce 中,当您安装应用程序的新版本时,ApplicationSettingsBase 会检测到它并在加载设置时自动为您升级设置。在非 Clickonce 的情况下,没有自动升级 - 您必须自己调用升级。这是确定何时调用升级的一种方法:
有一个名为 CallUpgrade 的布尔设置,并给它一个默认值 true。当您的应用启动时,您可以执行以下操作:
if (Properties.Settings.Value.CallUpgrade)
{
Properties.Settings.Value.Upgrade();
Properties.Settings.Value.CallUpgrade = false;
}
这将确保仅在部署新版本后应用程序第一次运行时调用 Upgrade()。
我根本不相信它真的可以工作——微软不可能提供这种能力,但方法是一样的。
要回答第一个问题,从技术上讲,您可以将文件放在您想要的任何位置,但是您必须自己编写代码,因为文件的默认位置是您的两个示例中的第一个。(链接到如何自己做)
至于第二个问题,这取决于你如何部署应用程序。如果您通过 .msi 进行部署,则安装项目(构建 msi)的属性中有两个哈希值,即“升级代码”和“产品代码”。这些决定了如何安装 msi,以及它是否升级、覆盖或安装在同一应用程序的任何其他版本旁边。
例如,如果您有两个版本的软件并且它们具有不同的“升级”代码,那么对于 Windows,无论名称是什么,它们都是完全不同的软件。但是,如果“升级”代码相同,但“产品”代码不同,那么当您尝试安装第二个 msi 时,它会询问您是否要升级,此时它应该从旧配置到新配置。如果两个值相同,并且版本号没有更改,那么新配置将与旧配置位于同一位置,并且不需要执行任何操作。 MSDN 文档
ClickOnce 有点不同,因为它更多地基于 ClickOnce 版本号和 URL 路径,但是我发现只要您继续“发布”到同一位置,新版本的应用程序将继续使用现有配置。(链接到 ClickOnce 如何处理更新)
我也知道有一种方法可以在安装 msi 期间使用自定义安装脚本手动合并配置,但我不记得执行此操作的确切步骤...(有关如何使用 web.xml 执行此操作的链接,请参阅此链接。配置)
user.config 文件存储在
c:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<verison>
<c:\Documents and Settings>
是用户数据目录,非漫游(上面的本地设置)或漫游。
<username>
是用户名。
<companyname>
是 CompanyNameAttribute 值(如果可用)。否则,忽略此元素。
<appdomainname>
是 AppDomain.CurrentDomain.FriendlyName。这通常默认为 .exe 名称。
<eid>
是基于可用于散列的证据的 URL、StrongName 或路径。
<hash>
是从 CurrentDomain 收集的证据的 SHA1 哈希,按以下优先顺序排列:
1. StrongName
2. URL:
如果这些都不可用,请使用 .exe 路径。
<version>
是 AssemblyInfo 的 AssemblyVersionAttribute 设置。
完整的描述在这里http://msdn.microsoft.com/en-us/library/ms379611.aspx
(我会将此作为评论添加到@Amr 的答案中,但我还没有足够的代表来做到这一点。)
MSDN 文章中的信息非常清楚,似乎仍然适用。然而,它没有提到 SHA1 散列是用 base 32 编码的,而不是更典型的 base 16。
我相信正在使用的算法是在 中实现的ToBase32StringSuitableForDirName
,可以在 Microsoft 参考源中找到。