Автоматизация COM в Internet Explorer: преобразование числового кода ошибки в строку - PullRequest
1 голос
/ 25 августа 2009

Я пишу некоторый код для управления Internet Explorer из программы Perl 5 через Win32::OLE, и я ищу способы преобразования числовых кодов состояния / ошибок, которые доставляются обратно в программу Perl через события (такие как NavigateError) в несколько более удобочитаемой форме.

Существует ли какая-то библиотечная функция, которая преобразует, например, 0x800C0005L или -2146697211 в "INET_E_RESOURCE_NOT_FOUND" или что-то еще более читабельное?

Я пробовал Win32::FormatMessage(), но, похоже, это работает только для условий, не связанных с приложением.

Обновление: Вот пример кода для пояснения. Какой-то тест вывод показан ниже.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Time::HiRes qw(sleep time);
use Win32::OLE qw(EVENTS);
use Win32::OLE::Variant;

$|++;

sub ie_browse {
    my $url = shift;
    my $ie = Win32::OLE->new('InternetExplorer.Application') or die;
    Win32::OLE->WithEvents($ie, 
        sub {
            my ($obj, $event, @args) = @_;
            given ($event) {
                when ('NavigateComplete2') {
                    push @extra, 
                      'url='.($args[1]->As(VT_BSTR));
                    say "$event: @extra";
                }
                when ('NavigateError') {
                    push @extra, 
                      'url='.($args[1]->As(VT_BSTR)),
                      'statuscode='.($args[3]->As(VT_I4));
                    say "$event: @extra";
                }
            }
        }, 'DWebBrowserEvents2');
    Win32::OLE->SpinMessageLoop;
    $ie->{visible} = 1;
    Win32::OLE->SpinMessageLoop;
    $ie->Navigate2($url);
    Win32::OLE->SpinMessageLoop;
    while(1) {
        Win32::OLE->SpinMessageLoop;
        sleep(0.1);
    }
}

ie_browse $ARGV[0];

Вот некоторые результаты для двух попыток получения. Извлечение переполнения стека страница успешно, конечно.

C:\Documents and Settings\nobody\Desktop>perl ie.pl http://stackoverflow.com/
NavigateComplete2: url=http://stackoverflow.com/
Terminating on signal SIGINT(2)

Но example.invalid не существует.

C:\Documents and Settings\nobody\Desktop>perl ie.pl http://example.invalid/
NavigateError: url=http://example.invalid/ statuscode=-2146697211
NavigateComplete2: url=http://example.invalid/
Terminating on signal SIGINT(2)

Мне интересно преобразовать это числовое значение (-2146697211), которое было вернулся во что-то полезное. Это не ошибка OLE как таковая, а условие ошибки сигнализируется COM-объектом Internet Explorer.

1 Ответ

4 голосов
/ 25 августа 2009

Обновление: В свете вашего комментария, я полагаю, вы ищете документацию Microsoft для события NavigateError:

INET_E_INVALID_URL (0x800C0002L or -2146697214)
INET_E_NO_SESSION (0x800C0003L or -2146697213)
INET_E_CANNOT_CONNECT (0x800C0004L or -2146697212)
...

Вы можете создать модуль, проанализировав этот список:

package Win32::WebBrowserControl::ErrorMnemonics;

use strict;
use warnings;

my %lookup;

sub import {
    my $class = shift;
    while ( my $x = <DATA> ) {
        my ($mnemonic, $code) = ( $x =~ m{
            ^(INET_E_[A-Z_]+)
            [ ]
            \(
                0x[[:xdigit:]]+L
                [ ] or [ ]
                (-[[:digit:]]+)
            \)
        }x ) or next;
        $lookup{$code} = $mnemonic;
    }
}

sub lookup {
    my $self = shift;
    return $lookup{shift()};
}

1;
__DATA__
INET_E_INVALID_URL (0x800C0002L or -2146697214)
INET_E_NO_SESSION (0x800C0003L or -2146697213)
INET_E_CANNOT_CONNECT (0x800C0004L or -2146697212)
INET_E_RESOURCE_NOT_FOUND (0x800C0005L or -2146697211)
INET_E_OBJECT_NOT_FOUND (0x800C0006L or -2146697210)
INET_E_DATA_NOT_AVAILABLE (0x800C0007L or -2146697209)
INET_E_DOWNLOAD_FAILURE (0x800C0008L or -2146697208)
INET_E_AUTHENTICATION_REQUIRED (0x800C0009L or -2146697207)
INET_E_NO_VALID_MEDIA (0x800C000AL or -2146697206)
INET_E_CONNECTION_TIMEOUT (0x800C000BL or -2146697205)
INET_E_INVALID_REQUEST (0x800C000CL or -2146697204)
INET_E_UNKNOWN_PROTOCOL (0x800C000DL or -2146697203)
INET_E_SECURITY_PROBLEM (0x800C000EL or -2146697202)
INET_E_CANNOT_LOAD_DATA (0x800C000FL or -2146697201)
INET_E_CANNOT_INSTANTIATE_OBJECT (0x800C0010L or -2146697200)
INET_E_REDIRECT_FAILED (0x800C0014L or -2146697196)
INET_E_REDIRECT_TO_DIR (0x800C0015L or -2146697195)
INET_E_CANNOT_LOCK_REQUEST (0x800C0016L or -2146697194)
INET_E_USE_EXTEND_BINDING (0x800C0017L or -2146697193)
INET_E_TERMINATED_BIND (0x800C0018L or -2146697192)
INET_E_INVALID_CERTIFICATE (0x800C0019L or -2146697191)
INET_E_CODE_DOWNLOAD_DECLINED (0x800C0100L or -2146696960)
INET_E_RESULT_DISPATCHED (0x800C0200L or -2146696704)
INET_E_CANNOT_REPLACE_SFP_FILE (0x800C0300L or -2146696448)
INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY (0x800C0500L or -2146695936)
INET_E_CODE_INSTALL_SUPPRESSED (0x800C0400L or -2146696192)

Относительно ошибок, связанных с OLE, см. Документацию Win32::OLE:

Win32::OLE->LastError()

Метод класса LastError() возвращает последняя зарегистрированная ошибка OLE. Это двойное значение, как переменная $!: в числовой контекст возвращает ошибку число и в контексте строки это возвращает сообщение об ошибке. Ошибка число является подписанным значением HRESULT. Пожалуйста, используйте функцию HRESULT(ERROR) преобразовать шестнадцатеричное без знака константа со знаком HRESULT.

...