检查文件是否正在使用以及哪个应用程序?

Pav*_*van 7 delphi delphi-2009 windows-api-code-pack

尝试使用下面提到的方法来获取有关锁定文件的更多详细信息.

文件正在使用中

function GetFileInUseInfo(const FileName : WideString) : IFileIsInUse;
var
  ROT : IRunningObjectTable;
  mFile, enumIndex, Prefix : IMoniker;
  enumMoniker : IEnumMoniker;
  MonikerType : LongInt;
  unkInt  : IInterface;
begin
  result := nil;

  OleCheck(GetRunningObjectTable(0, ROT));
  OleCheck(CreateFileMoniker(PWideChar(FileName), mFile));

  OleCheck(ROT.EnumRunning(enumMoniker));

  while (enumMoniker.Next(1, enumIndex, nil) = S_OK) do
  begin
    OleCheck(enumIndex.IsSystemMoniker(MonikerType));
    if MonikerType = MKSYS_FILEMONIKER then
    begin
      if Succeeded(mFile.CommonPrefixWith(enumIndex, Prefix)) and
         (mFile.IsEqual(Prefix) = S_OK) then
      begin
       if Succeeded(ROT.GetObject(enumIndex, unkInt)) then
        begin
          if Succeeded(unkInt.QueryInterface(IID_IFileIsInUse, result)) then
          begin
            result := unkInt as IFileIsInUse;
            exit;
          end;
        end;
      end;
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

但呼吁

unkInt.QueryInterface(IID_IFileIsInUse, result) 
Run Code Online (Sandbox Code Playgroud)

总是回来E_NOINTERFACE.

平台:Windows 7 32位操作系统,打开word文件和.msg文件.

检查从资源管理器中打开文件并尝试删除.它显示了有关打开文件的应用程序的正确详细信息.在我的应用程序中,我尝试显示有关打开文件的应用程序的信息.但是当尝试将指针强制转换为IFileIsInUse接口时,QueryInterface调用将失败并返回代码E_NOINTERFACE,这意味着ROT中的对象无法实现IFileIsInUse.AFASIK,MS Office文件实现IFileIsInUse

知道这里有什么问题吗?

Dav*_*nan 7

实际上你的代码运行正常.问题是您正在测试的程序确实没有实现IFileIsInUse.当系统返回时,E_NOINTERFACE它是准确的.该接口未实现.

使用SDK中File Is In Use Sample对此进行了测试.由该应用程序添加到ROT的文件(确实实现)IFileIsInUse由您的代码选取.另一方面,Acrobat 8​​和Word 2010打开的文件不是.

我从中得出的结论IFileIsInUse是原则上这是一个好主意,但如果应用程序不支持它,则没有多大用处.似乎有一些主要的应用程序没有.

很明显,当您发现IFileIsInUse未实现文件时,您将需要使用一个或多个其他机制来检测哪个应用程序已锁定文件.