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

Как отобразить номер версии ClickOnce в Windows Forms

У меня есть приложение для форм Windows, которое развертывается в двух разных местах.

  • Интранет - ClickOnce
  • Интернет - установлен на ферме citrix через установщик Windows

Я показываю номер версии ClickOnce для развернутой версии ApplicationDeployment.IsNetworkDeployed для разблокировки по-разному.

if (ApplicationDeployment.IsNetworkDeployed)
        return ApplicationDeployment.CurrentDeployment.CurrentVersion;

Но для приложения без клика я не уверен, как получить версию clickonce, если я не закодировал номер версии в сборке.

Есть ли автоматический способ получить номер версии ClickOnce для развернутой версии без клика?

4b9b3361

Ответ 1

Нет, я не верю, что есть способ. Я считаю, что информация ClickOnce поступает из манифеста, который будет доступен только при развертывании ClickOnce. Я думаю, что жесткая кодировка номера версии - ваш лучший вариант.

Ответ 2

  • Добавьте ссылку на сборку 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).)

Ответ 3

Я бы просто сделал сборку версии основной сборки такой же, как версия CLickOnce, каждый раз, когда вы выпускаете новую версию. Затем, когда он запускается как приложение без клика, просто используйте Reflection, чтобы выбрать версию сборки.

Ответ 4

Попробуйте проверить поток:

if (ApplicationDeployment.IsNetworkDeployed)
        {
            if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
            {
                Application.ExitThread();
                Application.Restart();
            }
        }

Ответ 5

Жесткий код или... Следите за версиями (File, Assembly, Deploy) в базе данных. Сделайте вызов в базу данных с вашей сборкой и получите версию Deploy.

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

Ответ 6

не то, что это имеет значение три года спустя, но в итоге я просто разбирал файл манифеста с помощью xml-ридера.

Ответ 7

Чтобы расширить решение 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 был скомпилирован в программу. Этот файл может начинаться пустым, и вы должны игнорировать его в своей системе управления версиями, потому что он автоматически изменяется, а информация для его создания уже хранится в другом месте.

Ответ 8

Используя компонент сборки, вы можете прочитать однократную версию файла проекта и записать ее автоматически в сборку, чтобы обе они были синхронизированы.

Ответ 9

Проделайте проверку потока, вставьте защищенный код...