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

我试图自定义user.config文件的位置。 目前它存储有散列和版本号

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

我希望它是不可知的应用程序的版本

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

可以这样做,怎么样? 有什么影响? 升级后,用户是否会丢失之前版本的设置?

为了回答第一个问题,你在技术上可以把文件放在任何你想要的地方,但是你必须自己编码,因为文件默认的地方是你的两个例子中的第一个。 ( 链接到如何自己做 )

至于第二个问题,这取决于你如何部署应用程序。 如果您通过.msi进行部署,则在安装项目的属性(msi由此生成),“升级代码”和“产品代码”中有两个哈希值。 这决定了如何安装msi,以及是否升级,覆盖或安装在相同应用程序的任何其他版本旁边。

例如,如果你有两个版本的软件,他们有不同的“升级”代码,那么对于windows而言,不pipe名字是什么,它们都是完全不同的软件。 但是,如果“升级”代码是相同的,但“产品”代码是不同的,那么当您尝试安装第二个msi它会问你是否要升级,在这个时候它应该从旧configuration到一个新的configuration。 如果两个值相同,并且版本号没有改变,则新的configuration将与旧的configuration位于相同的位置,并且不需要执行任何操作。 MSDN文档

ClickOnce有点不同,因为它基于ClickOnce版本号和URLpath,但是我发现只要你继续“发布”到相同的位置,新版本的应用程序将继续使用现有的configuration。 ( 链接到ClickOnce如何处理更新 )

我也知道有一种方法可以在使用自定义安装脚本安装msi的过程中手动合并configuration,但我不记得确切的步骤来做到这一点…(请参阅此链接以了解如何使用networking。configuration)

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

 Properties.Settings.Value.Upgrade(); 

从客户端设置FAQ博客文章:

问:为什么在user.configpath中有一个版本号? 如果我部署了一个新版本的应用程序,用户不会丢失以前版本保存的所有设置吗?

答:为什么user.configpath是版本敏感的,有几个原因。

(1)支持并行部署不同版本的应用程序(例如,可以使用Clickonce来完成此操作)。 不同版本的应用程序可以保存不同的设置。

(2)升级应用程序时,设置类可能已被更改,可能与保存的内容不兼容,这可能会导致问题。

但是,我们已经很容易地将设置从以前的应用程序版本升级到最新版本。 只需调用ApplicationSettingsBase.Upgrade() ,它将从之前版本中检索与当前版本的类匹配的设置,并将其存储在当前版本的user.config文件中。 您也可以select在设置类或提供者实现中重写此行为。

问:好的,但是我怎么知道什么时候打电话升级?

A:好问题。 在Clickonce中,当您安装新版本的应用程序时,ApplicationSettingsBase将检测到它并在加载点设置时自动升级设置。 在非Clickonce的情况下,没有自动升级 – 你必须自己升级。 这里是确定何时调用升级的一个想法:

有一个名为CallUpgrade的布尔值设置,并将其设置为默认值true。 当您的应用程序启动时,您可以执行如下操作:

 if (Properties.Settings.Value.CallUpgrade) { Properties.Settings.Value.Upgrade(); Properties.Settings.Value.CallUpgrade = false; } 

这将确保仅在部署新版本后第一次运行应用程序时调用Upgrade()。

我不相信它可以实际上工作 – 微软不会提供这种能力,但方法是一样的。

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:
如果这些都不可用,请使用.exepath。
<version>是AssemblyInfo的AssemblyVersionAttribute设置。

详细描述在这里http://msdn.microsoft.com/en-us/library/ms379611.aspx

(我把这个添加为@ Amr的回答,但我没有足够的代表这样做呢。)

MSDN文章中的信息非常清晰,似乎仍然适用。 然而,它没有提到SHA1散列写出基地32编码,而不是更典型的基地16。

我相信正在使用的algorithm是在ToBase32StringSuitableForDirName实现的, 可以在这里findMicrosoft Reference Source 。