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