代码之家  ›  专栏  ›  技术社区  ›  hillu

Internet Explorer COM自动化:将数字错误代码转换为字符串

  •  1
  • hillu  · 技术社区  · 15 年前

    我正在编写一些代码,用于将Internet Explorer从Perl5程序驱动到 Win32::OLE 我正在寻找通过事件(例如 NavigateError )变成一种更具人类可读性的形式。

    是否有某种库函数可以将0x800c005l或-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错误,而是一个错误条件 由Internet Explorer COM对象发出信号。

    1 回复  |  直到 15 年前
        1
  •  4
  •   Sinan Ünür    15 年前

    更新: 鉴于您的评论,我相信您正在寻找有关 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) 功能 转换无符号十六进制 常量到有符号 结果 .