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

发布于 2024-08-02 19:38:06 字数 2353 浏览 6 评论 0原文

我正在编写一些代码,用于通过 Win32:: 从 Perl 5 程序驱动 Internet Explorer OLE,我正在寻找方法来转换通过事件传递回 Perl 程序的数字状态/错误代码(例如 NavigateError) 转换为更易于理解的形式。

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

I am writing some code for driving Internet Explorer from a Perl 5 program through Win32::OLE, and I am looking for ways to convert numeric status/error codes that are delivered back to the Perl program via events (such as NavigateError) into a somewhat more human-readable form.

Is there some kind of library function that converts i.e. 0x800C0005L or -2146697211 to "INET_E_RESOURCE_NOT_FOUND" or something even more readable?

I have tried Win32::FormatMessage(), but that seems to work only for non application-specific error conditions.

Update: Here is some example code for clarification. Some test
output is shown below.

#!/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];

Here is some output for two fetch attempt. Fetching the Stack Overflow
page is successful, of course.

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

But example.invalid doesn't exist.

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)

I am interested in turning that numeric value (-2146697211) that has been
passed back into something useful. This is not an OLE error as such but an error condition
signaled by the Internet Explorer COM object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓦然回首 2024-08-09 19:38:06

更新:根据您的评论,我相信您正在寻找有关 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 错误。这是一个
双值,如 $! 变量:在
数字上下文它返回错误
数字和字符串上下文中的它
返回错误消息。错误
number 是带符号的 HRESULT 值。
请使用HRESULT(ERROR)函数
转换无符号十六进制
常量为有符号的 HRESULT

Update: In light of your comment, I believe you are looking for Microsoft's documentation on the NavigateError event:

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

You could create a module by parsing this list:

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)

For OLE related errors, see the Win32::OLE documentation:

Win32::OLE->LastError()

The LastError() class method returns
the last recorded OLE error. This is a
dual value like the $! variable: in a
numeric context it returns the error
number and in a string context it
returns the error message. The error
number is a signed HRESULT value.
Please use the HRESULT(ERROR) function
to convert an unsigned hexadecimal
constant to a signed HRESULT.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文