How i can retrieve the error description for a Win

2019-04-06 14:56发布

问题:

I need to obtain the description of an WinInet function error code, The MSDN documentation about the WinInet functions says which I must use the GetLastError function to retrieve the last error code when a functions fails. Now when I check the documentation about the GetLastError function says .

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

I check which the SysErrorMessage delphi function internally calls the FormatMessage winapi function, so i am using that function to retrieve the error description, but is not working (I mean does not return a description for a WinInet error code) I tested this code in Delphi 2007 and Delphi XE.

See this code

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.

when I execute this code returns the code 12006 which is defined as ERROR_INTERNET_UNRECOGNIZED_SCHEME and the description associated is The URL scheme could not be recognized or is not supported.

So the question is How I can retrieve the error description for the WinInet error codes in delphi?

回答1:

I think you should try to use FormatMessage directly, because you need to tell from where the error code is originated. I have found this working code.

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;

You should make some changes, probably use 'wininet.dll' instead of Advapi32.dll, but it should work.

UPDATE

This is the version for WinInet functions

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;


回答2:

To me the error looks OK - I don't know any URL scheme called "foo" :)

Try something like "http://foo.bar" as URL to see do you get some other error message.