我可以控制.NET用户设置的位置,以避免在应用程序升级时丢失设置吗?


104

我正在尝试自定义user.config文件的位置。目前,它与哈希和版本号一起存储

%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\

我希望与应用程序版本无关

%AppData%\[CompanyName]\[ProductName]\

这可以做到吗?这意味着什么?升级后,用户会从以前的版本中丢失设置吗?


尽管uzbones的答案在文件位置方面很有用,但我认为Ian在升级方面更正确。
Anthony Mastrean 2011年

4
@AnthonyMastrean我个人认为,任何重要的设置都不应依赖Microsoft提供的ApplicationSettings基础结构。Muxa应该只将设置存储在%AppData%\[CompanyName]/[ProductName]我们可以相信的位置。
伊恩·博伊德

2
毫无疑问,我对内置应用程序和用户设置的持续体验非常糟糕。我建议在appdata或programdata中使用json文件。
Anthony Mastrean 2011年

您还可以将设置存储在注册表中。有关替代设置类的实现,请参见stackoverflow.com/a/12127888/1273550
拉维·帕特尔

Answers:


39

要回答第一个问题,从技术上讲,您可以将文件放在任意位置,但是您必须自己编写代码,因为文件转到的默认位置是两个示例中的第一个。(链接到自己如何做

至于第二个问题,这取决于您如何部署应用程序。如果通过.msi进行部署,则安装项目(建立msi的项目)的属性中有两个散列,即“升级代码”和“产品代码”。这些决定了msi的安装方式,以及是否升级,覆盖或在同一应用程序的任何其他版本旁边安装。

例如,如果您有两个版本的软件,并且它们具有不同的“升级”代码,则对Windows而言,它们是完全不同的软件,无论其名称是什么。但是,如果“升级”代码相同,但“产品”代码不同,则当您尝试安装第二个msi时,它将询问您是否要升级,此时应从中复制值。从旧配置到新配置。如果两个值相同,并且版本号未更改,则新配置将与旧配置位于同一位置,并且无需执行任何操作。 MSDN文档

ClickOnce有点不同,因为它更多地基于ClickOnce版本号和URL路径,但是我发现只要您继续“发布”到相同位置,新版本的应用程序将继续使用现有配置。(链接到ClickOnce处理更新的方式

我也知道有一种方法手动合并CONFIGS在安装过程中使用自定义安装脚本微星的,但我不记得确切的步骤去做...(见这个链接如何与Web做到这一点。配置)


升级代码不是应该保持不变的代码,产品代码不是应该在发行版之间进行更改的代码吗?blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx
estanford,2011年

h!您是对的,简直不敢相信我会倒退(花了两年时间才抓到它)。就像在我过去的某一时刻进行自动签名一样:(
uzbones 2011年

这是否意味着只有安装用户才能升级她的设置?
Micha Wiedenmann

79

我想在将来遇到此问题时添加引用的文本作为参考。可以通过调用Upgrade指示ApplicationSettings基础结构从先前版本复制设置:

Properties.Settings.Value.Upgrade();

客户端设置常见问题的博客帖子:存档

问:为什么在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()。

我一秒钟都不相信它实际上可以工作-微软无法提供这种功能,但是方法是一样的。


3
这完全有效!我只使用了简单的if(CallUpgrade) { Upgrade(); }语句。
Anthony Mastrean 2011年

@Ian Boyd:我喜欢这个主意,我对拥有潜在的解决方案感到非常兴奋,但是我对一件事感到困惑。我没有Properties.Settings.Value 我需要的Properties.Settings部分,但是我是否缺少某些东西?
折射圣骑士

8
这很好用,但是我提醒读者,直到但不包括版本号的配置路径必须相同。即看到@Amr的答案。例如,如果从不同于先前版本的文件路径启动了该应用程序的新版本,则该Upgrade行不通。
斯蒂芬·斯文森

1
@RefractedPaladinProperties.Settings.Default.Upgrade()
Stephen Swensen

5
将其Properties.Settings.Default.Save();更改为false后,请不要忘记添加:-)
Jeff

32

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或Path(基于可用于哈希的证据)。
<hash>是从CurrentDomain收集的SHA1证据哈希,按以下优先顺序排列:
1. StrongName
2. URL:
如果这两个都不可用,请使用.exe路径。
<version>是AssemblyInfo的AssemblyVersionAttribute设置。

完整的说明在这里http://msdn.microsoft.com/zh-cn/library/ms379611.aspx


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.