2013-02-11 21 views
7

Próba użycia poniższego podejścia w celu uzyskania szczegółowych informacji na temat zablokowanego pliku.Sprawdzanie, czy plik jest w użyciu i do jakiej aplikacji?

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; 

Ale wywołanie

unkInt.QueryInterface(IID_IFileIsInUse, result) 

zawsze zwraca E_NOINTERFACE.

Platforma: Windows 7 32-bitowy system operacyjny, otwierające pliki tekstowe i pliki .msg.

Sprawdzanie otwierania plików od eksploratora i próby usunięcia. Pokazuje właściwe szczegóły dotyczące aplikacji, w której plik jest otwierany. W mojej aplikacji staram się wyświetlać informacje o aplikacji, w której plik jest otwierany. Ale podczas próby rzutowania wskaźnika na interfejs IFileIsInUse, wywołania nieudane z kodem powrotu E_NOINTERFACE, co oznacza, że ​​obiekt w ROT nie implementuje IFileIsInUse. Pliki AFASIK, MS Office implementują IFileIsInUse

Każdy pomysł, co jest tutaj nie tak?

+0

Podobne pytanie na http://stackoverflow.com/questions/2479733/file-locked-by-which-process, ale dla .NET. Może być pomoc w odpowiedzi na własne pytanie. –

Odpowiedz

7

W rzeczywistości Twój kod działa poprawnie. Problem polega na tym, że programy, które testujesz, naprawdę nie implementują IFileIsInUse. Kiedy system zwraca E_NOINTERFACE, jest on dokładny. Interfejs nie jest zaimplementowany.

Testowałem to z File Is In Use Sample from the SDK. Pliki, które są dodawane do ROT przez tę aplikację, która implementuje IFileIsInUse, zostały pobrane przez twój kod. Z drugiej strony pliki otwarte przez Acrobat 8 ​​i Word 2010 nie były.

Wniosek, który wyciągam z tego, jest następujący: IFileIsInUse jest z zasady dobrym pomysłem, ale nie ma większego znaczenia, jeśli aplikacje go nie obsługują. I wydaje się, że istnieją poważne aplikacje, które tego nie robią.

Jest oczywiste, że będziesz musiał użyć jednego lub więcej innych mechanizmów, aby wykryć, która aplikacja ma zablokowany plik, gdy stwierdzisz, że IFileIsInUse nie jest zaimplementowany.

+0

@Pavan Czy ta pomoc? –

+0

Tak. Dziękuję Ci. Podejście awaryjne służy do pobierania danych, gdy obiekt nie implementuje IFileIsInUse. – Pavan

Powiązane problemy