2013-02-11 126 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

相關問題