2009-06-25 5 views
1

Ich möchte ein COM-Objekt in meiner Anwendung verwenden.
Wie kann ich sicherstellen, dass das Objekt in der Maschine registriert ist?C# interop - validate Objekt existiert

Die einzige Lösung, die ich gefunden (auch on SO) war ein Try-Catch-Block um die Initialisierung zu verwenden:

try { 
    Foo.Bar COM_oObject = new Foo.Bar(); 
} catch (Exception ee) { 
    // Something went wrong during init of COM object 
} 

Kann ich es auf andere Weise?
Ich fühle mich falsch, mit einem Fehler umzugehen, indem ich es erwarte und es berichte, ich würde lieber wissen, dass ich scheitern werde und es vermeiden werde, damit anzufangen.

Antwort

6

Sie verwenden die Ausnahme, die den richtigen Weg behandelt: um aus einer bestimmten Situation, von der Sie wissen, wie Sie wiederherstellen können, ordnungsgemäß zu scheitern.

Es gibt kein Problem mit Try-Catch in diesem Fall, aber Sie könnten zumindest genauer zu fangen: ComException.

+0

+1 zum Abfangen der spezifischen Ausnahme, insbesondere für einen Ein-Zeilen-Aufruf an eine gut dokumentierte und stabile API. –

+0

Was meinst du damit, dass es keine Möglichkeit gibt, Ausnahmen zu vermeiden, wenn das Objekt nicht installiert ist? – Dror

1

„Ich seine falsch fühlen mit einem Fehler umgehen, indem sie es erwartet und die Berichterstattung darüber“

Ist es nicht genau der Zweck der Try-Catch? Übrigens, eine Ausnahme tritt auf, wenn etwas wirklich Schlimmes passiert ist, und da es eine ziemlich schlechte Sache ist, dass das COM-Objekt, auf das Sie sich beziehen, nicht registriert ist, deshalb ist eine Ausnahme die perfekte Lösung. Und Sie können eine Ausnahme nicht anders behandeln.

Ich denke, das ist der richtige Weg, es zu tun.

+0

Ausnahmen sind teuer (siehe http://www.codeproject.com/KB/dotnet/When_to_use_exceptions.aspx) - Ich bin auf der Suche nach einem besseren Weg, wenn ich keinen finden kann, werde ich mit dem zufrieden sein bestehender Code. – Dror

1

Wenn Sie die ProgId Ihrer Komponente kennen. Sie könnten diesen Trick versuchen

comType = Type.GetTypeFromProgID(progID,true/*throw on error*/); 
0

Wenn Sie diese viel tun und wünschen Ihnen eine nicht-Ausnahme Wurf Äquivalent hatte, versuchen:

public static class Catching<TException> where TException : Exception 
{ 
    public static bool Try<T>(Func<T> func, out T result) 
    { 
     try 
     { 
      result = func(); 
      return true; 
     } 
     catch (TException x) 
     { 
      // log exception message (with call stacks 
      // and all InnerExceptions) 
     } 

     result = default(T); 
     return false; 
    } 

    public static T Try<T>(Func<T> func, T defaultValue) 
    { 
     T result; 
     if (Try(func, out result)) 
      return result; 

     return defaultValue; 
    } 
} 

Sie also jetzt kann dies tun:

Foo.Bar newObj; 
if (!Catching<ComException>.Try(() => new Foo.Bar(), out newObj)) 
{ 
    // didn't work. 
} 

Oder wenn Sie ein Objekt standardmäßig gespeichert in defaultMyInterface würden Sie eine Schnittstelle zu implementieren, verwenden, wenn es nichts ist besser:

IMyInterface i = Catching<ComException>.Try(() => new Foo.Bar() as IMyInterface, 
              defaultMyInterface); 

Sie können dies auch tun, in einem ganz anderen Szenario:

int queueSize = Catching<MyParsingException> 
    .Try(() => Parse(optionStr, "QueueSize"), 5); 

Wenn Parse wirft ein MyParsingException, queueSize-5 ausfällt, andernfalls wird der zurückgegebene Wert von Parse verwendet wird (oder eine andere Ausnahme pflanzt sich normalerweise, die ist normalerweise, was Sie mit einer unerwarteten Ausnahme wünschen).

Dadurch wird verhindert, dass der Codefluss unterbrochen wird, und die Protokollierungsrichtlinien werden zentralisiert.