我有一个部署到两个不同位置的Windows窗体应用程序。
我为Click-once部署版本ApplicationDeployment.IsNetworkDeployed
显示ClickOnce版本号。
if (ApplicationDeployment.IsNetworkDeployed)
return ApplicationDeployment.CurrentDeployment.CurrentVersion;
但对于非点击应用程序,我不知道如何检索clickonce版本,除非我在汇编信息中对版本号进行硬编码。
是否有自动检索非Clickonce部署版本的ClickOnce版本号?
答案 0 :(得分:95)
将System.Deployment
的装配参考添加到您的项目中。
在您的班级文件中导入名称空间:
VB.NET:
Imports System.Deployment
C#:
using System.Deployment;
从CurrentVersion
媒体资源中检索ClickOnce版本。
您可以从ApplicationDeployment.CurrentDeployment.CurrentVersion
属性获取当前版本。这将返回System.Version
个对象。
注意(来自MSDN):
如果有新的更新,
CurrentVersion
将与UpdatedVersion
不同 已安装但尚未调用Restart
。如果部署 manifest配置为执行自动更新,可以进行比较 这两个值用于确定是否应该重新启动应用程序。
注意:CurrentDeployment
静态属性仅在使用ClickOnce部署应用程序时有效。因此,在访问此属性之前,应首先检查ApplicationDeployment.IsNetworkDeployed
属性。它总是在调试环境中返回false。
VB.NET:
Dim myVersion as Version
If ApplicationDeployment.IsNetworkDeployed Then
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion
End If
C#:
Version myVersion;
if (ApplicationDeployment.IsNetworkDeployed)
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
使用Version
对象:
从这里开始,您可以使用标签中的版本信息,例如在“关于”表单上,以这种方式:
VB.NET:
versionLabel.Text = String.Concat("ClickOnce published Version: v", myVersion)
C#:
versionLabel.Text = string.Concat("ClickOnce published Version: v", myVersion);
(Version
个对象被格式化为一个由四部分组成的数字(major.minor.build.revision)。)
答案 1 :(得分:11)
不,我不相信有办法。我相信ClickOnce信息来自清单,该清单仅在ClickOnce部署中可用。我认为硬编码版本号是您的最佳选择。
答案 2 :(得分:8)
每次推出新版本时,我只是简单地将主程序集的汇编版本与CLickOnce版本相同。然后,当它作为非clickonce应用程序运行时,只需使用Reflection来获取程序集版本。
答案 3 :(得分:4)
尝试线程验证:
if (ApplicationDeployment.IsNetworkDeployed)
{
if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
{
Application.ExitThread();
Application.Restart();
}
}
答案 4 :(得分:2)
硬编码,或...跟踪数据库中的版本(文件,程序集,部署)。使用Assembly调用数据库并获取Deploy版本。
这假定您以逻辑方式递增版本,使每个版本类型都有关系。这个小问题需要做很多工作。我个人会选择Jared的解决方案;虽然我讨厌硬编码任何东西。
答案 5 :(得分:2)
三年后并不重要,但我最终只是用xml reader解析清单文件。
答案 6 :(得分:2)
扩展RobinDotNet的解决方案:
Protip:您可以自动运行程序或脚本,以便在每次构建时从.csproj文件MSBuild配置中为您执行此操作。我为一个我正在维护的Web应用程序执行此操作,执行Cygwin bash shell脚本以执行某些版本控制h4x以从Git历史记录计算版本号,然后预处理编译到构建输出中的程序集信息源文件。 / p>
可以做一个类似的事情来解析项目文件中的ClickOnce版本号,即Project.PropertyGroup.ApplicationRevision
和Project.PropertyGroup.ApplicationVersion
(尽管我不知道版本字符串的含义,但你可以只是猜测,直到它破坏并修复它然后)并将该版本信息插入到程序集信息中。
我不知道ClickOnce版本何时出现,但可能在构建过程之后,因此您可能需要修改此解决方案以获取编译的新编号。 我猜总是/*h4x*/ +1
。
我使用了Cygwin,因为* nix脚本比Windows好得多,解释代码省去了在构建之前构建预构建程序的麻烦,但你可以使用任何技术编写程序想要(包括C#/。NET)。预处理器的命令行进入PreBuildEvent
:
<PropertyGroup>
<PreBuildEvent>
$(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version
</PreBuildEvent>
</PropertyGroup>
正如您所想象的那样,这发生在构建阶段之前,因此您可以在编译之前有效地预处理源代码。我不想自动编辑Properties\AssemblyInfo.cs
文件,以便安全地播放我所做的是创建一个Properties\VersionInfo.base.cs
文件,其中包含具有版本信息的类的文本模板,并标记为{{ 1}}在项目设置中,以便它不用项目编译:
BuildAction=None
(一个非常肮脏,穷人的占位符语法类似于Windows的环境变量,其中一些额外的h4x被用于简单/复杂的缘故)
using System.Reflection;
using EngiCan.Common.Properties;
[assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")]
[assembly: AssemblyRevisionIdentifier("$REVID$")]
是我为保存Git SHA1而创建的自定义属性,因为它对开发人员而言比 a.b.c.d 更有意义。
我的AssemblyRevisionIdentifierAttribute
程序会将该文件复制到refresh-version
,然后替换已经计算/解析的版本信息(我使用Properties\VersionInfo.cs
进行替换,是使用Cygwin的另一个好处)。 sed(1)
被编入该计划。该文件可以从空开始,您应该通过版本控制系统忽略它,因为它会自动更改,生成它的信息已存储在其他位置。
答案 7 :(得分:1)
使用构建组件,您可以从项目文件中读取单击一次版本并自动将其写入程序集信息,以便它们都同步。
答案 8 :(得分:1)
进行线程验证,插入粗化代码......