C # interop - валидация объекта существует - PullRequest
1 голос
/ 25 июня 2009

Я хотел бы использовать COM-объект в своем приложении.
Как я могу убедиться, что объект зарегистрирован в машине?

Единственное решение, которое я нашел (также на SO ), - это использовать блок try-catch вокруг инициализации:

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

Могу ли я сделать это любым другим способом?
Я чувствую, что неправильно иметь дело с ошибкой, ожидая ее и сообщая об этом, я бы предпочел знать, что потерплю неудачу, и избегать ее с самого начала.

Ответы [ 4 ]

6 голосов
/ 25 июня 2009

Вы используете обработку исключений правильным способом: изящно провалиться из конкретной ситуации, из которой вы знаете, как восстановиться.

В этом случае нет проблем с использованием try-catch, но вы можете по крайней мере поймать более конкретно: ComException.

1 голос
/ 25 июня 2009

Если вы знаете ProgId вашего компонента. Вы можете попробовать этот трюк

comType = Type.GetTypeFromProgID(progID,true/*throw on error*/);
1 голос
/ 25 июня 2009

«Я чувствую, что неправильно иметь дело с ошибкой, ожидая ее и сообщая об этом»

Разве это не цель try-catch? Кстати, Исключение возникает, когда происходит что-то действительно плохое, и, поскольку довольно плохо, что COM-объект, на который вы ссылаетесь, не зарегистрирован, следовательно, Исключение является идеальным решением. И вы не можете обработать исключение любым другим способом.

Я думаю, что это правильный способ сделать это.

0 голосов
/ 25 июня 2009

Если вы делаете это много и хотите, чтобы у вас был эквивалентный бросок без исключения, попробуйте:

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;
    }
}

Так что теперь вы можете сделать это:

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

Или, если у вас есть объект по умолчанию, хранящийся в defaultMyInterface, вы бы использовали его для реализации интерфейса, если нет ничего лучше:

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

Вы также можете сделать это в совершенно другом сценарии:

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

Если Parse выдает MyParsingException, queueSize будет по умолчанию равным 5, в противном случае используется возвращаемое значение из Parse (или любое другое исключение будет распространяться нормально, что обычно является тем, что вы хотите с неожиданное исключение).

Это помогает избежать нарушения потока кода, а также централизует вашу политику ведения журналов.

...