0

我正在尝试在 Delphi 7 中使用 32 位应用程序删除 64 位注册表项。我编写了以下代码来完成相同的操作,但收到“错误代码 87 - 指定的参数无效”。

Procedure DeleteRegistryKeyEx(RootKey : HKEY; KeyToDelete : String) ;
Var
      DllHandle : THandle;
      RegDeleteKeyExA : Function (Key : HKEY; lpSubKey : LPCTSTR ; samDesired : REGSAM ; reserved : DWORD) : Integer;
     KeyName   ,
     ErrBuff   : Array[0..MAX_PATH] of Char;
 begin
      DllHandle := LoadLibrary(PChar('advapi32.dll')) ;
      KeyName   := #0;
      ErrBuff   := #0;
     Try
           If DllHandle > 0 Then
           Begin
           Try
                RegDeleteKeyExA := GetProcAddress(DllHandle,'RegDeleteKeyExA');
                If @RegDeleteKeyExA <> nil then
                begin
                   ErrCode := -1;
                   StrPCopy(KeyName , '123') ;
                   hKey1 := 0;
                   ErrCode := -1;
               ErrCode := RegOpenKeyEx( HKEY_LOCAL_MACHINE, 'SOFTWARE',
                          0, KEY_ALL_ACCESS Or $0100, hkey1);
                   If ErrCode = 0 Then               
                   Begin
                       ErrCode := -1;
                       ErrCode := RegDeleteKeyExA(hKey1 , KeyName , $0100 , 0);
                       If ErrCode =  ERROR_SUCCESS Then
                          WriteLn('Key deleted by Ex')
                       Else
                       Begin
                        ErrBuff :=#0;
                        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,ErrCode,0, ErrBuff, SizeOf(ErrBuff),nil);
                        //error msg in ErrBuff for error in RegDeleteKeyExA 
                       end;
       End
       Else
       Begin
         ErrBuff := #0;
         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,ErrCode,0, ErrBuff, SizeOf(ErrBuff),nil);
         // Error code in ErrBuff for error in RegopenKeyEx 
       End;

     end
   Except
    On E:Exception Do
   End;
End;
 Finally
  Try
     If DllHandle > 0 Then
       FreeLibrary(DllHandle) ;
  Except

  End;

 End;
 end;

我正在尝试删除“HKLM\Software”下的键“123”。openKey 成功但 DeleteKeyExA 返回错误 87。我不知道我要去哪里。我在 windows 64 位 XP 专业版下测试了这段代码。

提前致谢

4

1 回答 1

5

你有一个调用约定不匹配。该函数必须是stdcall,但您的声明将使用默认register约定。像这样修复它:

RegDeleteKeyExA: function(Key: HKEY; lpSubKey: LPCTSTR; samDesired: REGSAM;
    reserved: DWORD): Integer; stdcall;

我对您的代码还有其他一些评论,您可以接受或离开。

>0与其检查模块句柄,不如检查<>0. 模块句柄应声明为HMODULE而不是THandle. 后者是你关闭的东西,CloseHandle模块句柄不是这样的东西。

我认为代码将受益于常量的声明:

const
  KEY_WOW64_64KEY = $0100;

对于文本参数,我会将它们声明为字符串,并使用 aPChar来获取指向以空字符结尾的字符串的指针。

var
  KeyName: string;
....
KeyName := '123';
....
ErrCode := RegDeleteKeyExA(hKey1, PChar(KeyName), KEY_WOW64_64KEY, 0);
于 2013-08-03T10:57:35.007 回答