Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在.NET ClickOnce应用程序中将发布版本同步到程序集版本?_C#_Version_Clickonce_Build Automation - Fatal编程技术网

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

C# 如何在.NET ClickOnce应用程序中将发布版本同步到程序集版本?,c#,version,clickonce,build-automation,C#,Version,Clickonce,Build Automation,在我的C#ClickOnce应用程序中,在项目->属性->发布选项卡中有一个自动递增的发布版本。我想在菜单“帮助->关于”框中显示该版本,但我使用的代码显然访问程序集版本,这是不同的 可以在“项目->属性->应用程序->程序集信息”对话框中手动更改程序集版本。现在,每次发布之前,我都会将发布版本复制到程序集版本,所以我的对话框会显示当前版本的 应用程序。必须有更好的方法来做到这一点 我真正想做的就是有一个准确的、自动更新的、代码可访问的版本号 下面是我用来访问程序集版本号的代码: public

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

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

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

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

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

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

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

  <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>

根据我的经验,西尔瓦纳的最后一句话看起来就像是要走的路;但需要注意的是,它只对应用程序的已部署版本可用。出于调试目的,您可能需要以下内容:

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

        return "Debug";
    }

我修改了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>

$(SolutionDir).build
我不确定项目文件中的位置有多重要,但我在项目文件的末尾添加了这个,就在:

</Project>

我采用了另一种方法,对我的程序集版本-1.0.*-使用了通配符,因此Visual Studio/MSBuild自动生成了一个版本号:

// AssemblyInfo.cs    
[assembly: AssemblyVersion("1.0.*")]
然后,我将以下AfterCompile目标添加到ClickOnce项目中,以将SynchronizePublishVersion与程序集版本分配到一起:

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

%(TargetAssemblyIdentity.Version)

我想进一步阐述Sylvanaar的回答,因为一些实现细节对我来说并不明显。因此:

  • 手动安装位于以下位置的社区生成任务:注意:如果清理了软件包,请不要使用nuget安装,因为生成将在有机会还原软件包之前失败,因为msbuildtasks在生成文件中被引用为任务。我把它们放在名为.build的解决方案文件旁边的文件夹中

  • 将一个完全空的文件添加到名为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>
    

    非常感谢-这是最简单的方法,而且它看起来很有魅力!但这并不理想,因为当右键单击程序集并查看属性时,显示的版本仍然是AssemblyVersion。注意:ApplicationDeployment.IsNetworkDeployed将导致引发第一次异常。这可能会干扰调试等。在从VisualStudio调试ClickOnce应用程序时,请使用
    if(!Debugger.IsAttached&&ApplicationDeployment.*){…}
    避免第一次出现异常。添加if(ApplicationDeployment.IsNetworkDeployed)似乎可以防止任何调试异常,这在VS 2015中可能是新的。我只是想和大家一起讨论和/或帮助别人。没有它,应用程序每次都抛出一个异常。为了以防万一,添加一个try-catch可能不是一个坏主意,我遵循了这一点,但是更改了ApplicationVersion,它似乎可以工作,但网站的版本号是错误的。
      <!-- 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>
    
    public string Version()
    {
        Version version = null;
    
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            version = ApplicationDeployment.CurrentDeployment.CurrentVersion;
        }
        else
        {
            version = typeof(ThisAddIn).Assembly.GetName().Version;
        }
    
        return version.ToString();
    }