COM-ErrorCode abfragen

Wer häufiger mit COM-Objekten arbeitet, möchte hin und wieder den ErrorCode abfragen, den ein solches COM-Objekt immer dann liefert, wenn die Operation aus irgendeinem Grund fehlschlägt. Wie es aussieht, ist es gar nicht so einfach an diesen ErrorCode heranzukommen. Hier erst einmal ein einfaches Beispiel:

$GPMT = new-object -com GPMGMT.GPM
$GPMT.GetDomain(„GibtEsNicht.de“, $Null, 1)

Zuerst wird die Gruppenrichtlinien-Komponente GPMGMT.GPM instanziert, anschließend wird eine Domäne angesprochen, die es nicht gibt. Das Ergebnis ist eine COM-Exception, deren ErrorCode (HResult) 0x8007054B lautet. Die Frage ist, wie sich dieser Errorcode abfragen lässt. Theoretisch über das Exception-Objekt, doch wie ein

$Error[0].Exception.GetType().Name

verrät, ist es eine MethodInvocationException und keine COMException. Diese wird erst über die GetBaseException-Methode geliefert:

$Error[0].Exception.GetBaseException().Errorcode

-2147023541

Und wie macht man noch einmal aus einer Integer-Zahl eine Hexadezimalzahl? Zum Beispiel über ein

[Convert]::ToString($ErrorCode,16)

oder

„{0:x}“ -f $ErrorCode

Ein Trap-Befehl, der diese Ausnahme abfängt und den Fehlercode ausgibt könnte wie folgt aussehen:

trap [System.Management.Automation.MethodInvocationException] { $ErrorCode = ($_.Exception.GetBaseException()).ErrorCode; „Errorcode: {0:x}“ -f $ErrorCode;Continue}
$GPMT = new-object -com GPMGMT.GPM
$GPMT.GetDomain(„GibtEsNicht.de“, $Null, 1)

Aus Gründen, die ich im Moment leider nicht im Detail nachvollziehen kann, lässt sich mit dem Trap-Befehl nicht direkt auf die System.Runtime.InteropServices.COMException prüfen. Außerdem muss die inner Exception über GetBaseException() und nicht über InnerException abgefragt werden

Das sind Details, die ich gerne Mal bei Gelegenheit von einem COM-Experten erklären lasse. Für den Moment gilt die Devise, dass wenn es funktioniert, wann nicht immer über die genauen Gründe philosophieren sollte.

Advertisements

Eine Antwort zu “COM-ErrorCode abfragen

  1. Meiner Treu, das hat mich Zeit gekostet! Ich wusste gar nicht, dass der Errorcode von InvocationException und der Errorcode von COMException ein und die gleiche Zahl ist. Danke für den Tipp!

    Das mit der GetBaseException verstehe ich auch nicht.

    Ich versuche gerade, die Windows-KMS-Aktivierung von VBScript auf Powershell umzustellen, und den Errorcode brauche ich zum Trappen, falls was schief läuft. Wen’s interessiert – Aktivierung von Vista, Win7 und WinServer 2008 über KMS, Umstellung von Slmgr.vbs auf Powershell:

    trap [System.Management.Automation.CmdletInvocationException]
    {
    $ErrorCode = ($_.Exception.GetBaseException()).ErrorCode
    $ErrorCodeHex=„{0:x}“ -f $ErrorCode
    if($ErrorCodeHex=“C004F039″)
    {
    Write-Warning „The computer could not be activated. The Key Management Service could not be reached.“
    }
    elseif ($ErrorCodeHex=“C004F038″)
    {
    Write-Warning „The computer could not be activated. The returned count from your Key Management Service is insufficient.“
    }
    else
    {
    Write-Warning „Activation failed with error code “ + $ErrorCodeHex + „. Please visit http://support.microsoft.com/kb/938450 for a list of error codes.“
    }
    break;
    }
    $softwarelicensingproduct=get-wmiobject softwarelicensingproduct -filter „PartialProductKey IS NOT NULL“ | ForEach-Object { $_.activate() }

Kommentar verfassen

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s