2008-11-20 24 views
10

Aquí está mi problema:¿Cómo cambiar programáticamente la versión del producto de un proyecto?

Tengo varios proyectos de implementación. Para implementar una aplicación, debo hacer varias tareas, una de ellas es cambiar la versión del producto y el código de producto de cada proyecto de implementación.

No encuentro una forma de cambiarlos programáticamente.

¿Alguien me puede ayudar?

Gracias de antemano.

ACTUALIZACIÓN: Dado que es un proyecto de Implementación (que finalmente produce un instalador ejecutable), no puedo trabajar con MSBuild, en su lugar estoy usando Devenv desde el símbolo del sistema. (Bruno, gracias por su rápida respuesta).

+0

¿qué tipo de proyecto es este? C++ o C#/vb? –

+0

El proyecto es un proyecto de implementación C#, estoy usando .Net 2.0. –

+0

¿alguna solución final con código fuente completo? son proyectos vdproj? – Kiquenet

Respuesta

10

Estaba buscando exactamente lo mismo hoy. Encontré esto usando 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(); 
    } 
} 
+0

He utilizado este enfoque para cambiar el código de producto en mi vsproj, de modo que cuando mi msi se compile y ejecute, se actualice bien, sin pedirle al usuario que elimine la versión anterior. Muchas gracias, ¡he estado buscando cómo hacer esto por un tiempo ahora! –

+0

+1 Tengo el mismo problema y parece que la expresión regular puede ser la solución más simple. – Beta033

0

Puede usar la tarea msbuild para actualizar su versión del producto. Consulte this post del equipo de MSBuild sobre este tema.

+0

¿dónde está ahora (2012) AssemblyInfoTask? – Kiquenet

1

Usamos un programa que actualiza cada AssemblyInfo.cs o AssemblyInfo.vb en función de un valor de archivo de configuración. ejecutamos este ejecutable antes de cada compilación. Eso fue lo mejor que pudimos hacer para automatizar este proceso. Puede agregar una llamada a este proceso por lotes en la configuración de sus proyectos como un paso previo a la compilación.

+0

Esto podría incluirse en el proceso de compilación utilizando una condición previa. –

0

Esto puede no ser lo que buscas, pero hace mucho tiempo escribí algo llamado stampver, que puede autoincrementar un número de compilación directamente en el archivo .exe como un paso posterior a la compilación.

5

Sé que el cartel original está buscando una solución .NET 2.0 a este problema. Sin embargo, como esto no fue etiquetado como .NET, ofreceré mi solución de C++ al problema. Esto puede ser aplicable en .NET land, pero se lo dejo a otros.

Esto no solo actualiza la información de la versión en el cuadro de información y el archivo de registro para mi aplicación, sino también toda la información de la versión de Windows que se ve en el Explorador de Windows.

ACTUALIZACIÓN: Agregué algunos cambios que he hecho en el proceso desde mi respuesta original.

Para empezar, que se trasladó todo el bloque de información de la versión de mi archivo Project.rc a mi archivo 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 

Esta transporta esencialmente toda la información de la versión materia que debe editar a partir del recurso editor en un archivo separado. Esto lo hace para que no tenga errores al editar el archivo de recursos desde fuera del editor. La desventaja es que ya no puede editar la información de la versión desde el editor de recursos. Pero, como queremos que esto se actualice automáticamente, no es gran cosa.

A continuación, creé un VersionInfo.h archivo y lo añadió a mi proyecto:

#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." 

continuación he incluido VersionInfo.h en el archivo rc2 y realizado los siguientes cambios:

#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> 

Con esta configuración, pude editar mi script de construcción (que usa Perl) para modificar la información de versión en el archivo VersionInfo.h antes de reconstruir todo el proyecto utilizando la línea de comandos devenv.

Un paso adicional que agregué que también podría ser de interés (aunque todavía no está completamente perfeccionado, y puede ser una pregunta futura) es generar un número de compilación único cada vez que se construye el proyecto. En la versión actual, siempre funciona para reconstrucciones completas, pero solo esporádicamente en compilaciones incrementales. Lo que hice fue crear un archivo llamado build_number.incl que contiene lo siguiente:

#define CurrentBuildNumber "20081020P1525" 

que es esencialmente la fecha y hora en que se inició la construcción. Creé un archivo por lotes que se ejecuta como un evento de precompilación para el proyecto que genera este archivo. La secuencia de comandos también define BuildYear para que los derechos de autor en el archivo VersionInfo.h siempre contengan el año de la compilación más reciente. La secuencia de comandos por lotes es la siguiente:

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 ---------------------------------------------------------------------- 

Este archivo se incluye entonces en cualquier archivo en el proyecto que necesita usar el número de compilación (es decir, el cuadro Acerca de).

Algo de esto fue obtenida de this CodeProject post.

Esperamos que esta información sea de utilidad.

-3

Observe el uso de RCS, CVS y/o subversión. Solo estoy familiarizado con RCS; Tengo entendido que CVS se basa en RCS pero es más completo. He leído en varios foros que la subversión es mejor, pero nunca la he usado. RCS ha sido adecuado para realizar un seguimiento de los cambios y versiones en todos mis documentos y proyectos de software.

RCS está aquí: http://www.cs.purdue.edu/homes/trinkle/RCS/

CVS está aquí: http://www.nongnu.org/cvs/

Subversion está aquí: editor de recursos http://subversion.tigris.org/

+0

La pregunta (IMO) no tiene nada que ver con el control de versión ... –

+0

Actualizo la información de la versión del código fuente usando git post-commit hooks. – ashwoods

0

Resource Tuner Console

Esta consola permite la creación de un sistema fiable y repetible proces s para actualizar los recursos de Información de versión del producto durante la etapa final del proceso de compilación desde el símbolo del sistema.

Ver específicamente la manipulación lote de información de versión de archivo página para mayores detalles:

2

que tenían el mismo problema, y ​​me di cuenta que la modificación de la .vdproj archivo en un prebuildevent no hace exactamente qué Me gusta.

que usa algún otro código para modificar el archivo archivo msi después de que el proyecto de instalación ha sido construida, por lo que utilizan el postbuildevent.

Ver mi publicación de blog here.

+1

se encontró con el mismo problema. VS no vuelve a cargar el vdproj después de ejecutar el paso de preconstrucción, por lo que es necesario construirlo dos veces o usar el enfoque de postconstrucción. – OSH

0

Sé que esto un hilo muy antiguo, pero aquí es una solución VBS para lograr el mismo fin. Simplemente coloque esto en su carpeta de despliegue junto al archivo .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 

Luego, en su proyecto de verdad, tienen un evento posterior construcción similar a:

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

Esto actualizará el vdproj con un nuevo CódigoProducto en preparación para la próxima acumulación. Una vez completada la compilación, VS solicitará una recarga del proyecto de implementación.

Cuestiones relacionadas