Как синхронизировать версию публикации с версией сборки в приложении .NET ClickOnce?
В моем приложении С# ClickOnce на вкладке "Проект → Свойства → Опубликовать" есть версия с автоматическим добавлением публикации. Я хотел бы отобразить эту версию в своем меню "Справка → О программе", но код, который я использую, по-видимому, обращается к версии сборки, которая отличается.
Версия сборки может быть изменена вручную в диалоговом окне Project → Properties → Application → Assembly Information. Так что пока, каждый раз перед публикацией я копировал версию публикации в версию сборки, поэтому в моем диалоговом окне отображается текущая версия
приложение. Должен быть лучший способ сделать это.
Все, что я действительно хочу сделать, это иметь точный, автоматически обновляемый, доступный код доступный номер версии.
Вот код, который я использую для доступа к номеру версии сборки:
public string AssemblyVersion
{
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
Альтернативой может быть поиск кода, который обращается к версии публикации.
Ответы
Ответ 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
Я хотел бы подробнее остановиться на ответе Сильванаара, поскольку некоторые детали реализации не были для меня очевидны. Так:
-
Вручную установите задачи по созданию сообщества, которые можно найти по адресу: https://github.com/loresoft/msbuildtasks/releases. Примечание. Не выполняйте установку с помощью 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>
5 Используйте метод, подобный следующему, чтобы получить доступ к тексту версии:
public string Version()
{
Version version = null;
if (ApplicationDeployment.IsNetworkDeployed)
{
version = ApplicationDeployment.CurrentDeployment.CurrentVersion;
}
else
{
version = typeof(ThisAddIn).Assembly.GetName().Version;
}
return version.ToString();
}