visual-studio - tutorial - visual studio code español
Ejecutar exe después de la instalación de msi? (6)
¡¡¡DE ACUERDO!!! Aquí está el código (sin las 2 funciones auxiliares ''FindFileIdentifier'' y ''StringEndsWith'' al final - use las originales en su lugar) que nos da la capacidad de cambiar los Ys y Alturas de los controles, junto con agregar las Condiciones de Visibilidad del Control de Casilla de Verificación (Consulte los 2 comentarios que están marcados entre ''NUEVO - INICIAR'' y ''NUEVO - FIN''):
// EnableLaunchApplication.js
// Performs a post-build fixup of an msi to launch a specific file when the install has completed
// Configurable values
var checkboxChecked = true; // Is the checkbox on the finished dialog checked by default?
var checkboxText = "Launch [ProductName]?"; // Text for the checkbox on the finished dialog
var filename = "*.exe"; // The name of the executable to launch - change * to match the file name you want to launch at the end of your setup
// Constant values from Windows Installer
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyInsert = 1
var msiViewModifyUpdate = 2
var msiViewModifyAssign = 3
var msiViewModifyReplace = 4
var msiViewModifyDelete = 6
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
var record
try
{
var fileId = FindFileIdentifier(database, filename);
if (!fileId)
throw "Unable to find ''" + filename + "'' in File table";
WScript.Echo("Updating the Control table...");
// Modify the Control_Next of BannerBmp control to point to the new CheckBox
sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`=''FinishedForm'' AND `Control`=''BannerBmp''";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.StringData(11) = "CheckboxLaunch";
view.Modify(msiViewModifyReplace, record);
view.Close();
// NEW - START
// Insert the new CheckBox control
// I changed the value for Y below from 201 to 191 in order to make the checkbox more obvious to the user''s eye. In order to do so, and avoid the controls ''BodyText'' & ''BodyTextRemove'' in the same form to
// overlap the checkbox, I added yet 2 more sql statements that change the values of the heights for the ''BodyText'' & ''BodyTextRemove'' from 138 to 128. This way I can play around with the values without using
// the Orca msi editor.
var CheckBoxY = 191; //This was initially set to 201
var NewHeight = 128; //This was initially set to 138
sql = "INSERT INTO `Control` (`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help`) VALUES (''FinishedForm'', ''CheckboxLaunch'', ''CheckBox'', ''9'', ''" + CheckBoxY + "'', ''343'', ''12'', ''3'', ''LAUNCHAPP'', ''{//VSI_MS_Sans_Serif13.0_0_0}" + checkboxText + "'', ''CloseButton'', ''|'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
sql = "Select `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_` = ''FinishedForm'' AND `Control` = ''BodyText''";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(7) = NewHeight;
view.Modify(msiViewModifyReplace, record);
view.Close();
sql = "Select `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_` = ''FinishedForm'' AND `Control` = ''BodyTextRemove''";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(7) = NewHeight;
view.Modify(msiViewModifyReplace, record);
view.Close();
// NEW - END
WScript.Echo("Updating the ControlEvent table...");
// Modify the Order of the EndDialog event of the FinishedForm to 1
sql = "SELECT `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering` FROM `ControlEvent` WHERE `Dialog_`=''FinishedForm'' AND `Event`=''EndDialog''";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(6) = 1;
view.Modify(msiViewModifyReplace, record);
view.Close();
// Insert the Event to launch the application
sql = "INSERT INTO `ControlEvent` (`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES (''FinishedForm'', ''CloseButton'', ''DoAction'', ''VSDCA_Launch'', ''LAUNCHAPP=1'', ''0'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
WScript.Echo("Updating the CustomAction table...");
// Insert the custom action to launch the application when finished
sql = "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES (''VSDCA_Launch'', ''210'', ''" + fileId + "'', '''')";
view = database.OpenView(sql);
view.Execute();
view.Close();
if (checkboxChecked)
{
WScript.Echo("Updating the Property table...");
// Set the default value of the CheckBox
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES (''LAUNCHAPP'', ''1'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
}
// NEW - START
WScript.Echo("Updating the ControlCondition table...");
// Insert the conditions where the Launch Application Checkbox appears
sql = "INSERT INTO `ControlCondition` (`Dialog_`, `Control_`, `Action`, `Condition`) VALUES (''FinishedForm'', ''CheckboxLaunch'', ''Show'', ''REMOVE=/"/"'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
sql = "INSERT INTO `ControlCondition` (`Dialog_`, `Control_`, `Action`, `Condition`) VALUES (''FinishedForm'', ''CheckboxLaunch'', ''Hide'', ''REMOVE<>/"/"'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
//NEW - END
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
Usando Visual Studio 2008 para crear un msi para implementar mi programa con un proyecto de instalación. Necesito saber cómo hacer que el msi ejecute el exe que acaba de instalar. Una acción personalizada? Si es así, explique dónde / cómo. Gracias.
En cuanto al "error oculto de la casilla de verificación", descubrí lo siguiente que no se explica por las respuestas anteriores de Cheeso y Muleskinner:
El cambio del guión (provisto por Muleskinner) coloca la posición Y de la casilla de verificación en 201 (supongo que es el píxel Y superior para el control). Si cambia Y a, digamos, 151 (para alinearlo en el centro verticalmente), aparece el error "repentinamente". El motivo es que hay otro control en la tabla de control del msi, es decir, ''BodyText'' (''Dialog'' field = ''FinishedForm'') cuya Y se establece en 63 y su altura en 138. Eso es 138 + 63 = 201. Por lo tanto, si cambia el valor Y de la casilla de verificación, el control ''BodyText'' se superpone con el control recién agregado y es por eso que el usuario necesita colocar el mouse para mostrar la casilla de verificación. Si no tiene ''BodyText'' o si su número de caracteres es lo suficientemente pequeño, podría cambiar (utilizando el editor de msica de Orca como lo hago o alterando el script anterior) las Ys y Alturas de estos 2 controles para poder y acomodar una posición Y diferente para la casilla de verificación recién agregada. Lo mismo aplica para el control: ''BodyTextRemove'' en el que nuevamente debemos modificar su valor de altura (que aparece durante la desinstalación)
Espero que esto ayude a todos los usuarios que tuvieron la misma pregunta que yo sobre este "error"
Sin embargo, ¡el script hace un muy buen trabajo!
Otra pregunta fue cómo hacer invisible la casilla de verificación durante el procedimiento de desinstalación. Usando el editor msi de Orca, agregué las siguientes 2 filas en la tabla ControlCondition del msi:
Fila 1 (cuando debe mostrarse el control):
(Diálogo) FinishedForm (Control) CheckboxLaunch (Acción) Show (Condición) REMOVE = ""
Fila 2 (Cuando el control debe ser invisible):
(Diálogo) FinishedForm (Control) CheckboxLaunch (Acción) Hide (Condición) REMOVE <> ""
PD. Estoy usando VS 2010, en Windows 7 (x64), pero creo que deberían funcionar también con versiones anteriores.
En cuanto al ''PostBuildEvent'' falló con el código de error ''1'' Error '' Error no especificado'' , cambie el PostBuildEvent de
cscript.exe /"$(ProjectDir)ModifyMsiToEnableLaunchApplication.js/" /"$(BuiltOuputPath)/"
a
cscript.exe "$(ProjectDir)ModifyMsiToEnableLaunchApplication.js" "$(BuiltOuputPath)"
En cuanto a la falla oculta de la casilla de verificación , puede editar la línea 54 del script para convertirse en:
sql = "INSERT INTO `Control` (`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help`) VALUES (''FinishedForm'', ''CheckboxLaunch'', ''CheckBox'', ''9'', ''201'', ''343'', ''12'', ''3'', ''LAUNCHAPP'', ''{//VSI_MS_Sans_Serif13.0_0_0}" + checkboxText + "'', ''CloseButton'', ''|'')";
Esto parece ser una solución MUCHO más simple: Visual Studio Installer> Cómo iniciar la aplicación al final del instalador
Sí, escribiría una acción personalizada y la colocaría al final de la tabla InstallExecutionSequence
Esta es una pregunta común. No lo hago con solo una acción personalizada. La única forma que conozco es modificar el .msi después de que se haya generado. Ejecuto un script de Javascript como un evento posterior a la construcción para hacer exactamente eso. Inserta un nuevo cuadro de diálogo en el asistente de instalación, con una casilla de verificación que dice "¿Iniciar aplicación Foo?". Y luego hay una acción personalizada para ejecutar la aplicación, si la casilla de verificación está marcada.
Aparece como la última pantalla en la secuencia del asistente de instalación. Se ve como esto:
Este es el script que uso para modificar el MSI:
// EnableLaunchApplication.js <msi-file>
// Performs a post-build fixup of an msi to launch a specific file when the install has completed
// Configurable values
var checkboxChecked = true; // Is the checkbox on the finished dialog checked by default?
var checkboxText = "Launch [ProductName]"; // Text for the checkbox on the finished dialog
var filename = "WindowsApplication1.exe"; // The name of the executable to launch - change this to match the file you want to launch at the end of your setup
// Constant values from Windows Installer
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyInsert = 1;
var msiViewModifyUpdate = 2;
var msiViewModifyAssign = 3;
var msiViewModifyReplace = 4;
var msiViewModifyDelete = 6;
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql;
var view;
var record;
try
{
var fileId = FindFileIdentifier(database, filename);
if (!fileId)
throw "Unable to find ''" + filename + "'' in File table";
WScript.Echo("Updating the Control table...");
// Modify the Control_Next of BannerBmp control to point to the new CheckBox
sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`=''FinishedForm'' AND `Control`=''BannerBmp''";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.StringData(11) = "CheckboxLaunch";
view.Modify(msiViewModifyReplace, record);
view.Close();
// Insert the new CheckBox control
sql = "INSERT INTO `Control` (`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help`) VALUES (''FinishedForm'', ''CheckboxLaunch'', ''CheckBox'', ''9'', ''201'', ''343'', ''12'', ''3'', ''LAUNCHAPP'', ''{//VSI_MS_Sans_Serif13.0_0_0}" + checkboxText + "'', ''CloseButton'', ''|'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
WScript.Echo("Updating the ControlEvent table...");
// Modify the Order of the EndDialog event of the FinishedForm to 1
sql = "SELECT `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering` FROM `ControlEvent` WHERE `Dialog_`=''FinishedForm'' AND `Event`=''EndDialog''";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(6) = 1;
view.Modify(msiViewModifyReplace, record);
view.Close();
// Insert the Event to launch the application
sql = "INSERT INTO `ControlEvent` (`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES (''FinishedForm'', ''CloseButton'', ''DoAction'', ''VSDCA_Launch'', ''LAUNCHAPP=1'', ''0'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
WScript.Echo("Updating the CustomAction table...");
// Insert the custom action to launch the application when finished
sql = "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES (''VSDCA_Launch'', ''210'', ''" + fileId + "'', '''')";
view = database.OpenView(sql);
view.Execute();
view.Close();
if (checkboxChecked)
{
WScript.Echo("Updating the Property table...");
// Set the default value of the CheckBox
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES (''LAUNCHAPP'', ''1'')";
view = database.OpenView(sql);
view.Execute();
view.Close();
}
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
function FindFileIdentifier(database, fileName)
{
// First, try to find the exact file name
var sql = "SELECT `File` FROM `File` WHERE `FileName`=''" + fileName + "''";
var view = database.OpenView(sql);
view.Execute();
var record = view.Fetch();
if (record)
{
var value = record.StringData(1);
view.Close();
return value;
}
view.Close();
// The file may be in SFN|LFN format. Look for a filename in this case next
sql = "SELECT `File`, `FileName` FROM `File`";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
while (record)
{
if (StringEndsWith(record.StringData(2), "|" + fileName))
{
var value = record.StringData(1);
view.Close();
return value;
}
record = view.Fetch();
}
view.Close();
}
function StringEndsWith(str, value)
{
if (str.length < value.length)
return false;
return (str.indexOf(value, str.length - value.length) != -1);
}
Originalmente obtuve esto del blog de Aaron Stebner , y luego lo modifiqué.
Guarde ese archivo Javascript en el directorio del proyecto (el mismo directorio que contiene .vdproj), ModifyMsiToEnableLaunchApplication.js
nombre ModifyMsiToEnableLaunchApplication.js
. Para cada proyecto de configuración único, necesita modificar ese script y poner el nombre del exe adecuado en él. Y luego, necesita configurar el evento post-compilación en el proyecto de instalación para que sea este:
cscript.exe "$(ProjectDir)ModifyMsiToEnableLaunchApplication.js" "$(BuiltOuputPath)"
Asegúrese de escribir correctamente el nombre de la macro $(BuiltOuputPath)
. La palabra Ouput
está mal escrita por Microsoft, y Built
no se deletrea ¡ Build
!
Eso debería hacerlo.
Ver también : esta modificación que no incluye la casilla de verificación "ejecutar Foo.exe" en DESINSTALAR.