管理対象のプロパティハンドラシェル拡張機能を実装する正しい方法は何ですか?

StackOverflow https://stackoverflow.com/questions/3200245

質問

今すぐ.NET CLR 4.0が並んで(SXS)操作をサポートする今、シェルを書くことが可能になるはずです 管理コード内の拡張子私はこれを試み、プロパティハンドラを正常にコーディングしました これは、iPropertyStore、IInitializeWithStreamとiPropertyStoreCapilitiesを実装しています。

ハンドラ エクスプローラを介してファイルを閲覧するときに正常に動作します。また、それを表示する際にもうまく機能します プレビューパネルのカスタムプロパティとファイルのプロパティ「詳細」パネル。

しかし、私がしようとしたとき [プレビュー]パネルでプロパティを編集し、[保存]をクリックします。「使用中のファイル」というエラーが表示されます。 ファイルはWindowsエクスプローラで開かれています。

いくつかのTidBITS:

  1. ExplorerがIinitializeWithStreamを呼び出すと、STGMプロパティはstgm_share_deny_writeに設定されています。
  2. と無償エクスプローラはIPRopertyStore.SetValueまたはiPropertyStore.commitを呼び出しました。
  3. 同じファイルプロパティのさまざまなスレッド上の私のハンドラへの呼び出しを繰り返し呼び出します。
  4. それでは、プロパティを保存するには変更(またはレジストラ)を変更する必要がありますか?

    更新:

    ベンに感謝しています。 「難しい部品」(少なくとも私のために)は、COM Interopが私のPropertyHandlerで処分または完全化を呼んでいないことを理解していました。これは、私が処理したファイルをGCに走行するまで終了しました。

    幸いなことに、「プロパティハンドラプロトコル」は、StreamModeがreadOnlyにiinitializewithsream.initialize()が呼び出されるように機能し、StreamModeがsetValue()で呼び出されたときにStreamModeがReadWrite()最後に呼ばれます。

    int IInitializeWithStream.Initialize( IStream stream, uint grfMode )
    {
        _stream = stream;
        _streamMode = (Stgm)grfMode;
    
        Load();
    
        // We release here cause if this is a read operation we won't get called back, 
        // and our finializer isn't called. 
        if ( ( _streamMode & Stgm.ReadWrite ) != Stgm.ReadWrite )
        {
            Marshal.ReleaseComObject( _stream );
            _stream = null;
        }
        return HResult.S_OK;
    }
    
    int IPropertyStore.Commit()
    {
        bool result = false;
    
        if ( _stream != null )
        {
            result = WriteStream( _stream );
            Marshal.ReleaseComObject( _stream );
            _stream = null;
        }
    
        return result ? HResult.S_OK : HResult.E_FAIL;
    }
    
    .

役に立ちましたか?

解決

はい、あなたはそれを開いたままにするためにストリームをaddref()する必要があり、参照を正しく保持します。

インデクサーは、プロパティハンドラを使用してファイルを開くことに注意してください。そのため、Streamオブジェクトをリークすると、ファイルは開いたままになります。SysInternals Procexpを使用して、どのコールと使用したパラメータを使用してファイルを開くか、またはプロセスがどのプロセスにあるかを伝えます。

他のヒント

Explorerは、ファイルが開いている可能性がある他のアプリケーションと干渉しないようにします。ファイルは他のアプリケーションによって正当に使用されている可能性がありますか?プレビューハンドラが開いていますか?

時々、ストリームを必要以上に長く開いたプロパティハンドラ(ファイルを制限付きのアクセス許可を持つファイルベースのハンドラ)を開きます。あなたがタイムリーな方法でストリームを解放しているかどうかを確認できますか?

最後に、これがあなたの即時問題に関連しているとは思わないが、.NETシェル拡張機能を使用することはサポートされていません。これはあらゆる製品に組み込まれていないことをお勧めします。

-Ben

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top