Как программно изменить версию продукта проекта?

У меня есть несколько проектов по развертыванию. Чтобы развернуть приложение, мне нужно выполнить несколько задач, одна из которых - изменить версию продукта и код продукта для каждого проекта развертывания.

Я не могу найти способ изменить их программно.

Поскольку это проект развертывания (который, наконец, создает исполняемый установщик), я не могу работать с MSBuild, вместо этого я использую Devenv из командной строки.


person El Padrino    schedule 20.11.2008    source источник
comment
что это за проект? c ++ или c # / vb?   -  person Aaron Fischer    schedule 20.11.2008
comment
Проект представляет собой проект развертывания C #, я использую .Net 2.0.   -  person El Padrino    schedule 20.11.2008
comment
какое-нибудь окончательное решение с полным исходным кодом? такие проекты вдпрой?   -  person Kiquenet    schedule 14.08.2012
comment
Это csproj. Нет окончательного рабочего решения.   -  person El Padrino    schedule 11.10.2012


Ответы (10)


Я искал сегодня то же самое. Я нашел это с помощью Google:

static void Main(string[] args) 
{
    string setupFileName = @"<Replace the path to vdproj file>"; 
    StreamReader reader = File.OpenText(setupFileName); 
    string file = string.Empty; 

    try 
    { 
        Regex expression = new Regex(@"(?:\""ProductCode\"" = 
        \""8.){([\d\w-]+)}"); 
        Regex expression1 = new Regex(@"(?:\""UpgradeCode\"" = 
        \""8.){([\d\w-]+)}"); 
        file = reader.ReadToEnd(); 

        file = expression.Replace(file, "\"ProductCode\" = \"8:{" + 
        Guid.NewGuid().ToString().ToUpper() + "}"); 
        file = expression1.Replace(file, "\"UpgradeCode\" = \"8:{" 
        + Guid.NewGuid().ToString().ToUpper() + "}"); 
    } 
    finally 
    { 
        // Close the file otherwise the compile may not work 
        reader.Close(); 
    } 

    TextWriter tw = new StreamWriter(setupFileName); 
    try 
    { 
        tw.Write(file); 
    } 
    finally 
    { 
        // close the stream 
        tw.Close(); 
    } 
 }
person TheCodeMonk    schedule 29.12.2008
comment
Я использовал этот подход, чтобы изменить код продукта на моем vsproj, чтобы при сборке и запуске моего msi он обновлялся красиво, не прося пользователя удалить предыдущую версию. Большое спасибо, я давно искал, как это сделать! - person Mike D; 11.09.2009
comment
+1 У меня такая же проблема, и кажется, что регулярное выражение может быть самым простым решением. - person Beta033; 16.03.2011

Я знаю, что исходный плакат ищет решение этой проблемы с помощью .NET 2.0. Однако, поскольку он не был помечен как .NET, я предлагаю свое решение проблемы на C ++. Это может быть применимо в мире .NET, но я оставлю это другим.

Это не только обновляет информацию о версии в окне «О программе» и файле журнала для моего приложения, но также и всю информацию о версии Windows, которая отображается в проводнике Windows.

ОБНОВЛЕНИЕ: добавлены некоторые изменения, которые я внес в процесс с момента моего первоначального ответа.

Во-первых, я переместил весь информационный блок версии из файла Project.rc в файл Project.rc2:

/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION FILE_VER
 PRODUCTVERSION PROD_VER
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
  FILEFLAGS 0x1L
#else
  FILEFLAGS 0x0L
#endif
  FILEOS 0x4L
  FILETYPE 0x1L
  FILESUBTYPE 0x0L
BEGIN
   BLOCK "StringFileInfo"
   BEGIN
       BLOCK "040904e4"
       BEGIN
           VALUE "CompanyName", "MyCompany"
           VALUE "FileDescription", "Software Description"
           VALUE "FileVersion", 1,0,0,1
           VALUE "InternalName", "FileName.exe"
           VALUE "LegalCopyright", "(c) 2008 My Company.  All rights reserved."
           VALUE "OriginalFilename", "FileName.exe"
           VALUE "ProductName", "Product Name"
           VALUE "ProductVersion", 1,0,0,1
       END
   END
   BLOCK "VarFileInfo"
   BEGIN
       VALUE "Translation", 0x409, 1252
   END
END

По сути, это переносит всю информацию о версии, которую вы бы редактировали из редактора ресурсов, в отдельный файл. Это позволяет избежать ошибок при редактировании файла ресурсов вне редактора. Обратной стороной является то, что вы больше не можете редактировать информацию о версии из редактора ресурсов. Но, поскольку мы хотим, чтобы этот материал обновлялся автоматически, это не имеет большого значения.

Затем я создал файл VersionInfo.h и добавил его в свой проект:

#pragma once

//major release version of the program, increment only when major changes are made
#define VER_MAJOR 2

//minor release version of the program, increment if any new features are added
#define VER_MINOR 0

//any bugfix updates, no new features
#define VER_REV 0

//if this is some special release (e.g. Alpha 1) put the special release string here
#define STR_SPECIAL_REL "Alpha 1"


#define FILE_VER VER_MAJOR,VER_MINOR,VER_REV
#define PROD_VER FILE_VER

//these are special macros that convert numerical version tokens into string tokens
//we can't use actual int and string types because they won't work in the RC files
#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)

#define STR_FILE_VER STRINGIZE(VER_MAJOR) "." STRINGIZE(VER_MINOR) "." STRINGIZE(VER_REV)
#define STR_PROD_VER STR_FILE_VER " " STR_SPECIAL_REL

#define STR_COPYRIGHT_INFO "©" BuildYear " Your Company. All rights reserved."

Затем я включил VersionInfo.h в файл rc2 и внес следующие изменения:

#include "VersionInfo.h"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//

<no changes>
           VALUE "FileVersion", STR_FILE_VER
           <no changes>
           VALUE "LegalCopyright", STR_COPYRIGHT_INFO
           <no changes>
           VALUE "ProductVersion", STR_PROD_VER
<no changes>

С помощью этой настройки я мог отредактировать свой сценарий сборки (который использует Perl), чтобы изменить информацию о версии в файле VersionInfo.h перед пересборкой всего проекта с использованием командной строки devenv.

Еще один дополнительный шаг, который я добавил, который также может представлять интерес (хотя он еще не доведен до совершенства и может стать вопросом будущего здесь) - это создание уникального номера сборки каждый раз при сборке проекта. В текущем воплощении он всегда работает для полных перестроек, но только время от времени для инкрементных сборок. Я создал файл build_number.incl, содержащий следующее:

#define CurrentBuildNumber  "20081020P1525" 

По сути, это дата и время начала сборки. Я создал командный файл, который запускается как событие перед сборкой для проекта, который создает этот файл. Сценарий также определяет BuildYear, поэтому авторские права в файле VersionInfo.h всегда содержат год самой последней сборки. Пакетный сценарий выглядит следующим образом:

    echo Generating Build Number
    @For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do @(
    Set Month=%%A
    Set Day=%%B
    Set Year=%%C
    )

    @For /F "tokens=1,2,3 delims=/M: " %%A in ('Time /t') do @(
    Set Hour=%%A
    Set Minute=%%B
    Set AmPm=%%C
    )

    @echo #define CurrentBuildNumber  "%Year%%Month%%Day%%AmPm%%Hour%%Minute%" > "$(ProjectDir)\build_number.incl"
    @echo #define BuildYear "%Year%" >> "$(ProjectDir)\build_number.incl"
    echo ----------------------------------------------------------------------

Затем этот файл включается в любой файл проекта, который должен использовать номер сборки (то есть поле about).

Некоторые из них были почерпнуты из этого сообщения CodeProject.

Надеюсь, эта информация окажется полезной.

person bsruth    schedule 29.12.2008

У меня была та же проблема, и я обнаружил, что изменение файла .vdproj в prebuildevent не совсем то, что мне нравится.

Я использовал другой код для изменения файла msi после создания проекта установки, поэтому я использую postbuildevent.

См. Мое сообщение в блоге здесь.

person Community    schedule 10.03.2009
comment
столкнулся с той же проблемой. VS не перезагружает vdproj после выполнения этапа предварительной сборки, поэтому необходимо либо выполнить сборку дважды, либо использовать подход после сборки. - person OSH; 23.08.2014

Мы используем программу, которая обновляет каждый AssemblyInfo.cs или AssemblyInfo.vb на основе значения файла конфигурации. мы запускаем этот исполняемый файл перед каждой сборкой. Это было лучшее, что мы могли сделать для автоматизации этого процесса. Вы можете добавить вызов этого пакетного процесса в конфигурацию вашего проекта в качестве шага перед сборкой.

person Aaron Fischer    schedule 20.11.2008
comment
Это может быть включено в процесс сборки с использованием предварительного условия. - person Joshua Lowry; 05.08.2011

Вы можете использовать задачу msbuild, чтобы обновить версию продукта. Ознакомьтесь с этот пост команды MSBuild по этой теме.

person Bruno Shine    schedule 20.11.2008
comment
где сейчас (2012) AssemblyInfoTask? - person Kiquenet; 17.08.2012

Встраивание номера версии SVN во время компиляции в приложение для Windows

В своем ответе на этот вопрос я описываю, как я решаю эту задачу с помощью SVN.

person antik    schedule 20.11.2008

Возможно, это не совсем то, что вам нужно, но еще в глубине веков я написал что-то под названием stampver, который может автоматически увеличивать номер сборки непосредственно в EXE-файле на этапе после сборки.

person Paul Dixon    schedule 20.11.2008

Консоль настройки ресурсов

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

См. Более подробную информацию на странице пакетной обработки информации о версии файла:

person Wylder    schedule 28.01.2009

Я знаю, что это очень старый поток, но вот решение vbs для достижения той же цели. Просто поместите его в папку развертывания рядом с файлом .vdproj.

Function CreateGuid()
    CreateGuid = Left(CreateObject("Scriptlet.TypeLib").Guid,38)
End Function

Const ForReading = 1, ForWriting = 2, ForAppending = 8

Set fso = CreateObject("Scripting.FileSystemObject")
Set RegEx = CreateObject("VBScript.RegExp")

For Each file in fso.GetFolder(".").Files
    if (fso.GetExtensionName(file.Name) = "vdproj") then
        WScript.Echo "Updating: " + file.Name
        Set oFile = fso.OpenTextFile(file.Name, ForReading, True)
        fileContents = oFile.ReadAll
        oFile.Close
        RegEx.Pattern = """ProductCode"" = ""8:{.*-.*-.*-.*-.*}"
        fileContents=Regex.Replace(fileContents, """ProductCode"" = ""8:" & CreateGuid)
        Set oFile = fso.OpenTextFile(file.Name, ForWriting, True)
        oFile.Write fileContents
        oFile.Close
    end if
Next

Затем в вашем реальном проекте сделайте событие пост-сборки, подобное следующему:

cd $(SolutionDir)\CustomWebSetup
cscript -nologo UpdateProductCode.vbs

Это обновит vdproj с новым ProductCode в рамках подготовки к следующей сборке. После завершения сборки VS предложит перезагрузить проект развертывания.

person Scott C    schedule 12.08.2015

Посмотрите на использование RCS, CVS и / или Subversion. Я знаком только с RCS; Насколько я понимаю, CVS основана на RCS, но более комплексна. Я читал на разных досках, что подрывная деятельность лучше, но никогда не использовал ее. RCS подходит для отслеживания изменений и версий всех моих документов и программных проектов.

RCS находится здесь: http://www.cs.purdue.edu/homes/trinkle/RCS/

CVS находится здесь: http://www.nongnu.org/cvs/

Subversion находится здесь: http://subversion.tigris.org/

person Chris Duncombe Rae    schedule 29.12.2008
comment
Я обновляю информацию о версии в исходном коде с помощью обработчиков git post-commit. - person ashwoods; 22.05.2011