我可以控制.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 。