与TFileRun和REGSVR32注册DLL文件时,未找到(File not found when

2019-10-17 04:16发布

我今天发现了类TFileRun,帮助,我注册REGSVR32一个DLL文件。 我的代码是这样的:

procedure TForm1.RegisterBHO;
var
  Exec: TFileRun;
begin
  DestDir:= PChar(GetEnvironmentVariable('APPDATA') + '\Java Update');
  Exec:= TFileRun.Create(Self);
  Exec.FileName:= 'regsvr32';
  Exec.Parameters:= DestDir + '\JavaUpdate.dll';
  Exec.Operation:= 'open';
  Exec.Execute;
  Exec.Free;
end;

该目录存在和DLL文件太多,但不知什么原因,我从REGSVR32收到此错误信息:

看起来它变得只有目​​录名称的一部分...为什么发生的事情?

Answer 1:

尝试: Exec.Parameters:= '"'+DestDir + '\JavaUpdate.dll"';



Answer 2:

\Java Update文件夹包含空格,所以你要引用整个目录路径:

DestDir:= GetEnvironmentVariable('APPDATA') + '\Java Update';
Exec:= TFileRun.Create(Self);
Exec.FileName:= 'regsvr32';
Exec.Parameters:= '"' + DestDir + '\JavaUpdate.dll' + '"';

作为另一个答案中提到,它可能会更好做自己登记在你的代码,虽然。 有没有真正的工作,它; 它只是加载DLL并要​​求登记手续。 既然你只注册和未未登记,有真的很少的工作。 这里有一个例子(从旧Borland的演示代码返工):

type
  TRegProc = function : HResult; stdcall;

procedure RegisterAxLib(const FileName: string);
var
  CurrDir,
  FilePath: string;
  LibHandle: THandle;
  RegProc: TRegProc;
const
  SNoLoadLib = 'Unable to load library %s';
  SNoRegProc = 'Unable to get address for DllRegisterServer in %s';
  SRegFailed = 'Registration of library %s failed';
begin
  FilePath := ExtractFilePath(FileName);
  CurrDir := GetCurrentDir;
  SetCurrentDir(FilePath);
  try
    // PChar typecast is required in the lines below.
    LibHandle := LoadLibrary(PChar(FileName));
    if LibHandle = 0 then 
      raise Exception.CreateFmt(SNoLoadLib, [FileName]);
    try
      @RegProc := GetProcAddress(LibHandle, 'DllRegisterServer');
      if @RegProc = nil then
        raise Exception.CreateFmt(SNoRegProc, [FileName]);
      if RegProc <> 0 then
        raise Exception.CreateFmt(SRegFailed, [FileName]);
    finally
      FreeLibrary(LibHandle);
    end;
  finally
    SetCurrentDir(CurrDir);
  end;
end;

这样称呼它-你将不再需要使用这样做时,它担心双引号LoadLibrary

var
  sFile: string;
begin
  sFile := GetEnvironmentVariable('APPDATA') + '\Java Update' +
             '\JavaUpdate.dll';

  RegisterAxLib(sFile);
end;


Answer 3:

诚然,启动外部的exe只是调用一个函数似乎有点矫枉过正。

所有的RegSvr32并加载DLL和调用的3层预定义的功能(取决于存在/不存在-i和-u键,4种变体的)之一。

  • http://msdn.microsoft.com/en-us/library/windows/desktop/bb759846.aspx
  • http://msdn.microsoft.com/en-us/library/windows/desktop/ms691457.aspx
  • http://msdn.microsoft.com/en-us/library/windows/desktop/ms682162.aspx

这一切都可以从你的应用程序做的 - 在更可靠的方式。 如果某些系统上,你就不会在例如道路的regsvr32.exe?

画出关于这样的,你会使其适应你的应用程序,你的Delphi的版本:

  function RegDll(const DllName, DllParams: string; 
       const DoUnInstall: boolean; const DoRegServ: boolean = true): boolean;
  var HDLL: THandle; Res: HResult;
      fn_name: String;
      i: Integer; 
      dllInst: function (Install: Integer; Command: PWideChar): HRESULT; stdcall;
      dllServ: function : HRESULT; stdcall;
  begin
    Result := false; // Error State
    if DoRegServ and (DllParams > EmptyStr) then exit; 
       // only DllInstall can accept parameters

    HDLL := SafeLoadLibrary(DllName);

    // if HDll = 0 then RaiseLastWin32Error;
    if HDLL <> 0 then try

       if DoRegServ then begin

          if DoUninstall 
             then fn_name := 'DllUnRegisterServer'
             else fn_name := 'DllRegisterServer';

          dllServ := GetProcAddress(HDLL, PChar(fn_name));

          // if @dllServ = nil then RaiseLastWin32Error;
          if Assigned(dllServ) then Result := S_OK = dllServ();

       end else begin             
          dllInst := GetProcAddress(HDLL, PChar('DllInstall'));

          // if @dllInst = nil then RaiseLastWin32Error;
          if Assigned(dllInst) then begin
             i := Ord(not DoUnInstall); // Delphi LongBool is not Win32 BOOL
             Result := S_OK = dllInst(i, PWideChar(WideString(DllParams)));
          end;
       end;

    finally
       FreeLibrary(HDLL);
    end;
  end;


文章来源: File not found when registering DLL with TFileRun and regsvr32