2009-08-25 52 views
1

我正在編寫一些代碼,用於通過Win32::OLE從Perl 5程序中驅動Internet Explorer,並且我正在尋找將數字狀態/錯誤代碼轉換回Perl程序通過事件(例如NavigateError)變成更人性化的形式。Internet Explorer COM自動化:將數字錯誤代碼轉換爲字符串

是否有某種庫函數可以將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對象發送的錯誤條件 。

+0

@hillu謝謝。我仍然對此感到惱火。必須有一個API在某個地方。 – 2009-08-26 11:05:49

回答

4

更新:在您的評論來看,我相信你正在尋找微軟的文檔在NavigateError事件:

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) 

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

你可以通過分析該列表創建模塊

有關OLE相關錯誤,請參閱Win32::OLE文檔:

Win32::OLE->LastError()

LastError()類方法返回 最後記錄的OLE錯誤。這是一個 雙值,如$!變量:在 數字上下文中,它返回錯誤 數字,並在字符串上下文中返回錯誤消息 。錯誤號碼 是已簽署的HRESULT值。 請使用HRESULT(ERROR)函數 將無符號十六進制數 常量轉換爲有符號的HRESULT

+0

我在找的不是一個與OLE相關的錯誤代碼。 – hillu 2009-08-25 20:13:54

+0

對於從文檔生成常量的想法+1。 – hillu 2009-08-26 08:04:01