Category Archives: Best Practices

COM Components

The Component Object Model (COM) is a technology developed by Microsoft to enable Windows interprocess communication and dynamic object creation. COM Objects are language independent and can be implemented in any development language which has a compiler that can compile the approriate code, such as C++.

Typical examples of compiled code are:

  • DLL (Dynamic Linking Library)
  • OCX (ActiveX control)
  • TLB (Type Libraries)
  • EXE (Executables)

The access to the funtionality of a COM Object takes place through an interface, which allows the functions offered by the COM Object.

Using the “REGSVR32.EXE” Tool the most common binaries such as DLL and OCX can be registered. Thereby new class IDs are created in the registry database that refer to the relevant binary file. Thus, their functions can now be used on Windows and programs access the class IDs to perform required functions.

Examples registering compiled codes:

In case of DLL/OCX

To register a DLL or OCX, use regsvr32.exe as follows:

  1. Select Start -> Run
  2. In the dialog box, type the following:

Regsvr32 <full path of DLL or OCX to be registered>

For example, “regsvr32 C:\Windows\System32\msaatext.dll” would register the library named msaatext.

If successful, you’ll see the message:


Why not all DLL’s can be registered

A DLL needs to be specifically written to be used with the regsvr32 command to register.
The DLL must implement DllRegisterServer and DllUnregisterServer, which contain the logic that is necessary to add or delete the required registry entries for the COM component. RegSvr32 finds the entry point to these functions, and calls them appropriately.
If the DLL was not written to be used with regsvr32 then the conventional entry point will not be found, and you get an error message.


In case of TLB

To register a type library, use regtlib.exe.

  1. Select Start -> Run
  2. In the dialog box, type the following

Regtlib <full path to the type library>

For example, “regtlib C:\Program Files\MyApp\MyTypeLib.tlb” would register the library MyTypeLib.

If successful, a dialog box similar to the one shown for the DLL will appear.

In case of EXE

To register an EXE:

  1. Select Start -> Run
  2. In the dialog box, type the following:

<Full path of the EXE file> /RegServer

For example, “C:\Program Files\myAPP\MyEXE.exe /RegServer” will register the Executable MyExe.exe.


Different Types of registration Keys



Below you find some registry keys in relation with com components and its explanations.


A CLSID (class identifier) is a globally unique identifier that identifies a COM class object.  The CLSID is a 128-bit number, spelled in hexadecimal format, within a pair of braces.

One of the following values must exist to instruct the system where to find the component:

 HKEY_CLASSES_ROOT\CLSID\<CLSID> (default) = <human-readable class name>
 HKEY_CLASSES_ROOT\CLSID\<CLSID>\LocalServer = <full path to 16-bit file>
 HKEY_CLASSES_ROOT\CLSID\<CLSID>\LocalServer32 = <full path to 32-bit file>
 HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer = <full path to 16-bit file>
 HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <full path to 32-bit file>

On 64-bit Windows, 64- and 32-bit in-process servers uses the InprocServer32 entry.

Other optional values include:

 HKEY_CLASSES_ROOT\CLSID\<CLSID>\DefaultIcon = <path to file, icon index #>


The ProgID (programmatic identifier), is a Registry entry that can be associated with a CLSID. The format of a ProgID is <Vendor>.<Component>.<Version>, separated by periods and with no spaces, as in Word.Document.6. Like the CLSID, the ProgID identifies a class, but with less precision. The ProgID is stored under the following registry key:

 HKEY_CLASSES_ROOT\<ProgID>\(default) = <human-readable component name>

There are also version-independent program ID’s with the format <Program>.<Component>, as follows:

 HKEY_CLASSES_ROOT\<Versionless-ProgID>\CurVer = <ProgID>


COM uses the word interface in a sense different from that typically used in Visual C++ programming. A C++ interface refers to all of the functions that a class supports and that clients of an object can call to interact with it. A COM interface refers to a predefined group of related functions that a COM class implements, but a specific interface does not necessarily represent all the functions that the class supports.

If the component needs to register an interface, it requires the following syntax:

 HKEY_CLASSES_ROOT\Interface\<IID>\ProxyStubCLSID or ProxyStubCLSID32 = <CLSID>


Type libraries are files that explicitly describe some or all of the contents of components. This includes information about the methods, properties, constants, and other members exposed by the component. The following Registry keys are also set in this case:

 HKEY_CLASSES_ROOT\Interface\<IID>\TypeLib\(default) = <TypeLib>
 HKEY_CLASSES_ROOT\TypeLib\<TypeLib>\<#.#>\<#>\<Platform>\(default) = <path to .TLB file>


If your typelib isn’t locale-specific, you can specify 0 for the <LCID>.

<Platform> can be win32, win64 or win16 depending on the platform of the binary.


The AppID concept was introduced as part of the security support in COM. The AppID essentially represents a process that is shared by multiple CLSIDs. All objects in this process share the same default security settings.

DCOM provides mechanisms to externally configure security settings for objects and clients. In the current implementations of DCOM all security policies are enforced at the process level. All objects in a process share the same security policies, unless they programmatically override them. To match this process-wide security configuration, DCOM introduces the concept of an AppID.

AppIDs group the configuration options for one or more DCOM objects into one centralized location in the registry. COM objects hosted by the same executable must map into the same AppID. In-process COM objects that are run in a surrogate process can be forced into the same process by assigning the same AppID to their CLSID entries.

The AppID is a string which looks like a filename, e.g. “MYAPP.EXE”.

 HKEY_CLASSES_ROOT\AppID\<AppID>\DllSurrogate or DllSurrogateExecutable = <path to file>
 HKEY_CLASSES_ROOT\AppID\<AppID>\LocalService and ServiceParameters

Registering COM Component in a MSI

Windows Installer Best Practices does not recommend using the SelfReg and TypeLib table to register a COM Component.
Instead use the registry table to add the COM registration information.

To get the registration information use any “Registry Capturing tool” like RegShot to capture the registry keys. The captured registry keys should be imported into the registry table in the MSI.

The AdminStudio Software Packaging Tool contains a “Component Wizard” which automatically extracts the necessary informations and implements into the installation.


The Future of COM Components

The trend is increasingly towards .NET Framework.
The .NET Framework provides bi-directional interoperability with COM, which enables COM-based applications to use .NET components and .NET applications to use COM components.

Good to know that .NET relies on COM+ for its enterprise features.  At least for the time being these technologies are complimentary.  And COM is one of the core technologies that is not going away any time soon either, although from the client’s perspective, there will be more and more .NET managed APIs exposed over time, which will provide developer with a choice of interfaces.



Class IDs verification Test

Dieser Post geht auf den Test Expert ein, welcher mit einer Wise Package Studio Quality Assurance Erweiterung oder mit der Wise Package Studio Suite Edition zur Verfügung steht.
Im Wise Test Expert existiert unter ‘Application Verification Tests’ ein Class IDs  Test Case.  Mit diesem Test Case lassen sich Klassen, also Registry Einträge unter HKCRCLSID automatisch Testen, ohne die Applikation starten und alle Funktionen sowie Unterfunktionen testen zu müssen.

Dieser Test Case unterliegt  der ClassID Tabelle der ausgewählten Applikation und verwendet die CoCreateInstance Funktion um die Funktionalität der Klasse zu verifizieren. Natürlich erhofft man sich bei der Verwendung des Wise Test Expert ein Erfolgs-Resultat von 100%. Die Praxis zeigt uns jedoch, dass bei den Class IDs Tests ein Resultat von 20% schon eine voll funktionierende Applikation ausweissen kann.

Der Grund für diesen Beitrag besteht darin offen zu legen, warum im Test Expert bei den Class IDs Test ein Resultat von 20% schon gut genug sein kann.

Ich habe über die Jahre alle möglichen Resulate aus dem Test Experten analysiert und eine Liste erstellt, worin zu ersehen ist, bei welchen ‘Error Numbers’ eine Installation auf Fehler zu überprüfen ist und bei welchen Nummern die Klasse als funktionsfähig einzustufen ist.

Error Number Error Description Real Error
0x80040154 Class not registered maybe
0x80004002 No such interface supported no
0x80080005 Server execution failed no
0x80004005 Unspecified error no
0x80040111 cannot supply requested class no
0x8007007E The specified module could not be found yes
0x8000FFFF Catastrophic failure no
0x80040112 Class is not licensed for use no

Die Liste zeigt auf, es gibt verschiedene Gründe, warum ein Klassen-Test fehlschlagen kann.

Bei folgenden Fehler-Nummern kann die betroffene Klasse korrigiert werden:

Class not registered: Der Test kann nochmals durchgeführt werden, nach dem die betroffene Klassen-Datei (.DLL oder .OCX) mit dem Programm regsvr32.exe registriert wurde. Sollte nach einem erneuten Test die Klasse erfolgreich gestet werden können, so kann die fehlende Klasse in die Installation eingebaut werden.

The specified module could not be found: Verwenden Sie den Dependency Walker von Microsoft um die fehlende(n) Datei(en) in die Installation einzubauen.

Bei den restlichen Fehlermeldungen liegt fast sicher kein Problem vor, oder dieser lässt sich aus Sicht eines System-Administrator nur sehr selten verbessern.

Zusammenfassend muss ich festhalten, dass ein Klassen-Test mit der CoCreateInstance Funktion keine optimale Lösung ist, um eine verlässliche Aussage treffen zu können, ob eine Klasse wirklich funktioniert. Die Test-Resulate liefern viele Error Codes zurück, obwohl die Applikation funktionieren wird. Schlussendlich hat ein Software Hersteller verschiedene Möglichkeiten eine Klasse  für seine Applikation zu inizialisieren.

Wise Package Studio 8: Network Client Update umgehen.

Nach der Migration des Wise Package Studio Servers auf die Version 8.0 ist es leider auch nötig die Netzwerk Client Installationen zu aktualisieren.

Je nach Packaging Umgebung kann dies jedoch enormen Aufwand bedeuten.

Mit folgendem Trick kann man sich diesen Aufwand allerdings sparen:

– Installiere den Network Client der 8.0 Version auf einer sauberen VM/Client

– Exportiere danach den “Wise Solutions” Registry key. In diesem Key sind die neuen Lizenzinformation drin. Ohne diese lässt sich WPS 8.0 nicht starten.

– Erstelle ein neues WiseScript und füge mittels “Edit Registry” Aktion diese Keys hinzu

– Als 2 Aktion füge eine “Run Executable” Aktion hinzu, und zeige dort auf die  “PackageStudio8.exe” Executable auf dem Wise Package Studio Share.

– Kompiliere ein neues Executable und lege dies im Wise Package Studio Programmverzeichnis als “PackageStudio7.exe” ab

Nun wird bei alten Netzwerk Client Installationen die PackageStudio7.exe gestartet, welche die benötigten Registrierungsschlüssel für das Wise Package Studio 8 ins Benutzerprofil schreibt und danach die aktuelle PackageStudio8.exe startet.


Exclusion Liste für Windows 7

Die Software Repaketierung unter Windows 7 baut grundsätzlich auf die gleichen Repackaging Best Practices wie bei Windows Vista auf.

Aus unseren Erfahrungen, die wir bei Windows 7 Migrationprojekten gesammelt haben, empfehlen wir die Ausschlussliste-Liste mit folgenden Einträgen zu erweitern, um eine bessere Qualität des Deltas eines Snap-Shots unter Windows 7 zu erreichen.

Verzeichnis C:Boot excl. Sub-Directory
Verzeichnis C:UsersAll Users excl. Sub-Directory
Verzeichnis C:UsersAppDataLocalTemp excl. Sub-Directory
Verzeichnis C:UsersAppDataLocalLowMicrosoftCryptnetUrlCache excl. Sub-Directory
Verzeichnis C:UsersAll UsersMicrosoftRAC excl. Sub-Directory
Verzeichnis C:UsersAll UsersMicrosoftSearch excl. Sub-Directory
Verzeichnis C:ProgramDataMicrosoftRAC excl. Sub-Directory
Verzeichnis C:ProgramDataMicrosoftSearch excl. Sub-Directory
Verzeichnis C:WindowsServiceProfiles excl. Sub-Directory
Verzeichnis C:WindowsSystem32LogFiles excl. Sub-Directory
Verzeichnis C:WindowsSystem32winevtLogs excl. Sub-Directory
Datei ntuser.dat.LOG1 File/Wildcard
Datei UsrClass.dat File/Wildcard
Datei UsrClass.dat.LOG1 File/Wildcard
Registry HKCU SoftwareClassesLocal SettingsMuiCache Ignore entire subtree
Registry HKCU SoftwareClassesLocal SettingsSoftwareMicrosoftWindowsShell Ignore entire subtree
Registry HKLM SOFTWAREMicrosoftWindows Search Ignore entire subtree
Registry HKLM SOFTWAREMicrosoftReliability AnalysisRAC Ignore entire subtree
Registry HKLM SOFTWAREMicrosoftWindows NTCurrentVersionSPP Ignore entire subtree
Registry HKLM SOFTWAREMicrosoftWindows NTCurrentVersionSystemRestore Ignore entire subtree
Registry HKLM SYSTEMCurrentControlSetservicesVSS Ignore entire subtree
Registry HKLM COMPONENTS Ignore entire subtree
Registry HKLM Schema Ignore entire subtree

Weitere Informationen, was bei einer Windows 7 Migration zu beachten ist, können Sie an unserem User Group Meeting erfahren.
Nebst verschiedenen Keynotes zu aktuellen Themen erwarten Sie Technologie- und Produkte-News sowie Live Demos und Praxisberichte. Nutzen Sie die Gelegenheit sich effektiv zu informieren und mit Fachkollegen und Spezialisten zu diskutieren.


Internal Error 2709

Die Windows Installer 2709 Fehlermeldung ist eine Benachrichtigung, die bei einer Update Installation erscheinen kann. Wird eine betroffene Installation auf einer Clean Machine installiert, so sieht alles gut aus, keine Fehlermeldung erscheint. Sollte die gleiche Installation als Update Installation durchgeführt werden, so erscheint die 2709 Fehlermeldung. Interessant dabei ist, das der Test auf einer Clean Machine eigentlich das gleiche Problem haben sollte, das Problem aber aus internen Abläufen der Windows Installer Session automatisch korrigiert wird.


Das Problem kann unter anderem durch ein Setup-Capture mit Wise Package Studio entstehen, wenn Dateien mit Merge Modulen ersetzt werden. Wie in diesem Beispiel wurde die Datei comdlg32.ocx durch ein Merge Module von Microsoft ersetzt. Dieser Vorgang löscht jedoch nicht die Verweise der bereits erstellten Componenten in der FeatureComponents Tabelle.

Komponenten die während einem Setup-Capture mit einem Merge-Module ersetzt wurden, bleiben in der FeatureComponents Tabelle zurück

Das etwas mit diesen Komponenten nicht stimmt, wird in der Tabellenansicht des Windows Installer Editors ersichtlich. Werden diese Einträge übersehen, so wird auf diesen Misstand während der Validierung darauf hingewiesen:
Not a valid foreign key; Table: FeatureComponents, Column: Component_, Key(s): Complete.comdlg32.ocx ice03.html FeatureComponents Component_ Complete comdlg32.ocx
Evaluation: ICE03

Diese Einträge sind aus der FeatureComponents Tabelle zu löschen. Es kann jedoch vorkommen, das die Validierung aus unbekannten Gründen bei dieser Überprüfung fehlschlägt und keine Probleme angezeigt werden. Bei einem anschliessenden Testdurchlauf der Installation wird keine Fehlermeldung erscheinen, da die Windows Installer Session diese fehlerhaften Einträge überspringt.

Doing action: InstallValidate
Feature: Complete; Installed: Absent;   Request: Local;   Action: Local
Component: CreateFolder; Installed: Absent;   Request: Local;   Action: Local
Component: registry44; Installed: Absent;   Request: Local;   Action: Local
Component: findmsm.exe; Installed: Absent;   Request: Local;   Action: Local

Während der InstallValidate Aktion werden die betroffenen Komponenten ausgewählt, die fehlerhaften Einträge werden einfach übergangen.

Soweit scheint alles zu funktionieren, bis zu dem Tag, an dem mit der gleichen Installation ein Update durchgeführt wird. Bei einer Update Installation wird zusätzlich die MigrateFeatureStates Aktion durchgeführt. Diese überprüft die Stati der bereits Installierten Features und vererbt die Feature States bei der Update Installation (Die Vererbung von Feature Stati kann mit der Upgrade Tabelle deaktiviert werden). Die Aktion  MigrateFeatureStates übergeht  die fehlerhaften Einträge in der FeatureComponents Tabelle jedoch nicht und wird mit der Fehlermeldung 2709 die Installation abbrechen.

DEBUG: Error 2709:  The specified Component name (‘comdlg32.ocx’) not found in Component Table.

In diesem Fall sind in der Installation die fehlerhaften Einträge in der FeatureComponents Tabelle zu beheben. Wir empfehlen diese Überprüfung in die Best-Practices von Software-Paketierungs Guidelines aufzunehmen, um diesem Problem zuvor zukommen.


Es muss nicht gleich zum Windows Installer Error 1324 kommen, doch woher kommt bei einer Installation die %HOMEDRIVE%%HOMEPATH% Information?

Diese Frage und deren Auswirkungen sind Imgrunde einfach zu verstehen.

Die System-Variablen im Shortcut werden vom Explorer aufgelöst und die Applikation, welche in der Regel Per-Machine installiert wurde und deren Shortcut sich ebenfalls im AllUsers Profil befindet, wird das aktuelles Arbeitsverzeichnis des Benuters genommen. Damit kann der Softwarehersteller ohne grosse Mühe eine Per-Machine Installation durchführen, ohne eigene Shortcuts für jeden Benutzer erstellen zu müssen.

Bei einer standard Installation von Windows wird dieses Verzeichnis direkt ins Root des aktuellen Benutzerprofils zeigen. Dieser Umstand ist nicht optimal, da keine Dateien ins Root des Benutzerprofiles geschrieben werden sollen. Eine Alternative in diesem Fall wäre %APPDATA%, sofern die Daten Roamen dürfen.

Je nach AD und GP Umgebung werden diese beiden System-Variablen auf ein Verzeichnis eines Datei-Servers umgebogen, dann sind diese Variablen durchaus gebrauchtbar.

Umsetzung nach einem Snap-Shot:
Nach einem Snap-Shot mit Wise Package Studio befindet sich der Pfad in der Directory Tabelle.


Solange dieser nur als WorkingDir in der Shortcut Tabelle verwendet wird, besteht kein Anlas diesen zu änderen.

Wenn nun jedoch dieses Verzeichnis auch noch anderweitig in der Intallation verwendet wird, dann können grössere Probleme nicht ausgeschlossen werden. Ein bekanntes Problem zeichnet sich mit dem Windows Installer Error 1324 ab.

Bei diesem Fehler muss das Problem über die Directory Tabelle gesucht und gelöst werden. Die %HOMEDRIVE%%HOMEPATH% Variablen sind nichts anderes als der ProfilesFolder Eintrag in der Directory Tabelle, welcher seit Wise Package Studio SP3 auch dem Paketierer zur Verfügung steht.

Wer diese Variablen bei einem Shorcut aus der Diretory Tabelle bekommen möchte, kann folgender Weg einschlagen:

1. Den Eintrag in der Directory Tabelle löschen, sofern nur Abhängigkeiten zum WkDir in der MSI Datei besteht.

2. Das WkDir in der Shortcut Tabelle auf eine eigene (PublicProperty) Variable verweisen.

3. Diese Variable in der Property Tabelle einrichten.

Das Endresultat ist wohl gleich, doch die Bereitstellung der Daten ist verfolgt einen schöneren Weg.

Stefan Hotan
A member of the Ontrex SPA Team

Schöner Wise-Scripten

Neben der Erstellung von MSI-Paketen bietet Wise Package Studio noch nützliche andere Funktionen. Ich greife heute die vergleichsweise einfache Implementierung von mächtigen Scripts mittels Wise Script heraus.

Durch die Bedienung des Editors via Drag&Drop sind syntaktische Fehler im Quellcode fast unmöglich, einfacher kann man beispielsweise Änderungen an INI-Dateien, Registry-Einträge oder Pfadvariablen automatisiert kaum vornehmen.

Durch Kompilieren des Scripts wird dann eine EXE-Datei erstellt, die ohne weitere Runtimes auf Windows-System lauffähig ist.
Einen Schönheitsfehler hat ein kompiliertes Wise Script dennoch: Den blauen Hintergrund zur Laufzeit.

Kompiliertes Wise Script mit blauem Hintergrund

Dieses Problem lässt sich umgehen, indem man das WSE-Projekt in einem beliebigen Editor, beispielsweise Notepad, öffnet und folgendes Bit “kippt”:

Wise Script in Notepad

Nachdem die vorletzte “0” in der Zeile “Windows Flags” in “1” geändert wurde, muss das WSE-Projekt gespeichert und erneut mit dem Wise Script Editor kompiliert werden.
Nun läuft die EXE-Datei ohne störenden blauen Hintergrund ab.

Wise Script ohne blauen Hintergrund

Tino John
Member of the Ontrex SPA Team

Einfacher Weg zum LocalLow Verzeichnis

Mit der Einführung der Integrity Access Level (IL) Funktionalität unter Windows Vista und Windows 7, wurde ein neues Verzeichnis, das LocalLow Verzeichnis eingeführt.

Das LocalLow Verzeichnis wir für Prozesse verwendet, die als Low-Level Prozess ausgeübt werden. In der Regel betrifft dies Prozesse, welche unter dem Internet Explorer Prozess gestartet werden, wie das Apple Quicktime Plugin oder Sun Java Runtime Environment. Diese Prozesse können nur noch Dateien in diesem Ordner schreiben oder modifzieren.

Wird eine Applikation repaketiert, welche in diesem Ordner eine Datei erstellt, dann wird schnell klar, dass der Windows Installer Dienst dieses neue Verzeichnis nicht auflöst. Eigentlich gehört das LocalLow Verzeichnis wie die restlichen ‘Special-Folders’ aufgelöst. Das neue Verzeichnis jedoch ist weder in MSI 4.0, 4.5 noch 5.0 Bestandteil der Directory Tabelle.

Es gibt hierzu eine einfache Lösung, wenn Wise Package Studio 7 SP3 oder höher eingesetzt wird. Ab dieser Version von Wise Package Studio wird mit der CustiomAction WiseSetProfilesFolder das Root-Verzeichnis des aktuellen Benutzers aufgelöst (ebenfalls eine Schwachstelle des Windows Installer Dienstes). Aufbauend auf diesem Verzeichnis (ProfileFolder) kann nun mit zwei Einträgen in die Directory Tabelle das LocalLow Verzeichnis dynamisch aufgelöst werden.

 Das LocalLow Verzeichnis

Stefan Hotan
Member of the Ontrex SPA Team

ALLUSERS Profile Auflösung

Das Wise Package Studio bzw. das SetupCapture Tool scheint Files/Ordner welche ins ALLUSERS Profile geschrieben werden nicht richtig aufzulösen (Eine Ausnahme bildet natürlich der CommonAppDataFolder Wert).

Bei einer Installation der repaketierten Applikation werden ohne Änderungen diese ins aktuelle Benutzerprofil des installierenden Users kopiert.

Um diesem Bug entgegen zu wirken baut man am besten folgende CustomAction im Immediate Bereich vor der CostFinalize Aktion ein:


Diese „biegt“ den entsprechenden Directory-Table Eintrag auf die Envirenmontvariable %ALLUSERSPROFILE%, welches in den meisten Fällen ein zufriedenstellendes Resultat produziert.

Doch wieso existiert dieser Bug?

WPS scheint es gut zu meinen, und kreiert ein entsprechenden Eintrag in der Directory Table namens „ALL_USERS“, dieser basiert auf den Werten “ProfilesFolder” & “All Users”.
ProfilesFolder wird aber zur Laufzeit auf das Userprofiles des Benutzers aufgelöst, was natürlich nicht das gewünsche Resultat ist.

Fabio Di Lorenzo
Member of the Ontrex SPA Team