Ответ 1
Нет, я не верю, что есть способ. Я считаю, что информация ClickOnce поступает из манифеста, который будет доступен только при развертывании ClickOnce. Я думаю, что жесткая кодировка номера версии - ваш лучший вариант.
У меня есть приложение для форм Windows, которое развертывается в двух разных местах.
Я показываю номер версии ClickOnce для развернутой версии ApplicationDeployment.IsNetworkDeployed
для разблокировки по-разному.
if (ApplicationDeployment.IsNetworkDeployed)
return ApplicationDeployment.CurrentDeployment.CurrentVersion;
Но для приложения без клика я не уверен, как получить версию clickonce, если я не закодировал номер версии в сборке.
Есть ли автоматический способ получить номер версии ClickOnce для развернутой версии без клика?
Нет, я не верю, что есть способ. Я считаю, что информация ClickOnce поступает из манифеста, который будет доступен только при развертывании ClickOnce. Я думаю, что жесткая кодировка номера версии - ваш лучший вариант.
Добавьте ссылку на сборку System.Deployment
в ваш проект.
Импортировать пространство имен в файл класса:
VB.NET:
Imports System.Deployment
С#:
using System.Deployment;
Получить версию ClickOnce из свойства CurrentVersion
.
Вы можете получить текущую версию из свойства ApplicationDeployment.CurrentDeployment.CurrentVersion
. Это возвращает объект System.Version
.
Примечание (из MSDN):
CurrentVersion
будет отличаться отUpdatedVersion
, если новое обновление имеет был установлен, но вы еще не вызвалиRestart
. Если развертывание манифест настроен для выполнения автоматических обновлений, вы можете сравнить эти два значения, чтобы определить, следует ли перезапустить приложение.
ПРИМЕЧАНИЕ. Статическое свойство CurrentDeployment
действует только тогда, когда приложение было развернуто с помощью ClickOnce. Поэтому перед доступом к этому свойству сначала необходимо проверить свойство ApplicationDeployment.IsNetworkDeployed
. Он всегда возвращает false в среде отладки.
VB.NET:
Dim myVersion as Version
If ApplicationDeployment.IsNetworkDeployed Then
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion
End If
С#:
Version myVersion;
if (ApplicationDeployment.IsNetworkDeployed)
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
Используйте объект Version
:
Здесь вы можете использовать информацию о версии на этикетке, например, в форме "О себе":
VB.NET:
versionLabel.Text = String.Concat("ClickOnce published Version: v", myVersion)
С#:
versionLabel.Text = string.Concat("ClickOnce published Version: v", myVersion);
(Version
объекты отформатированы как четырехчастное число (major.minor.build.revision).)
Я бы просто сделал сборку версии основной сборки такой же, как версия CLickOnce, каждый раз, когда вы выпускаете новую версию. Затем, когда он запускается как приложение без клика, просто используйте Reflection, чтобы выбрать версию сборки.
Попробуйте проверить поток:
if (ApplicationDeployment.IsNetworkDeployed)
{
if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
{
Application.ExitThread();
Application.Restart();
}
}
Жесткий код или... Следите за версиями (File, Assembly, Deploy) в базе данных. Сделайте вызов в базу данных с вашей сборкой и получите версию Deploy.
Это предполагает, что вы увеличиваете свои версии логически, так что каждый тип версии имеет отношения. Это большая работа для такой незначительной проблемы. Я бы лично пошел с решением Джареда; хотя я ненавижу жесткое кодирование.
не то, что это имеет значение три года спустя, но в итоге я просто разбирал файл манифеста с помощью xml-ридера.
Чтобы расширить решение RobinDotNet:
Protip: вы можете автоматически запускать программу или script, чтобы сделать это для вас изнутри .csproj файла MSBuild конфигурации каждый раз, когда вы строите. Я сделал это для одного веб-приложения, которое в настоящее время поддерживаю, выполняя оболочку Cygwin bash script, чтобы сделать некоторый контроль версии h4x, чтобы вычислить номер версии из истории Git, а затем предварительно обработать собранный файл исходной информации сборки в выводе сборки.
Аналогичная вещь может быть выполнена для анализа номера версии ClickOnce из файла проекта, т.е. Project.PropertyGroup.ApplicationRevision
и Project.PropertyGroup.ApplicationVersion
(хотя я не знаю, что означает строка версии, но вы можете просто догадаться, пока она не сломается и исправить его) и вставить эту информацию о версии в информацию о сборке.
Я не знаю, когда нажимается версия ClickOnce, но, вероятно, после процесса сборки, поэтому вам может понадобиться возиться с этим решением, чтобы скомпилировать новый номер. Я предполагаю, что всегда есть /*h4x*/ +1
.
Я использовал Cygwin, потому что * nix scripting намного лучше, чем Windows, и интерпретируемый код избавляет вас от необходимости создавать вашу предварительную сборку перед созданием, но вы могли бы написать программу, используя любую технику, которую вы хотели (в том числе С#/.NET). Командная строка для предварительного процессора находится внутри PreBuildEvent
:
<PropertyGroup>
<PreBuildEvent>
$(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version
</PreBuildEvent>
</PropertyGroup>
Как вы думаете, это происходит до этапа сборки, поэтому вы можете эффективно предварительно обработать исходный код перед его компиляцией. Я не хотел автоматически редактировать файл Properties\AssemblyInfo.cs
, поэтому для его безопасного использования я создал файл Properties\VersionInfo.base.cs
, который содержал текстовый шаблон класса с информацией о версии и был помечен как BuildAction=None
в проекте чтобы он не был скомпилирован с проектом:
using System.Reflection;
using EngiCan.Common.Properties;
[assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")]
[assembly: AssemblyRevisionIdentifier("$REVID$")]
(Очень простой и грязный синтаксис заполнителя, похожий на переменные среды Windows, с добавленным дополнительным h4x был использован для простоты/сложности)
AssemblyRevisionIdentifierAttribute
был настраиваемым атрибутом, который я создал для хранения Git SHA1, поскольку он гораздо более значим для разработчиков, чем a.b.c.d.
Моя программа refresh-version
затем скопирует этот файл в Properties\VersionInfo.cs
, а затем выполнит замену информации о версии, которую он уже вычислил/проанализировал (я использовал sed(1)
для подстановки, что было еще одним преимуществом использования Cygwin). Properties\VersionInfo.cs
был скомпилирован в программу. Этот файл может начинаться пустым, и вы должны игнорировать его в своей системе управления версиями, потому что он автоматически изменяется, а информация для его создания уже хранится в другом месте.
Используя компонент сборки, вы можете прочитать однократную версию файла проекта и записать ее автоматически в сборку, чтобы обе они были синхронизированы.
Проделайте проверку потока, вставьте защищенный код...