Intelligente Installationen
Auch wenn der CAB Parser von Windows Mobile diverse nette Aktivitäten anhand von .xml-Dateien alleine durchführen kann, trifft man trotzdem von Zeit zu Zeit auf Aufgaben, die mit einer .xml-Datei allein nicht lösbar sind (z. B. das Löschen von zur Laufzeit erstellten Dateien). In so einem Fall kann nur selbst erstellter Code helfen. Doch wie soll man den ausführen, wenn die Anwendung schon längst gelöscht ist? Für dieses Problem hat Microsoft immerhin eine Lösung gefunden. Und die heißt Setup-DLL. Das ist eine native (also in C++ geschriebene) Bibliothek, die vom CAB Parser im Rahmen der Installation oder Deinstallation der Anwendung aufgerufen wird. Die Grundstruktur einer solchen DLL zeigt Listing 5:
//#include "tchar.h"#include "stdafx.h"#include "ce_setup.h"#include "notify.h"#include <windows.h>#include <commctrl.h>BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpvReserved){return TRUE;}//these are needed according to MSDN, as the library is not//recognized otherwisecodeINSTALL_INIT Install_Init(HWND hwndParent,BOOL fFirstCall, // is this the first time this function is being called?BOOL fPreviouslyInstalled,LPCTSTR pszInstallDir){// TODO: Add custom installation code here// To continue installation, return codeINSTALL_INIT_CONTINUE// If you want to cancel installation,// return codeINSTALL_EXIT_UNINSTALLreturn codeINSTALL_INIT_CONTINUE;}codeINSTALL_EXIT Install_Exit(HWND hwndParent,LPCTSTR pszInstallDir,WORD cFailedDirs,WORD cFailedFiles,WORD cFailedRegKeys,WORD cFailedRegVals,WORD cFailedShortcuts){// TODO: Add custom installation code here// To exit the installation DLL normally,// return codeINSTALL_EXIT_DONE// To unistall the application after the function exits,// return codeINSTALL_EXIT_UNINSTALLreturn codeINSTALL_EXIT_DONE;}codeUNINSTALL_INIT Uninstall_Init(HWND hwndParent,LPCTSTR pszInstallDir){// TODO: Add custom uninstallation code here// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE// If you want to cancel installation,// return codeUNINSTALL_INIT_CANCELreturn codeUNINSTALL_INIT_CONTINUE;}codeUNINSTALL_EXIT Uninstall_Exit(HWND hwndParent){// TODO: Add custom uninstallation code herereturn codeUNINSTALL_EXIT_DONE;}
Diese Struktur muss zu 100 Prozent übernommen werden (inklusive der DLLMain). Fehlt auch nur eine einzige Funktion, wird die DLL nicht akzeptiert und zur Laufzeit vom CAB Parser stillschweigend (!!!) ignoriert. Die vier Routinen werden zu bestimmten Zeitpunkten während der Installation aufgerufen. Je nach Rückgabewert wird die Installation / Deinstallation abgebrochen oder fortgeführt.
Setup-DLL – Feuer frei!
Als abschließendes Beispiel wird hier eine Setup-DLL konstruiert, die eine Event-Registrierung aufhebt. Zuerst muss die Setup-DLL erstellt werden. Dazu dient ein „normales“ und MFC-freies Win32-Smartprojekt (zu finden unter VISUAL C++ | INTELLIGENTES GERÄT | WIN32-PROJEKT FÜR INTELLIGENTE GERÄTE). Man muss im Settings Wizard jedoch DLL wählen, um eine DLL zu erhalten.
Dann kopiert man die zuvor gezeigte DLL-Struktur ins Programm und fügt das in Listing 6 gezeigte Snippet anstelle des Funktionsskeletts ein. Es ruft mehrfach die Funktion zur Deregistrierung eines Eventhandlers auf – mehr dazu findet sich in der MSDN:
codeUNINSTALL_INIT Uninstall_Init(HWND hwndParent,LPCTSTR pszInstallDir){int i;_tcscat((TCHAR*)pszInstallDir,_T("\\DaquPopup.exe"));for(i=0; i<20; i++){CeRunAppAtEvent((TCHAR*)pszInstallDir, NOTIFICATION_EVENT_NONE);}return codeUNINSTALL_INIT_CONTINUE;}
Damit ist die DLL eigentlich erledigt. Leider wissen außenstehende Anwendungen nichts davon, was in der DLL so alles schlummert – dazu benötigt man eine DEF-Datei, die dem Projekt hinzugefügt werden muss. In ihr definiert man die von außen sichtbaren Funktionen –hier ein Beispiel dafür:
LIBRARY "SetupDLL"EXPORTSInstall_InitInstall_ExitUninstall_InitUninstall_Exit
Wenn sich die DLL problemlos kompilieren lässt, ist der Spuk auch schon vorbei – die DLL wird, wie oben gezeigt, dem CAB-Projekt hinzugefügt (auch hier lautet das Zauberwort Primäre Ausgabe). Dann wird sie in der Eigenschaftsseite dem Projekt als CE Setup-DLL zugewiesen und das CAB neu erstellt. Geschafft …



