2009-03-06 9 views
6

Aby rozwiązać problem listed here Muszę zmienić rekord InstallExecuteSequence .RemoveExistingProducts w MSI.Skrypt do zmiany rekordów sekwencji akcji w MSI

chcę zrobić to jako część procesu budowania zamiast mucking z Orca

+0

obejmuje także http://stackoverflow.com/questions/370940/visual-studio-2008-service-installer-project-upgrade-issue, którego cytowane pytanie jest dupkiem –

Odpowiedz

13

Modyfikacja skryptu MSI_SetProperty.js daje

// 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); 
} 

Aby wywołać ten skrypt, aby wykonać zmianę działaniu w powyższej sekwencji umieścisz następujące informacje w pliku wsadowym i wywołasz je w zdarzeniu budowania postu, np PostBuildEvent = $ (ProjectDir) PostBuild.bat

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

Łącze MS również wspomina o usunięciu InstallExecute linia. Czy to jest wymagane? – RBear

+0

Erm - jaki link MS? Używam tego tak jak przez ponad rok, wydaje się działać dobrze. – Ryan

+0

Ten w twoim drugim poście możesz umieścić link na górze http://social.msdn.microsoft.com/forums/en-US/winformssetup/thread/519faa07-5b4e-4546-bfb3-6f233bf7286f. Szwy działają tak czy inaczej. – RBear

0

Kilka uwag dla innych osób. Miałem błąd "Błąd 1001. Określona usługa już istnieje" i wypróbowałem powyższe i wydawało się, że nie działa. Oto, na co natknąłem się:

* Upewnij się, że właściwość RemovePreviousVersions w projekcie instalatora jest ustawiona na True. Wydaje się to oczywiste - oczywiste, to znaczy, jeśli o tym wiesz. Domyślnie jest ustawiony na False. Jeśli Fałsz, powyższa procedura nie rozwiąże Twojego problemu. *

Mam kilka złożeń zainstalowanych w GAC. Wydaje się, że kiedy przeniosłem sekwencję RemoveExistingProducts, że te pliki zostały usunięte z GAC, ale nie zostały ponownie zainstalowane. Aby rozwiązać ten problem, zainstalowałem wszystkie zestawy w folderze aplikacji. FYI, używam VS2010.

Kolejny nit-pick. Jeśli użytkownik wybierze opcję "Napraw" podczas próby ponownego zainstalowania tej samej wersji produktu, nadal będzie wyświetlał komunikat "Określona usługa już istnieje". Jeśli dostanę czas, spróbuję to naprawić. Jeśli ktoś inny wie, jak to naprawić, czy możesz opublikować?

Wszystko, co powiedzieliśmy, dzięki za opublikowanie tego!

0

Rozwiązanie dostarczone przez Ryana dotyczy części problemu, z którym się stykam. Wykonuje pełne odinstalowanie, a następnie instalację.

Jednak mam inny problem, w moim przypadku niektóre programy działają w tle. Zanim uruchomi się instalator, instalator narzeka, że ​​niektóre pliki są w użyciu. I daje standardowe okno dialogowe z prośbą o zamknięcie aplikacji lub ponowne uruchomienie w celu dokończenia aktualizacji.

Czy istnieje sposób, np. niestandardową akcję lub ustawienie, aby zabić procesy działające w tle, aby instalator działał gładko?

+0

Lepiej spytaj o to jako własne PYTANIE zamiast zamieszczać je tutaj jako ODPOWIEDŹ - sprawdź FAQ w prawym górnym rogu. – Ryan