Błąd MSI 2769
Błąd "MSI 2769" jest dość często spotykanym błędęm, występującym podczas instalacji, reperacji lub deinstalacji pakietów wykonanych w "Microsoft Visual Studio" i bazujących na technologii ".Net Framework". Elementami powodującymi powstawanie tego błędu są najczęściej błędnie napisane klasy lub akcje ("Custom actions").
W poniższym opisie posłużono się pakietem opartym na klasie "ProjectInstaller" oraz jej komponentach "ServiceProcessInstaller" i "ServiceInstaller".
Instalacja oraz deinstalacjia pakietu przebiega bezproblemowo jednak podczas reperacji generowany jest "błąd 1001", informujący o tym, że serwis jest już zainstalowany w systemie i nie wymaga ponownej instalacji.
Rys.1. Błąd reperacji pakietu
"Błąd 1001" ma swoje odzwierciedlenie w tabeli "Error" bazy danych pakietu-msi.
Rys.2. Tabela "Error" w edytorze ORCA
Błędy o numeracji od 1000 do 1999 są błedami wewnętrznymi Windows Installera i są obsługiwane przez wpisy w tabeli "Errors", natomiast o numeracji od 2500 do 3000 są błędami wywołania akcji ("Custom actions") i bardzo często mają krytyczny wpływ na instalację pakietu.
Wpis w tabeli "Errors" nie mówi nam za wiele i aby znaleźć prawdziwe źródło odpowiedzialne za powstały błąd, należy zajrzeć do logu instalacyjnego (szukamy więc informacji o błędzie 1001).
MSI (s) (80:FC) [14:14:45:888]: Generating random cookie.
MSI (s) (80:FC) [14:14:45:904]: Created Custom Action Server with PID 1288 (0×508).
MSI (s) (80:F0) [14:14:45:966]: Running as a service.
MSI (s) (80:04) [14:14:45:966]: Hello, I'm your 32bit Elevated custom action server.
MSI (s) (80:F4) [14:15:55:524]: Leaked MSIHANDLE (9) of type 790531 for thread 1660
MSI (s) (80:F4) [14:15:55:524]: Note: 1: 2769 2: _09A1EA63_58DC_4827_BFA4_44059F3467B0.install 3: 1
MSI (c) (B4:C8) [14:14:46:435]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg Fehler 1001. Error 1001. Der angegebene Dienst ist bereits vorhanden
DEBUG: Error 2769: Custom Action _09A1EA63_58DC_4827_BFA4_44059F3467B0.installdid not close 1 MSIHANDLEs.
Bei der Installation dieses Pakets ist ein unerwarteter Fehler aufgetreten. Es liegt eventuell ein das Paket betreffendes Problem vor. Der Fehlercode ist 2769. Argumente: _09A1EA63_58DC_4827_BFA4_44059F3467B0.install, 1,
MSI (s) (80:98) [14:15:55:524]: User policy value 'DisableRollback' is 0
MSI (s) (80:98) [14:15:55:524]: Machine policy value 'DisableRollback' is 0
Aktion beendet um 14:15:55: InstallExecute. Rückgabewert 3.
Jak można zauważyć podczas reperacji produktu w logu instalacyjnym zapisywany jest błąd o numerze "2769", którego źródłem jest akcja "_09A1EA63_58DC_4827_BFA4_44059F3467B0.install"
DEBUG: Error 2769: Custom Action _09A1EA63_58DC_4827_BFA4_44059F3467B0.installdid not close 1 MSIHANDLEs.
Aby stwierdzić czy serwis jest instalowany w standardowy sposób czy przy pomocy akcji ("Custom actions") przechodzimy do tabel "ServiceInstall" i "ServiceControl" i sprawdzamy ich zawartość. Obie tabele są puste, co oznacza, że serwis jest instalowany przy pomocy akcji. W tabeli "CustomActions" znajdziemy wszystkie akcje odpowiedzialne za instalację /deinstalację serwisu (zaczynają sie od podkreślnika)
Rys.3. Zawartość tabeli "CustomAction"
Natomiast w tabeli "InstallExecuteSequence" znajdziemy sekwencje, którym przypisane są kolejno poszczególne akcje. Odszukujemy naszą "akcję" i sprawdzamy zawartość rekordu "Condition":
Rys.4. Zawartość tabeli "InstallExecuteSequence"
Mamy tu następujący zapis "$C__A86DDC61F5864695A26A870927B7E6A3>2", z którego wynika, że akcja jest wykonywana gdy, komponent "C__A86DDC61F5864695A26A870927B7E6A3" ($ wskazuje na komponent), zawierający plik "StartAppsEWX.exe", jest dostępny w systemie lub uruchamiany bezpośrednio ze źródła instalacji (wartość > 2, oznacza, że może przyjmować stany 3 i 4).
Poniższa tabela zawiera możliwe stany dla komponentów i "ficzerów" stosowane przy definiowaniu kondycji.
Stan (State) Wartość (Value) Znaczenie (Meaning)
INSTALLSTATE_UNKNOWN -1 Akcja nie będzie wykonywana na komponencie lub "ficzerze".
INSTALLSTATE_ADVERTISED 1 Tylko w przypadku istnienia zaanonsowanych "ficzerów". Stan niedostępny dla komponentów.
INSTALLSTATE_ABSENT 2 "Ficzer" lub komponent nie istnieje.
INSTALLSTATE_LOCAL 3 "Ficzer" lub komponent znajduje się na lokalnym komputerze.
INSTALLSTATE_SOURCE 4 "Ficzer" lub komponent jest uruchamiany z plików źródłowych.
Rozwiązanie
1. Otwieramy pakiet do edycji w programie Orca i tworzymy transformację (menu "Transform" -> "New Transform")
2. Przechodzimy do tabeli "CustomAction" i usuwamy wszystkie akcje powiązane z naszym serwisem
Rys.5. Zawartość tabeli "CustomAction" po modyfikacjach
3. Analogicznie postępujemy w tabeli "InstallExecuteSequence"
Rys.6. Zawartość tabeli "InstallExecuteSequence" po modyfikacjach
4. Następnie w tabeli "ServiceInstall" uzupełniamy następujace rekordy
Nazwa rekordu Wartość Opis
ServiceInstall App Główny klucz (Primary key) tabeli - dowolna nazwa
Name app Nazwa serwisu
DisplayName App Client Service Nazwa serwisu używana do identyfikacji przez inne programy
ServiceType 16 Typ serwisu, wartość "16" oznacza 32-bitowy serwis, który jest uruchamiany we własnym procesie
StartType 2 Flaga identyfikujaca w jaki sposób uruchamiany jest serwis. Wartość "2" oznacza, że serwis jest uruchamiany przy starcie systemu
ErrorControl 1 Określa sposób obsługi błędu, podczas uruchamiania serwisu. Wartość "1" oznacza , że informacja o napotkanym błądzie zapisywana jest do logu systemowego. Dodatkowo wyświetlany jest komunikat z treścią błędu i kontynuowana jest operacja uruchomienia serwisu.
Component_ C__A86DDC61F5864695A26A870927B7E6A3 Wskaźnik do komponentu
Description App Service Opis serwisu
Rys.7. Zawartość tabeli "ServiceInstall" po wprowadzeniu danych
5. W tabeli "ServiceControl" uzupełniamy kolejno następujące rekordy
Nazwa rekordu Wartość Opis
ServiceControl app Główny klucz (Primary key) tabeli - dowolna nazwa
Name app Nazwa serwisu
Event 160 Operacje wykonywane na serwisie podczas instalacji\deinstalacji produktu (wartość "160" oznacza, że serwis jest zatrzymywany i usuwany podczas deinstalacji)
Wait 0 Wartość "0" wymusza pause na instalatorze, aż do momentu kiedy SCM (Service Control Manager) powiadomi o tym, że serwis jest w stanie oczekiwania na kolejne instrukcje.
Component_ C__A86DDC61F5864695A26A870927B7E6A3 Wskaźnik do komponentu
Rys.8. Zawartość tabeli "ServiceConrol" po wprowadzeniu danych
6. Zapisujemy transformację (menu "Transform" -> "Generate Transform…") i testujemy instalację, reperację oraz deinstalację pakietu.









