2013-02-11 118 views
7

试图使用下面提到的方法来获取有关锁定文件的更多详细信息。检查文件是否正在使用以及按哪个应用程序?

Is file in use

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,微软Office文件执行IFileIsInUse

任何想法这里有什么错?

+0

类似的问题在http://stackoverflow.com/questions/2479733/file-locked-by-which-process,但对于.NET。可能有助于回答你自己的问题。 – 2013-02-11 15:47:57

回答

7

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

我测试了这个与File Is In Use Sample from the SDK。通过该应用程序添加到ROT的文件(实现IFileIsInUse)已由您的代码拾取。另一方面,Acrobat 8​​和Word 2010打开的文件不是。

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

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

+0

@Pavan对此有帮助吗? – 2013-02-12 19:08:14

+0

是的。谢谢。当对象没有实现IFileIsInUse时,使用回退方法来获取数据。 – Pavan 2013-02-20 19:44:20

相关问题