2009-03-06 4 views
6

Per risolvere un problema listed here Devo modificare il record InstallExecuteSequence .RemoveExistingProducts in un MSI.Script per modificare i record di sequenza di azioni in un MSI

che voglio fare questo come parte del processo di generazione piuttosto che gingillarsi con Orca

+0

copre anche http://stackoverflow.com/questions/370940/visual-studio-2008-service-installer-project-upgrade-issue, che la domanda citata è un dup di –

risposta

13

Modificare lo script MSI_SetProperty.js dà

// MSI_SetActionSequence.js <msi-file> <table> <action> <sequence> 
// Performs a post-build fixup of an msi to set the specified table/action/sequence 

// Constant values from Windows Installer SDK 
var msiOpenDatabaseModeTransact = 1; 

var msiViewModifyInsert   = 1; 
var msiViewModifyUpdate   = 2; 
var msiViewModifyAssign   = 3; 
var msiViewModifyReplace  = 4; 
var msiViewModifyDelete   = 6; 

if (WScript.Arguments.Length != 4) 
{ 
    WScript.StdErr.WriteLine("Usage: " + WScript.ScriptName + " file table action sequence"); 
    WScript.Quit(1); 
} 

var filespec = WScript.Arguments(0); 
var table = WScript.Arguments(1); 
var action = WScript.Arguments(2); 
var sequence = parseInt(WScript.Arguments(3)); 

var installer = WScript.CreateObject("WindowsInstaller.Installer"); 
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact); 

WScript.StdOut.WriteLine("Looking for action:" + action); 

try 
{ 
    var sql = "SELECT Action, Sequence FROM " + table + " WHERE Action = '" + action + "'"; 
    var view = database.OpenView(sql); 

    view.Execute();  
    var record = view.Fetch(); 

    if (record) 
    {  
     while (record) 
     { 
      WScript.StdOut.Write("Found: " + record.StringData(0) + ", " + record.StringData(1) + ", " + record.StringData(2)); 
      if (record.IntegerData(2) != sequence) 
      { 
       WScript.StdOut.WriteLine(" - changing to " + sequence); 
       record.IntegerData(2) = sequence; 
       view.Modify(msiViewModifyUpdate,record); 
      } 
      else 
       WScript.StdOut.WriteLine(" - OK"); 

      record = view.Fetch(); 
     } 

     view.Close(); 
     database.Commit(); 
    } 
    else 
    {   
     view.Close(); 
     throw("Warning - Could not find " + table + "." + action); 
    } 
} 
catch(e) 
{ 
    WScript.StdErr.WriteLine(e); 
    WScript.Quit(1); 
} 

chiamare questo script per eseguire la modifica all'azione sequenza sopra menzionata metterebbe quanto segue in un file batch e chiameremo quell'evento post build ad es PostBuildEvent = $ (ProjectDir) PostBuild.bat

cscript.exe MSI_SetActionSequence.js YOURINSTALLER.MSI InstallExecuteSequence RemoveExistingProducts 1525 
+0

Il collegamento MS menziona anche la rimozione di InstallExecute linea. È richiesto? – RBear

+0

Erm - quale collegamento MS? Ho usato questo come è per oltre un anno, sembra funzionare bene. – Ryan

+0

Quello dell'altro post che si collega a http://social.msdn.microsoft.com/forums/en-US/winformssetup/thread/519faa07-5b4e-4546-bfb3-6f233bf7286f Le giunzioni funzionano in entrambi i casi. – RBear

0

Alcune note per gli altri là fuori. Ho avuto il problema "Errore 1001. Il servizio specificato esiste già" e ho provato quanto sopra e non sembra funzionare. Ecco cosa mi sono imbattuto in:

* Assicurarsi che la proprietà RemovePreviousVersions sul progetto di installazione sia impostata su True. Questo sembra ovvio, ovvio, cioè se lo sai. Di default è impostato su False. Se False, la procedura sopra descritta non risolverà il tuo problema. *

Ho alcuni assembly installati nel GAC. Sembra che quando ho spostato la sequenza RemoveExistingProducts che questi file sono stati rimossi dal GAC, ma non reinstallati. Per risolvere questo problema ho installato tutti gli assembly nella cartella dell'applicazione. Per tua informazione, sto usando VS2010.

Inoltre, un altro pignone. Se un utente seleziona "Ripristina" quando tenta di reinstallare la stessa versione di un prodotto, otterrà comunque l'errore "Il servizio specificato esiste già". Se avrò tempo cercherò di risolvere questo problema. Se qualcun altro là fuori sa come risolverlo, potresti pubblicare?

Tutto ciò detto, grazie per aver postato questo!

0

La soluzione fornita da Ryan risolve parte del problema che sto affrontando. Esegue la disinstallazione completa, seguita dall'installazione.

Tuttavia, ho un altro problema, nel mio caso alcuni dei programmi sono in esecuzione in background. Prima che il programma di installazione possa essere eseguito, l'installatore si lamenta che alcuni dei file siano in uso. E fornisce una finestra di dialogo standard che chiede di chiudere l'applicazione o di riavviarla per completare l'aggiornamento.

C'è un modo, ad es. un'azione personalizzata o un'impostazione, per uccidere i processi in esecuzione in background in modo che il programma di installazione vada liscio?

+0

È meglio chiederlo come una tua DOMANDA piuttosto che postarla qui come RISPOSTA - controlla le FAQ in alto a destra. – Ryan