Подтвердить что ты не робот

Как синхронизировать версию публикации с версией сборки в приложении .NET ClickOnce?

В моем приложении С# ClickOnce на вкладке "Проект → Свойства → Опубликовать" есть версия с автоматическим добавлением публикации. Я хотел бы отобразить эту версию в своем меню "Справка → О программе", но код, который я использую, по-видимому, обращается к версии сборки, которая отличается.

Версия сборки может быть изменена вручную в диалоговом окне Project → Properties → Application → Assembly Information. Так что пока, каждый раз перед публикацией я копировал версию публикации в версию сборки, поэтому в моем диалоговом окне отображается текущая версия приложение. Должен быть лучший способ сделать это.

Все, что я действительно хочу сделать, это иметь точный, автоматически обновляемый, доступный код доступный номер версии.

Вот код, который я использую для доступа к номеру версии сборки:

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

Альтернативой может быть поиск кода, который обращается к версии публикации.

4b9b3361

Ответ 1

sylvanaar последняя строка выглядит как способ, по моему опыту; но с оговоркой, что он доступен только для развертываемых версий приложения. Для целей отладки вам может понадобиться что-то вроде:

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

        return "Debug";
    }

Ответ 2

Я изменил файл .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>

Опубликованная версия может быть:

ApplicationDeployment.CurrentDeployment.CurrentVersion

Ответ 3

Я модифицировал решение 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 соответственно и создал авторское право на основе текущей даты:

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

В итоге я добавил это в свой файл vbproj. Для этого сначала необходимо установить пакет NuGet MSBuildTasks:

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

Ответ 4

Я сделал это наоборот, использовал подстановочный шаблон для моей версии сборки - 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>

Ответ 5

Я хотел бы подробнее остановиться на ответе Сильванаара, поскольку некоторые детали реализации не были для меня очевидны. Так:

  1. Вручную установите задачи по созданию сообщества, которые можно найти по адресу: https://github.com/loresoft/msbuildtasks/releases. Примечание. Не выполняйте установку с помощью 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();
}