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

Вот моя проблема:

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

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

Кто-нибудь может мне помочь?

Спасибо заранее.

ОБНОВЛЕНИЕ: поскольку это проект развертывания (который, наконец, создает исполняемый установщик), я не могу работать с MSBuild, вместо этого я использую Devenv из командной строки. (Бруно, спасибо за ваш быстрый ответ).

Ответ 1

Я искал то же самое сегодня. Я нашел это с помощью 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(); 
    } 
 }

Ответ 2

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

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

UPDATE: Добавлены некоторые изменения, которые я внес в этот процесс с момента моего первоначального ответа.

Во-первых, я переместил весь блок информации о версии из моего файла 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>

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

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

#define CurrentBuildNumber  "20081020P1525" 

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

    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.

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

Ответ 3

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

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

Смотрите мой блог-пост здесь.

Ответ 4

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

Ответ 5

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

Ответ 7

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

Ответ 8

Консоль Resource Tuner

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

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

Ответ 10

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

Затем в вашем реальном проекте создайте событие post build, похожее на:

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

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

Ответ 11

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

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

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

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