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 ビット OS、word ファイルと .msg ファイルを開く。

エクスプローラーからファイルを開いて削除しようとすることを確認しました。ファイルが開かれているアプリケーションに関する適切な詳細が表示されます。私のアプリケーションでは、ファイルが開かれているアプリケーションに関する情報を表示しようとしています。しかし、ポインターをIFileIsInUseインターフェイスにキャストしようとすると、QueryInterface呼び出しが戻りコードE_NOINTERFACEで失敗します。これは、ROT のオブジェクトが実装されていないことを意味しますIFileIsInUse。AFASIK、MS Office ファイルの実装IFileIsInUse

ここで何が間違っているのですか?

4

2 に答える 2

7

実際、コードは正常に機能します。問題は、テスト対象のプログラムが実際には実装されていないことIFileIsInUseです。システムが戻るとき、E_NOINTERFACEそれは正確です。インターフェイスは実装されていません。

SDKのFileIsInUseサンプルを使用してこれをテストしました。を実装するそのアプリケーションによってROTに追加されたファイルはIFileIsInUse、コードによって取得されました。一方、Acrobat8とWord2010で開かれたファイルはそうではありませんでした。

私がこれから導き出した結論は、それIFileIsInUseは原則としては良い考えですが、アプリケーションがそれをサポートしていない場合はあまり使用されないということです。そして、そうでない主要なアプリケーションがあるようです。

他のメカニズムの1つ以上を使用して、ファイルIFileIsInUseが実装されていないことがわかったときに、どのアプリケーションでファイルがロックされているかを検出する必要があることは明らかです。

于 2013-02-11T18:02:17.637 に答える