Winapi 实施IFileIsInUse

Winapi 实施IFileIsInUse,winapi,com,Winapi,Com,我正在尝试在我的Delphi程序中实现IFileUseCOM接口,以便Windows资源管理器在锁定文件时可以显示有关我的应用程序的更多详细信息。 我的代码基于来自Microsoft()的FileIsUse示例,并且达到以下目标: type TFileIsInUseImpl = class(TInterfacedObject, IUnknown, IFileIsInUse) protected function GetAppName(out ppszName: LPWSTR) :

我正在尝试在我的Delphi程序中实现
IFileUse
COM接口,以便Windows资源管理器在锁定文件时可以显示有关我的应用程序的更多详细信息。 我的代码基于来自Microsoft()的FileIsUse示例,并且达到以下目标:

type
  TFileIsInUseImpl = class(TInterfacedObject, IUnknown, IFileIsInUse)
  protected
    function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
    function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
    function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
    function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
    function CloseFile() : HRESULT; stdcall;
  public
    constructor Create(const AFileName: string);
  end;

procedure RegisterFileIsInUse(const AFileName: string);
var
  Cookie: Longint;
  rot: IRunningObjectTable;
  hr: HRESULT;
  mk: IMoniker;
  FileIsInUse: IFileIsInUse;
begin
  hr := GetRunningObjectTable(0, rot);
  if SUCCEEDED(hr) then
  begin
    hr := CreateFileMoniker(PChar(AFileName), mk);
    if SUCCEEDED(hr) then
    begin
      FileIsInUse := TFileIsInUseImpl.Create(AFileName);

      hr := rot.Register(ROTFLAGS_REGISTRATIONKEEPSALIVE or ROTFLAGS_ALLOWANYCLIENT, FileIsInUse, mk, Cookie);
      if hr = CO_E_WRONG_SERVER_IDENTITY then
        hr := rot.Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, FileIsInUse, mk, Cookie);
      if SUCCEEDED(hr) then
        FRegisteredFiles.Add(AFileName, TRegisteredFile.Create(Cookie, FileIsInUse));
    end;
  end;
end;
我在
HKEY_CLASSES\u ROOT\AppID\MyApp.exe
HKEY_CLASSES\u ROOT\AppID\{MyGUID}
中添加了注册表信息,以指示
RunAs=Interactive user
,这样对
rot.Register
的第一次调用就成功了
ROTFLAGS\u ALLOWANYCLIENT

但是,从未调用过我的
TFileIsInUseImpl
方法。 重写它的
QueryInterface
时,我发现它确实会被调用,但只用于封送相关接口,而不会用于
iFleisinuse

环顾四周,我得出的结论是,有些东西并没有按照我的应用程序中应有的方式初始化,但我不明白为什么。 我已经试过了:

  • 调用
    coinitializex(nil,COINIT\u多线程)
    而不是默认的
    CoInitialize(nil)
  • 添加
    HKEY\u CLASSES\u ROOT\CLSID\{MyGuid}\InProcServer32\ThreadingModel=Both
但没有任何帮助。考虑到微软的示例是一个独立的应用程序,我应该能够复制它的功能


你们谁能告诉我我做错了什么吗?

如果代码的构建与MSDN示例类似,那么它就可以正常工作。可以从代码库下载示例代码:

缺陷链接:

新链接:
从Windows 7 SDK下载:

您在32位或64位注册表配置单元中注册了它吗?除非我大错特错,否则HKCR在32位和64位之间没有虚拟化。我通过HKLM查看了这两个视图,它们完全相同。如果您看到IMarshal的QI,但从未使用过iFiliseInUse,那么您确实存在封送问题。您应该看到资源管理器正在查找ProxyStubClsId32的接口注册表项。使用SysInternals的ProcMon查看。@OBones:HKCR本身是一个“虚拟”文件夹(请参阅:),是16位应用程序的主要文件夹…(请参阅:)请将其注册到
HKEY\U CURRENT\u USER\Software\Classes
@OBones:MSDN示例适用于您吗?它也可以在Windows7SDK中使用!