title: Implementing IFileIsInUse
body: <p>I'm trying to implement the <code>IFileIsUse</code> COM interface in my Delphi program so that Windows Explorer can show more details about my application when it locks a file.
  I based my code on the FileIsUse sample from Microsoft (<a href="http://msdn.microsoft.com/en-us/library/ee330722%28VS.85%29.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ee330722%28VS.85%29.aspx</a>) and am up to this:</p>
  
  <pre><code>type
    TFileIsInUseImpl = class(TInterfacedObject, IUnknown, IFileIsInUse)
    protected
      function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
      function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
      function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
      function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
      function CloseFile() : HRESULT; stdcall;
    public
      constructor Create(const AFileName: string);
    end;
  
  procedure RegisterFileIsInUse(const AFileName: string);
  var
    Cookie: Longint;
    rot: IRunningObjectTable;
    hr: HRESULT;
    mk: IMoniker;
    FileIsInUse: IFileIsInUse;
  begin
    hr := GetRunningObjectTable(0, rot);
    if SUCCEEDED(hr) then
    begin
      hr := CreateFileMoniker(PChar(AFileName), mk);
      if SUCCEEDED(hr) then
      begin
        FileIsInUse := TFileIsInUseImpl.Create(AFileName);
  
        hr := rot.Register(ROTFLAGS_REGISTRATIONKEEPSALIVE or ROTFLAGS_ALLOWANYCLIENT, FileIsInUse, mk, Cookie);
        if hr = CO_E_WRONG_SERVER_IDENTITY then
          hr := rot.Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, FileIsInUse, mk, Cookie);
        if SUCCEEDED(hr) then
          FRegisteredFiles.Add(AFileName, TRegisteredFile.Create(Cookie, FileIsInUse));
      end;
    end;
  end;
  </code></pre>
  
  <p>I added registry infos in both <code>HKEY_CLASSES_ROOT\AppID\MyApp.exe</code> and <code>HKEY_CLASSES_ROOT\AppID\{MyGUID}</code> to indicate <code>RunAs=Interactive user</code> so that the first call to <code>rot.Register</code> succeeds with <code>ROTFLAGS_ALLOWANYCLIENT</code></p>
  
  <p>However, none of my <code>TFileIsInUseImpl</code> methods are ever called.
  Overriding <code>QueryInterface</code> for it, I discovered that it does get called but only for marshaling related interfaces, never for <code>IFileIsInUse</code>.</p>
  
  <p>Looking around I came to the conclusion that something is not initialized the way it should be in my application, but I can't figure out why.
  I already tried this:</p>
  
  <ul>
  <li>Call <code>CoInitializeEx(nil, COINIT_MULTITHREADED)</code> instead of the default <code>CoInitialize(nil)</code></li>
  <li>Add <code>HKEY_CLASSES_ROOT\CLSID\{MyGuid}\InProcServer32\ThreadingModel=Both</code></li>
  </ul>
  
  <p>but nothing helped. Considering that Microsoft's sample is a standalone application, I should be able to replicate what it does.</p>
  
  <p>Can any of you tell me what I'm doing wrong here?</p>