如何在Windows窗体上显示ClickOnce版本号

我有一个Windows窗体应用程序部署到两个不同的位置。

  • 内联网 – ClickOnce
  • 互联网 – 通过Windows安装程序安装在citrix服务器场上

我为单击一次部署的版本ApplicationDeployment.IsNetworkDeployed显示ClickOnce版本号。

 if (ApplicationDeployment.IsNetworkDeployed) return ApplicationDeployment.CurrentDeployment.CurrentVersion; 

但是对于非点击应用程序,我不知道如何检索clickonce版本,除非我在汇编信息中硬编码版本号。

有没有一种自动的方式检索ClickOnce版本号的非clickonce部署版本?

不,我不相信有一个方法。 我相信ClickOnce信息来自只在ClickOnce部署中可用的清单。 我认为硬编码版本号是你最好的select。

  1. System.Deployment的程序集引用添加到您的项目。

  2. 在您的类文件中导入名称空间:

    VB.NET:

     Imports System.Deployment 

    C#:

     using System.Deployment; 
  3. CurrentVersion属性中检索ClickOnce版本。

    您可以从ApplicationDeployment.CurrentDeployment.CurrentVersion属性获取当前版本。 这将返回一个System.Version对象。

    注意(来自MSDN):

    如果已安装新的更新但尚未调用RestartCurrentVersion将与UpdatedVersion不同。 如果部署清单configuration为执行自动更新,则可以比较这两个值以确定是否应重新启动应用程序。

    注意: CurrentDeployment静态属性仅在使用ClickOnce部署应用程序时才有效。 因此,在访问此属性之前,应先检查ApplicationDeployment.IsNetworkDeployed属性。 它总是会在debugging环境中返回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; 
  4. 使用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)。)

每当你发布一个新版本的时候,我会简单地将主程序集的程序集版本和CLickOnce版本一样。 然后,当它作为非clickonce应用程序运行时,只需使用Reflection即可获取程序集版本。

尝试线程validation:

 if (ApplicationDeployment.IsNetworkDeployed) { if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion) { Application.ExitThread(); Application.Restart(); } } 

硬代码或…跟踪您的版本(文件,汇编,部署)在数据库中。 使用您的程序集调用数据库并获取部署版本。

这假定您正在以一种合乎逻辑的方式递增您的版本,以便每个版本types都有关系。 对于这样一个小问题,这是很多的工作。 我会亲自跟Jared解决 尽pipe我讨厌编码任何东西。

这不是三年后的事情,但是我最终只是用XML阅读器parsing清单文件。

扩展RobinDotNet的解决scheme:

Protip:您可以自动运行一个程序或脚本,以便在每次构build时从.csproj文件MSBuildconfiguration中为您执行此操作。 我为一个当前正在维护的Web应用程序执行此操作,执行Cygwin bash shell脚本来执行一些版本控制h4x,以便从Git历史logging中计算版本号,然后预编译生成输出的程序集信息源文件。

类似的事情可以做的parsingClickOnce版本号的项目文件,即Project.PropertyGroup.ApplicationRevisionProject.PropertyGroup.ApplicationVersion (尽pipe我不知道版本string的意思,但你可以猜测,直到它然后打破并修复),并将该版本信息插入到程序集信息中。

我不知道什么时候ClickOnce版本被碰撞,但可能在构build过程后,所以你可能需要修改这个解决scheme,以获得新的编号。 我猜总有/*h4x*/ +1

我使用Cygwin是因为* nix脚本比Windows好得多,并且解释代码可以帮助您在构build之前构build预构build程序 ,但可以使用任何所需技术(包括C#/ .NET)编写程序。 预处理器的命令行进入PreBuildEvent

 <PropertyGroup> <PreBuildEvent> $(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version </PreBuildEvent> </PropertyGroup> 

正如你所想象的,这发生在构build阶段之前,所以你可以在编译之前有效地预处理你的源代码。 我不想自动编辑Properties\AssemblyInfo.cs文件,所以为了安全起见,我所做的就是创build一个Properties\VersionInfo.base.cs文件,该文件包含带有版本信息的类的文本模板并标记为BuildAction=None在项目设置中BuildAction=None ,所以它没有与项目编译:

 using System.Reflection; using EngiCan.Common.Properties; [assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")] [assembly: AssemblyRevisionIdentifier("$REVID$")] 

(一个非常脏,穷人的占位符语法,类似于Windows的环境variables,为了简化/复杂性而使用了一些额外的h4x)

AssemblyRevisionIdentifierAttribute是我为创buildGit SHA1而创build的一个自定义属性,因为它对开发者来说比abcd更有意义。

然后,我的refresh-version程序会将该文件复制到Properties\VersionInfo.cs ,然后replace已经计算/parsing的版本信息(我使用sed(1)进行replace,这是使用Cygwin的另一个好处)。 Properties\VersionInfo.cs被编译到程序中。 该文件可以开始为空,并且应该由版本控制系统忽略它,因为它会自动更改,并且生成它的信息已经存储在别处。

使用构build组件,您可以从项目文件中读取一次性版本,并自动将其写入程序集信息,以使它们同步。

做一个线程validation,插入硬编码…