简体   繁体   中英

DLL registration with regsvr32.exe freezes when unit HtmlHelpViewer is used in Delphi XE or Delphi XE2

DLL registration with regsvr32.exe freezes when unit HtmlHelpViewer is used in DLL sources in Delphi XE or Delphi XE2 Update 3. Just add the unit to interface uses list. The main project (that uses DLL) freezes on exit too.

How to fix the issue?

Thanks for the help!

STEPS TO REPRODUCE THE ISSUE AND ISSUE IN SUGGESTED FIX:

1). Please create the following DLL:

library Test;

uses
  ComServ,
  HtmlHelpFixer,
  HtmlHelpViewer;

exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;

begin
end.

2). Also create the following BPL linked to this DLL (by -LUTestBpl dcc32 parameter for example):

package TestBpl;

requires
  Vcl;

end.

3). Then just execute: regsvr32.exe /s Test.dll . OS Windows 7 32-bit.

Update

According to the latest comments on the QC report submitted by Altaveron, this problem will be resolved in the next Delphi update, update 4. And indeed, Altaveron now confirms that update 4 does resolve the issue.


This is a known problem with the MS HTML help control, hhctrl.ocx. The best description of it that I am aware of is at the HelpWare FAR HTML FAQ. There are many QC reports describing the issue: 48983 , 67463 , 78998 , 89616 .

According to the latest QC report, this is fixed in XE2 but you report otherwise and I'd be inclined to believe you. Especially as a comparison of the source for the HtmlHelpViewer unit from XE and XE2 reveals no changes that appear related to this issue.

It's quite hard to work around the issue since the code that needs to be modified is buried deep inside the HtmlHelpViewer unit. I've had to resort to patching the HtmlHelp API call. Like this:

unit HtmlHelpFixer;

interface

implementation

uses
  Windows;

function HtmlHelp(hWndCaller: HWND; pszFile: PWideChar; uCommand: UINT; dwData: DWORD): HWND;
begin
  if uCommand=HH_CLOSE_ALL then begin
    //don't call HtmlHelpW because it can result in a hang due to a bug in hhctrl.ocx
    Result := 0;
  end else begin
    Result := HtmlHelpW(hWndCaller, pszFile, uCommand, dwData);
  end;
end;

procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
  OldProtect: DWORD;
begin
  if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then begin
    Move(NewCode, Address^, Size);
    FlushInstructionCache(GetCurrentProcess, Address, Size);
    VirtualProtect(Address, Size, OldProtect, @OldProtect);
  end;
end;

type
  PInstruction = ^TInstruction;
  TInstruction = packed record
    Opcode: Byte;
    Offset: Integer;
  end;

procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
  NewCode: TInstruction;
begin
  NewCode.Opcode := $E9;//jump relative
  NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
  PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;

procedure RedirectHtmlHelp;
var
  HtmlHelp: function(hWndCaller: HWND; pszFile: PWideChar; uCommand: UINT; dwData: DWORD_PTR): HWND;
begin
  HtmlHelp := Windows.HtmlHelp;
  RedirectProcedure(@HtmlHelp, @HtmlHelpFixer.HtmlHelp);
end;

initialization
  RedirectHtmlHelp;

end.

Include this unit early in your .dpr uses list, before any unit that does anything with HTML help.

The version of the code that I use does a little more and takes steps to ensure that any open help windows are closed when the DLL unloads. This no longer happens because we have stopped sending HH_CLOSE_ALL .

You will want to make sure that any help windows are shut down then keep track of the window handles returned by HtmlHelp calls, which you can now intercept. Then at shutdown send a WM_CLOSE message to those windows which replaces the missing HH_CLOSE_ALL call to HtmlHelp .

However, I believe that the code above should get you over your immediate hurdle with regsvr32 which won't be showing help windows.

Feel free to do some experimentation! At the very least, the code above gives you entry points with which you can modify the behaviour of the HtmlHelpViewer unit.

Embarcadero已在Delphi XE2 Update 4上解决了此问题。但是,当您将BPL与using子句中的HtmlHelpViewer单元一起使用时,上下文帮助在IDE上不起作用。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM