AKInstaller      
Erste Schritte - Teil7: Benutzerdefinierte Aktionen, Teil 3 Eigene DLLs



Die Königsdisziplin, eigene DLLs die den Funktionsumfang des Setups erweitern. Genau diese Schnittstelle für DLLs wird unter anderem von folgenden Erweiterungen genutzt: Firewall, Instanzen, Treiber, geplante Tasks, NT-Dienste, .NET-Assemblies und Windows Features.

Das zeigt schon das man damit eine ganze Menge bewerkstelligen kann.


Tipp: In dem Ordner ?:\Programme\AKApplications\AKInstaller\Extensions\ finden Sie ein Demo-Projekt mit Namen EXT_Demo.zip dazu.


Die API bietet eine Vielzahl von Funktionen mit der Sie auf den Datenbestand des Setups zugreifen oder mit der Sie Daten wandeln bzw. prüfen können.

Neben WriteToLog um Meldungen in das Logfile zu schreiben oder GetProperty, SetProperty und EvaluateCondition auch Befehle wie GetUserSID oder CompareVersion und Zugriff auf den RestartManager mittels RMRegisterFile.

Dabei sind viele Befehle nach dem gleichen Schema aufgebaut, dazu schauen wir und mal einen davon an:

typedef long ( WINAPI * AKI_GetProperty)
   (
LPCTSTRI szProperty, LPSTRI pValueBuf, DWORD& chValueBuf);

Im ersten Parameter wird der Name der Eigenschaft erwartet.

Der Zweite erwartet einen CHAR-Buffer entsprechender Länge.

Der dritte ein DWORD mit der Länge.



Die einfachste Variante wäre also:

char szString1[100-1] = {0};
DWORD dwSize= 100;
akiStruct->GetProperty("VAR_MeineEigenschaft", szString1, dwSize);


Etwas aufwendiger wird es, wenn die Länge unbekannt ist, hier mal ein Beispiel mit Text:

dwSize = 0;
if(akiStruct->GetText( "IDC_WelcomeSetup", NULL, dwSize) == 0)
   {
   char* pBuffer1 = reinterpret_cast<char *>(malloc( dwSize));

   if(pBuffer1)
      {
       akiStruct->GetText("IDC_WelcomeSetup", pBuffer1 pBuffer11, dwSize);
...


Häufig kommt es vor, das man Texte ähnlich sprintf() formatieren möchte, man hat z. B. einige Daten ermittelt und möchte jede nach Situation an unterschiedlicher Stelle platzieren und damit sinnvoll ausgeben oder entsprechen für Zugriffe aufarbeiten. 

Ein sehr einfaches Beispiel:
"Hallo [1], [2] ist [3]" ist unsere Vorlage.
Text1=Benutzer,
Text2=heute,
Text3=Freitag

dwSize= 0;
if(akiStruct->FormatString("Hallo [1], [2] ist [3]", NULL, dwSize,
   "Benutzer", "heute", "Freitag", NULL) == 0)
   {
   char*pBuffer2 = reinterpret_cast< char*>(malloc(dwSize));

   if( pBuffer2)
      {
      akiStruct-> FormatString("Hallo [1], [2] ist [3]", pBuffer2, dwSize,
         "Benutzer", "heute", "Freitag, NULL);

     
MessageBox(0, pBuffer2, "FormatString",0);
      free ( pBuffer2);
      }
   }

Der Vorteil gegenüber sprintf() ist hier, das der Aufbau der Vorlage durch die Syntax von Sprachen durchaus variieren kann, z. B. das Tag/Monat im Deutschen Monat/Tag im Englischen.

In diesem Falle wäre die Vorlage die auf der Seite Sprachen angegeben und die vorher mittels GetText() geholt wurde "[1].[2].[3]" oder "[2].[1].[3]" während die Parameter immer "24", "12", "2017" lauten.


Wie bei normalen Benutzerdefinierten Aktionen die Setup-Seiten, müssen diese DLLs mindestens eine der folgenden Einstiegspunkte haben:

  • EXT_IAppSearchProcess
  • EXT_IAppSearchExecute
  • EXT_ILaunch
  • EXT_IPrepare
  • EXT_IProcess
  • EXT_IExecute
  • EXT_IRollbackPre
  • EXT_IRollbackPost
  • EXT_ICommit
  • EXT_UProcess
  • EXT_UExecute

long WINAPI EXT_IExecute(struct AKIStructI*akiStruct) ...

Hat eine DLL eine dieser Funktionen wird diese aufgerufen.
Und im Idealfall kehrt die Funktion mit ERROR_SUCCESS (0) zurück.  An dieser Stelle sei noch mal das Demo-Projekt ..\AKApplications\AKInstaller\Extensions\EXT_Demo.zip erwähnt welches viele Funktionen mit Beispielen bedient.

>> Fortsetzung