visual-studio - instalar - visual studio code español
Cómo incluir el número de versión en el archivo de salida del proyecto de instalación de VS (6)
El mismo concepto que la respuesta de Jim Grimmett, pero con menos dependencias:
FOR /F "tokens=2 delims== " %%V IN (''FINDSTR /B /R /C:" */"ProductVersion/"" "$(ProjectDir)MySetupProjectName.vdproj"'') DO FOR %%I IN ("$(BuiltOuputPath)") DO REN "$(BuiltOuputPath)" "%%~nI-%%~nxV%%~xI"
Algunos puntos a tener en cuenta:
MySetupProjectName.vdproj
debe cambiarse al nombre de su archivo de proyecto. Olvidarse de cambiar esto da como resultado un error de compilación: ''PostBuildEvent'' failed with error code ''1''
y la ventana de Output
muestra qué archivo FINDSTR
no pudo abrir.
Descripción paso a paso:
FINDSTR /B /R /C:" */"ProductVersion/"" $(ProjectDir)MySetupProjectName.vdproj
- Esto encuentra la línea
"ProductVersion" = "8:xyzetc"
del archivo de proyecto.
FOR /F "tokens=2 delims== " %%V IN (...) DO ... %%~nxV ...
- Esto se utiliza para analizar la parte
xyzetc
del resultado anterior.
$(BuiltOuputPath)
- Esta es la ruta de salida original, según lo que se dice en "Macros" de la línea de comandos de eventos posteriores a la compilación.
FOR %%I IN (...) DO ... %%~nI-%%~nxV%%~xI
- Esto se utiliza para convertir la cadena
foo.msi
afoo-xyzetc.msi
.
REN "$(BuiltOuputPath)" ...
- Esto simplemente cambia el nombre de la ruta de salida al nuevo nombre.
FOR ... DO FOR .. DO REN ...
- Está escrito en una línea como esta para que un error a lo largo de forma limpia rompa la construcción.
¿Hay alguna manera de incluir el número de versión como parte del nombre de archivo de output.msi en un Proyecto de configuración VS2008?
Me gustaría, por ejemplo, un archivo de salida llamado "myinstaller-1.0.13.msi" donde la parte de la versión se establece automáticamente en función del número de versión que he puesto en las propiedades del proyecto de implementación.
Lo hice con 2 líneas en powershell.
$versionText=(Get-Item MyProgram.exe).VersionInfo.FileVersion (Get-Content MySetup.vdproj.template).replace(''${VERSION}'', $($versionText)) | Set-Content MySetup.vdproj
Cambie el nombre de su .vdproj existente para que sea MySetup.vdproj.template e inserte "$ {VERSION}" donde desee insertar la versión de su archivo exe principal.
VS detectará el cambio en el archivo vdproj y le preguntará si desea volver a cargarlo.
No estoy seguro de si todavía necesita esto o no, pero quería contestar esto, ya que hicimos una operación similar en el evento postbuild. En cuanto a la investigación que hice, no es posible establecer el nombre de archivo como desee internamente a través del proceso de configuración.
Puede hacer esto de otra manera nombrando el archivo de salida a través de una aplicación externa en el evento posterior a la compilación.
Esto es lo que puedes hacer:
En el evento posterior a la construcción ->
[MsiRenamerAppPath] / MsiRenamer.exe "$ (BuildOutputPath)"
Cree una aplicación que cambie el nombre del archivo msi con el número de versión del proyecto de implementación. A continuación se muestra el código utilizado para la aplicación. Esto debería cumplir su requisito, supongo.
Obtener el código de propiedades msi se usa desde el artículo alteridem
class MsiRenamer
{
static void Main(string[] args)
{
string inputFile;
string productName = "[ProductName]";
if (args.Length == 0)
{
Console.WriteLine("Enter MSI file:");
inputFile = Console.ReadLine();
}
else
{
inputFile = args[0];
}
try
{
string version;
if (inputFile.EndsWith(".msi", StringComparison.OrdinalIgnoreCase))
{
// Read the MSI property
version = GetMsiProperty(inputFile, "ProductVersion");
productName = GetMsiProperty(inputFile, "ProductName");
}
else
{
return;
}
// Edit: MarkLakata: .msi extension is added back to filename
File.Copy(inputFile, string.Format("{0} {1}.msi", productName, version));
File.Delete(inputFile);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static string GetMsiProperty(string msiFile, string property)
{
string retVal = string.Empty;
// Create an Installer instance
Type classType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Object installerObj = Activator.CreateInstance(classType);
Installer installer = installerObj as Installer;
// Open the msi file for reading
// 0 - Read, 1 - Read/Write
Database database = installer.OpenDatabase(msiFile, 0);
// Fetch the requested property
string sql = String.Format(
"SELECT Value FROM Property WHERE Property=''{0}''", property);
View view = database.OpenView(sql);
view.Execute(null);
// Read in the fetched record
Record record = view.Fetch();
if (record != null)
{
retVal = record.get_StringData(1);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(record);
}
view.Close();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(view);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(database);
return retVal;
}
}
No quería usar el método .exe de arriba y tenía un poco de tiempo libre, así que empecé a investigar. Estoy usando VS 2008 en Windows 7 64 bit. Cuando tengo un proyecto de instalación, llamémoslo MySetup, todos los detalles del proyecto se pueden encontrar en el archivo $ (ProjectDir) MySetup.vdproj.
La versión del producto se encontrará en una sola línea en ese archivo en el formulario
ProductVersion="8:1.0.0"
Ahora, hay un evento posterior a la construcción en un proyecto de configuración. Si seleccionas un proyecto de configuración y presionas F4, obtienes un conjunto de propiedades completamente diferente al hacer clic derecho y seleccionar propiedades. Después de presionar F4 verás que uno de ellos es PostBuildEvent. Una vez más, asumiendo que el proyecto de configuración se llama MySetup, lo siguiente establecerá el nombre de .msi para incluir la fecha y la versión
set datevar=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%
findstr /v PostBuildEvent $(ProjectDir)MySetup.vdproj | findstr ProductVersion >$(ProjectDir)version.txt
set /p var=<$(ProjectDir)version.txt
set var=%var:"=%
set var=%var: =%
set var=%var:.=_%
for /f "tokens=1,2 delims=:" %%i in ("%var%") do @echo %%j >$(ProjectDir)version.txt
set /p realvar=<$(ProjectDir)version.txt
rename "$(ProjectDir)$(Configuration)/MySetup.msi" "MySetup-%datevar%-%realvar%.msi"
Te llevaré a través de lo anterior.
datevar es la fecha actual en el formato AAAAMMDD.
La línea findstr pasa por MySetup.vdproj, elimina cualquier línea con PostBuildEvent, luego devuelve la única línea que queda con productVersion y la envía a un archivo. Luego eliminamos las comillas, los espacios, y convertimos los puntos en guiones bajos.
La línea for divide la cadena restante en dos puntos, toma la segunda parte y la envía a un archivo nuevamente.
Luego establecemos realvar al valor que queda en el archivo, y cambiamos el nombre de MySetup.msi para incluir la fecha y la versión.
Por lo tanto, dada la ProductVersion anterior, si fuera el 27 de marzo de 2012, el archivo pasará a llamarse
MySetup-20120327-1_0_0.msi
Claramente, al usar este método, puedes tomar CUALQUIERA de las variables en el archivo vdproj e incluirlas en tu nombre de archivo de salida y no tenemos que compilar ningún programa .exe adicional para hacerlo.
HTH
Si usa un proyecto WIX (a diferencia de un proyecto de configuración e implementación de VS), este artículo explica exactamente cómo lograr lo que está buscando.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using WindowsInstaller;
// cscript //nologo "$(ProjectDir)WiRunSql.vbs" "$(BuiltOuputPath)" "UPDATE `Property` SET `Property`.`Value`=''4.0.0.1'' WHERE `Property`=''ProductVersion''"
// "SELECT `Property`.`ProductVersion` FROM `Property` WHERE `Property`.`Property` = ''ProductVersion''"
/*
* That''s a .NET wrapper generated by tlbimp.exe, wrapping the ActiveX component c:/windows/system32/msi.dll.
* You can let the IDE make one for you with Project + Add Reference, COM tab,
* select "Microsoft Windows Installer Object Library".
*/
namespace PostBuildEventModifyMSI
{
/* Post build event fro Rename MSI file.
* $(SolutionDir)PostBuildEventModifyMSI/bin/Debug/PostBuildEventModifyMSI.exe "$(SolutionDir)TestWebApplicationSetup/Debug/TestWebApplicationSetup.msi"
*/
[System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid("000C1090-0000-0000-C000-000000000046")]
class Installer { }
class Program
{
static void Main(string[] args)
{
#region New code.
string msiFilePath = string.Empty;
if (args.Length == 0)
{
Console.WriteLine("Enter MSI file complete path:");
msiFilePath = Console.ReadLine();
}
else
{
Console.WriteLine("Argument Received args[0]: " + args[0]);
msiFilePath = args[0];
}
StringBuilder sb = new StringBuilder();
string[] words = msiFilePath.Split(''//');
foreach (string word in words)
{
sb.Append(word + ''//');
if (word.Contains("Debug"))
{
break;
}
else
{
}
}
// Open a view on the Property table for the Label property
//UPDATE Property set Value = ''2.06.36'' where Property = ''ProductVersion''
Program p = new Program();
string version = p.GetMsiVersionProperty(msiFilePath, "ProductVersion");
string productName = p.GetMsiVersionProperty(msiFilePath, "ProductName");
string newMSIpath = sb.ToString() + string.Format("{0}_{1}.msi", productName, version);
Console.WriteLine("Original MSI File Path: " + msiFilePath);
Console.WriteLine("New MSI File Path: " + newMSIpath);
System.IO.File.Move(msiFilePath, newMSIpath);
#endregion
//Console.Read();
}
private string GetMsiVersionProperty(string msiFilePath, string property)
{
string retVal = string.Empty;
// Create an Installer instance
WindowsInstaller.Installer installer = (WindowsInstaller.Installer) new Installer();
// Open the msi file for reading
// 0 - Read, 1 - Read/Write
Database db = installer.OpenDatabase(msiFilePath, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly); //// Open the MSI database in the input file
// Fetch the requested property
string sql = String.Format(
"SELECT Value FROM Property WHERE Property=''{0}''", property);
View view = db.OpenView(sql);
//View vw = db.OpenView(@"SELECT `Value` FROM `Property` WHERE `Property` = ''ProductVersion''");
view.Execute(null);
// Read in the fetched record
Record record = view.Fetch();
if (record != null)
{
retVal = record.get_StringData(1);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(record);
}
view.Close();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(view);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
return retVal;
}
}
}