7

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

文件是否在使用中

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;

但是调用

unkInt.QueryInterface(IID_IFileIsInUse, result) 

总是返回E_NOINTERFACE

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

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

知道这里有什么问题吗?

4

2 回答 2

7

事实上,您的代码工作正常。问题是您正在测试的程序实际上并没有实现IFileIsInUse。当系统返回时E_NOINTERFACE,它是准确的。接口未实现。

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

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

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

于 2013-02-11T18:02:17.637 回答
0

SysInternals Process Explorer 帮助我删除了一个锁定的 .msg 文件,该文件导致了系统问题,例如锁定桌面。

  • 运行 Process Explorer,使用 Find 菜单,
  • 输入完整路径文件名,
  • 点击搜索。

为了删除锁定的文件,我打开了一个 cmd 窗口并尝试del锁定文件,但删除挂在锁上。

然后我使用 Process Explorer 重新启动持有锁的进程 - Explorer.exe。

然后del顺利完成。

于 2019-11-15T20:03:32.567 回答