如何在 .NET ClickOnce 应用程序中将发布版本同步到程序集版本?

发布于 2024-08-05 23:23:03 字数 544 浏览 2 评论 0原文

在我的 C# ClickOnce 应用程序中,项目中有一个自动递增的发布版本 -> 属性 -> 发布选项卡。我想在我的菜单帮助中显示该版本 -> 关于框,但我使用的代码显然访问程序集版本,这是不同的。

可以在项目 -> 中手动更改程序集版本属性 -> 申请 ->装配信息对话框。所以现在,每次发布之前我都会将发布版本复制到程序集版本,因此我的对话框显示了当前版本 该应用程序。必须有更好的方法来做到这一点。

我真正想做的就是拥有一个准确的、自动更新的、可通过代码访问的版本号。

这是我用来访问程序集版本号的代码:

public string AssemblyVersion
{
    get
    {
        return Assembly.GetExecutingAssembly().GetName().Version.ToString();
    }
}

另一种方法是查找访问发布版本的代码。

In my C# ClickOnce application, there is an auto-incremented publish version in the Project -> Properties -> Publish tab. I'd like to display that version in my menu Help -> About box, but the code I'm using apparently accesses the assembly Version, which is different.

The Assembly Version can be changed manually in the Project -> Properties -> Application -> Assembly Information dialog. So for now, every time before I publish I've been copying the publish version to the assembly version, so my dialog shows the current version of
the application. There must be a better way to do this.

All I really want to do is have an accurate, auto-updated, code-accessible version number.

Here's the code I'm using to access the assembly version number:

public string AssemblyVersion
{
    get
    {
        return Assembly.GetExecutingAssembly().GetName().Version.ToString();
    }
}

An alternative would be to find code that accesses the publish version.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

萌面超妹 2024-08-12 23:23:03

根据我的经验,希尔瓦纳的最后一句话看起来像是正确的选择;但需要注意的是,它仅适用于应用程序的已部署版本。出于调试目的,您可能需要类似以下内容:

    static internal string GetVersion()
    {
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            return ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
        }

        return "Debug";
    }

sylvanaar's last line looks like the way to go, in my experience; but with the caveat that it is only available to deployed versions of the application. For debugging purposes, you might want something like:

    static internal string GetVersion()
    {
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            return ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
        }

        return "Debug";
    }
隐诗 2024-08-12 23:23:03

我修改了 .csproj 文件以更新程序集版本。我为此创建了一个名为“公开发布”的配置,但不需要这样做。

  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
    <MSBuildCommunityTasksPath>$(SolutionDir)Tools\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
  </PropertyGroup>
  <!-- Required Import to use MSBuild Community Tasks -->
  <Import Project="$(SolutionDir)Tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
  <Target Name="BeforeCompile" Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|PublicRelease'">
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
    </FormatVersion>
    <AssemblyInfo CodeLanguage="CS" OutputFile="$(ProjectDir)Properties\VersionInfo.cs" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" />
  </Target>

发布的版本可能是:

ApplicationDeployment.CurrentDeployment.CurrentVersion

I modified my .csproj file to update the assembly version. I created a configuration called "Public Release" for this, but it's not required to do that.

  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
    <MSBuildCommunityTasksPath>$(SolutionDir)Tools\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
  </PropertyGroup>
  <!-- Required Import to use MSBuild Community Tasks -->
  <Import Project="$(SolutionDir)Tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
  <Target Name="BeforeCompile" Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|PublicRelease'">
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
    </FormatVersion>
    <AssemblyInfo CodeLanguage="CS" OutputFile="$(ProjectDir)Properties\VersionInfo.cs" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" />
  </Target>

The published version may be:

ApplicationDeployment.CurrentDeployment.CurrentVersion
却一份温柔 2024-08-12 23:23:03

我想扩展 Sylvanaar 的答案,因为一些实现细节对我来说并不明显。因此:

  1. 手动安装位于以下位置的社区构建任务:https://github.com/loresoft/msbuildtasks/版本 注意:如果清理软件包,请不要通过 nuget 安装,因为在有机会恢复软件包之前构建将会失败,因为 msbuildtasks 在构建文件中被引用为任务。我将它们放在名为 .build 的解决方案文件旁边的文件夹中

  2. 将一个完全空的文件添加到名为 VersionInfo.cs 的项目属性文件夹中

3 删除这些行(如果 AssemblyInfo.cs 中存在)

[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.*")]

4 修改 csproj 文件

  <!-- Include the build rules for a C# project. -->
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

  <!--INSERT STARTS HERE-->
  <!--note the use of .build directory-->
  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
    <MSBuildCommunityTasksPath>$(SolutionDir)\.build\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
  </PropertyGroup>
  <!-- Required Import to use MSBuild Community Tasks -->
  <Import Project="$(SolutionDir)\.build\MSBuild.Community.Tasks.targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
  <Target Name="BeforeCompile" Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|Release'">
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
    </FormatVersion>
    <AssemblyInfo CodeLanguage="CS" OutputFile="$(ProjectDir)Properties\VersionInfo.cs" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" />
  </Target>

5 使用如下方法访问版本文本:

public string Version()
{
    Version version = null;

    if (ApplicationDeployment.IsNetworkDeployed)
    {
        version = ApplicationDeployment.CurrentDeployment.CurrentVersion;
    }
    else
    {
        version = typeof(ThisAddIn).Assembly.GetName().Version;
    }

    return version.ToString();
}

I would like to expand on Sylvanaar's answer, as some of implementation details weren't obvious to me. So:

  1. Manually install community build tasks found at: https://github.com/loresoft/msbuildtasks/releases Note: Don't install by nuget if you clean your packages, as the build will fail before getting a chance to restore the packages, since msbuildtasks are referenced as a task in the build file. I put these in folder next to solution file called .build

  2. Add a completely empty file to your projects properties folder called VersionInfo.cs

3 Remove these lines if they exist in AssemblyInfo.cs

[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.*")]

4 Modify your csproj file

  <!-- Include the build rules for a C# project. -->
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

  <!--INSERT STARTS HERE-->
  <!--note the use of .build directory-->
  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
    <MSBuildCommunityTasksPath>$(SolutionDir)\.build\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
  </PropertyGroup>
  <!-- Required Import to use MSBuild Community Tasks -->
  <Import Project="$(SolutionDir)\.build\MSBuild.Community.Tasks.targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
  <Target Name="BeforeCompile" Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|Release'">
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
    </FormatVersion>
    <AssemblyInfo CodeLanguage="CS" OutputFile="$(ProjectDir)Properties\VersionInfo.cs" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" />
  </Target>

5 Use a method like the following to access the version text:

public string Version()
{
    Version version = null;

    if (ApplicationDeployment.IsNetworkDeployed)
    {
        version = ApplicationDeployment.CurrentDeployment.CurrentVersion;
    }
    else
    {
        version = typeof(ThisAddIn).Assembly.GetName().Version;
    }

    return version.ToString();
}
微凉徒眸意 2024-08-12 23:23:03

我修改了 sylvanaar 的解决方案以与 VB: 一起使用

- Microsoft.VisualBasic.targets instead of Microsoft.CSharp.targets
- CodeLanguage="VB" instead of CodeLanguage="CS" 
- AssemblyInfo.vb instead of VersionInfo.cs

,路径差异:

- $(SolutionDir).build instead of $(SolutionDir)Tools\MSBuildCommunityTasks
- $(ProjectDir)AssemblyInfo.vb instead of $(ProjectDir)Properties\VersionInfo.cs

,并删除条件:

- Condition="'$(BuildingInsideVisualStudio)' == 'true'"
- Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|PublicRelease'"

我还分别使用 ClickOnce PublisherName 和 ProductName 同步公司和产品,并根据当前日期生成版权:

- AssemblyCompany="$(PublisherName)"
- AssemblyProduct="$(ProductName)" 
- AssemblyCopyright="© $([System.DateTime]::Now.ToString(`yyyy`)) $(PublisherName)"

我最终将其添加到我的 vbproj文件。它需要首先安装 MSBuildTasks NuGet 包:

  <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
    <MSBuildCommunityTasksPath>$(SolutionDir).build</MSBuildCommunityTasksPath>
  </PropertyGroup>
  <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
  <Target Name="BeforeCompile">  
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
    </FormatVersion>
    <AssemblyInfo CodeLanguage="VB" OutputFile="$(ProjectDir)AssemblyInfo.vb" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" AssemblyCompany="$(PublisherName)" AssemblyProduct="$(ProductName)" AssemblyCopyright="© $([System.DateTime]::Now.ToString(`yyyy`)) $(PublisherName)"/>
  </Target>

我不确定项目文件中的位置有多重要,但我将其添加到项目文件的末尾,就在之前:

</Project>

I modified sylvanaar's solution for use with VB:

- Microsoft.VisualBasic.targets instead of Microsoft.CSharp.targets
- CodeLanguage="VB" instead of CodeLanguage="CS" 
- AssemblyInfo.vb instead of VersionInfo.cs

, differences in paths:

- $(SolutionDir).build instead of $(SolutionDir)Tools\MSBuildCommunityTasks
- $(ProjectDir)AssemblyInfo.vb instead of $(ProjectDir)Properties\VersionInfo.cs

, and to remove conditions:

- Condition="'$(BuildingInsideVisualStudio)' == 'true'"
- Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|PublicRelease'"

I also synchronized Company and Product with ClickOnce PublisherName and ProductName respectively and generated a Copyright based on the current date:

- AssemblyCompany="$(PublisherName)"
- AssemblyProduct="$(ProductName)" 
- AssemblyCopyright="© $([System.DateTime]::Now.ToString(`yyyy`)) $(PublisherName)"

I ended up adding this to my vbproj file. It requires the MSBuildTasks NuGet package to be installed first:

  <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
    <MSBuildCommunityTasksPath>$(SolutionDir).build</MSBuildCommunityTasksPath>
  </PropertyGroup>
  <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
  <Target Name="BeforeCompile">  
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
    </FormatVersion>
    <AssemblyInfo CodeLanguage="VB" OutputFile="$(ProjectDir)AssemblyInfo.vb" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" AssemblyCompany="$(PublisherName)" AssemblyProduct="$(ProductName)" AssemblyCopyright="© $([System.DateTime]::Now.ToString(`yyyy`)) $(PublisherName)"/>
  </Target>

I'm not sure how much the location within the project file matters, but I added this to the end of my project file, just before:

</Project>
嘿咻 2024-08-12 23:23:03

我反其道而行之,对程序集版本使用通配符 - 1.0.* - 因此 Visual Studio/MSBuild 自动生成版本号:

// AssemblyInfo.cs    
[assembly: AssemblyVersion("1.0.*")]

然后我将以下 AfterCompile 目标添加到 ClickOnce 项目中,以分配与程序集同步的 PublishVersion版本:

<Target Name="AfterCompile">
    <GetAssemblyIdentity AssemblyFiles="$(IntermediateOutputPath)$(TargetFileName)">
      <Output TaskParameter="Assemblies" ItemName="TargetAssemblyIdentity" />
    </GetAssemblyIdentity>
    <PropertyGroup>
      <PublishVersion>%(TargetAssemblyIdentity.Version)</PublishVersion>
    </PropertyGroup>
</Target>

I did it the other way around, used a wildcard for my assembly version - 1.0.* - so Visual Studio/MSBuild generated a version number automatically:

// AssemblyInfo.cs    
[assembly: AssemblyVersion("1.0.*")]

And then I added the following AfterCompile target to the ClickOnce project to assign synchronize PublishVersion with the assembly version:

<Target Name="AfterCompile">
    <GetAssemblyIdentity AssemblyFiles="$(IntermediateOutputPath)$(TargetFileName)">
      <Output TaskParameter="Assemblies" ItemName="TargetAssemblyIdentity" />
    </GetAssemblyIdentity>
    <PropertyGroup>
      <PublishVersion>%(TargetAssemblyIdentity.Version)</PublishVersion>
    </PropertyGroup>
</Target>
怎会甘心 2024-08-12 23:23:03

其他解决方案将提供来自 AssemblyInfo.cs 的书面文本(例如“2.5.*”)或 .net5 之前的运行时。

为了获得不确定的[1]图像运行时版本(带有构建等),请从后面的 MainWindow.xaml 代码中说:

private string GetVersion() =>
   typeof(MainWindow).Assembly.GetName().Version.ToString();

[1]在确保您处于非确定性模式之后(对于 . net5+),在项目文件中:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <Deterministic>false</Deterministic>

示例:

在 AssemblyInfo.cs 中,给定行:

[assembly: AssemblyVersion("4.1.*")]

ImageRuntimeVersion 将是:

v4.1.3034.8779

The other solutions will offer the written text from AssemblyInfo.cs (eg., "2.5.*") or for pre .net5 runtimes.

In order to get the non deterministic[1] Image Runtime Version (with build etc), say from the MainWindow.xaml code behind:

private string GetVersion() =>
   typeof(MainWindow).Assembly.GetName().Version.ToString();

[1] After making sure you are in non deterministic mode (for .net5+), in the project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <Deterministic>false</Deterministic>

Example:

In AssemblyInfo.cs, given the line:

[assembly: AssemblyVersion("4.1.*")]

ImageRuntimeVersion will be:

v4.1.3034.8779

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文