2011-07-07 81 views
8

我需要獲取WinInet函數錯誤代碼的說明,有關WinInet函數的MSDN文檔說明我必須使用GetLastError函數檢索上次錯誤一個函數失敗時的代碼。現在,當我檢查關於GetLastError函數的文檔說。我如何檢索來自delphi的WinInet錯誤代碼的錯誤描述

.To obtain an error string for system error codes, use the FormatMessage function

我檢查其SysErrorMessage Delphi函數內部調用FormatMessage WINAPI功能,所以我用這個函數來檢索錯誤的描述,但不工作(我的意思是一個WinInet錯誤代碼不會返回說明)我在Delphi 2007和Delphi XE中測試了這個代碼。

看到這個代碼

uses 
    Wininet, Windows, SysUtils; 


procedure TestWinInet(const AUrl : string); 
var 
    hInter,hRemoteUrl : HINTERNET; 
    Code : Cardinal; 
begin 

    hInter := InternetOpen(PChar('Explorer 5.0'), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); 
    if hInter=nil then 
    begin 
    Code:=GetLastError; 
    raise Exception.Create(Format('Error %d Description %s',[Code,SysErrorMessage(Code)])); 
    end; 

    try 
    hRemoteUrl := InternetOpenUrl(hInter, PChar(AUrl), nil, 0, INTERNET_FLAG_RELOAD, 0); 
    if hRemoteUrl=nil then 
    begin 
     Code:=GetLastError; 
     raise Exception.Create(Format('Error %d Description %s',[Code,SysErrorMessage(Code)])); 
    end; 

    try 
     //do something else 


    finally 
    InternetCloseHandle(hRemoteUrl); 
    end; 
    finally 
    InternetCloseHandle(hInter); 
    end; 
end; 

begin 
    try 
     //i am passing a invalid url just to raise the error 
    TestWinInet('Foo'); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 

當我執行這個代碼返回代碼12006定義爲ERROR_INTERNET_UNRECOGNIZED_SCHEME和相關的描述是The URL scheme could not be recognized or is not supported.

所以,問題是How I can retrieve the error description for the WinInet error codes in delphi?

+0

不是解決問題的解決方案,但你可以使用RaiseLastOSError,而不是'代碼:= GetLastError函數;提出Exception.Create(格式('錯誤%d說明%s',[代碼,SysErrorMessage(代碼)]));' –

+0

@Gerry,謝謝,但我試過你的建議,並沒有檢索任何關於錯誤的描述。 – Salvador

回答

10

我想你應該嘗試直接使用FormatMessage,因爲你需要告訴錯誤代碼來自哪裏。我找到了這個工作代碼。

class function TCertificateManager.GetLastErrorText: string; 
var 
    code: DWORD; 
    Len: Integer; 
    Buffer: array[0..255] of Char; 
begin 
    code := GetLastError(); 
    Len := FormatMessage(FORMAT_MESSAGE_FROM_HMODULE or FORMAT_MESSAGE_FROM_SYSTEM, 
    Pointer(GetModuleHandle('Advapi32.dll')), code, 0, Buffer, SizeOf(Buffer), nil); 
    while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len); 
    SetString(Result, Buffer, Len); 
end; 

您應該進行一些更改,可能使用'wininet.dll'而不是Advapi32.dll,但它應該可以工作。

UPDATE

這是版本的WinInet函數

function GetWinInetError(ErrorCode:Cardinal): string; 
const 
    winetdll = 'wininet.dll'; 
var 
    Len: Integer; 
    Buffer: PChar; 
begin 
    Len := FormatMessage(
    FORMAT_MESSAGE_FROM_HMODULE or FORMAT_MESSAGE_FROM_SYSTEM or 
    FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_ARGUMENT_ARRAY, 
    Pointer(GetModuleHandle(winetdll)), ErrorCode, 0, @Buffer, SizeOf(Buffer), nil); 
    try 
    while (Len > 0) and {$IFDEF UNICODE}(CharInSet(Buffer[Len - 1], [#0..#32, '.'])) {$ELSE}(Buffer[Len - 1] in [#0..#32, '.']) {$ENDIF} do Dec(Len); 
    SetString(Result, Buffer, Len); 
    finally 
    LocalFree(HLOCAL(Buffer)); 
    end; 
end; 
+0

非常感謝這項工作的完美。 – Salvador

+0

@ErvinS,我更新了你的答案,添加了我使用的功能,以幫助其他用戶使用同一個問題。 :)和+1回答 – RRUZ

+0

示例用法存在於程序THTTPReqResp.RaiseCheck(ErrCode:DWORD; ShowSOAPAction:Boolean)中的Soap.SOAPHTTPTrans.pas中;和Datasnap.Win.SConnect in procedure TWebConnection.Check(Error:Boolean); –

-3

對我來說,錯誤看起來不錯 - 我不知道任何稱爲「foo」的URL方案:)

嘗試一下l ike「http://foo.bar」作爲URL來查看你是否收到其他錯誤信息。

+0

問題不在於錯誤。問題是我無法檢索錯誤描述。 – Salvador