什么是实行有管理的物业处理程序外壳扩展了正确的方法是什么? [英] What is the correct way to implement a Managed Property Handler Shell Extension?

查看:166
本文介绍了什么是实行有管理的物业处理程序外壳扩展了正确的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在的.NET CLR 4.0支持并排(血散)的操作,现在应该可以编写shell 在扩展管理code。我尝试这一点,并成功地$ C $光盘属性处理程序 实现IPropertyStore,IInitializeWithStream和IPropertyStoreCapabilities。

的处理程序 工作正常,被称为通过浏览器浏览文件时的预期。它也能正常工作在显示 自定义属性在preVIEW面板和文件属性详细信息面板。

然而,当我试图 编辑在preVIEW面板中的属性,然后单击保存我得到一个文件正在使用错误消息, 该文件是在Windows资源管理器中打开。

几个花絮:

  1. 当浏览器调用IInitializeWithStream.Initialize的STGM属性设置为STGM_SHARE_DENY_WRITE。
  2. 而在任何时候,浏览器调用IPropertyStore.SetValue或IPropertyStore.Commit。
  3. 在我看到的一再呼吁,我在不同的线程对同一文件的属性处理程序。

那么,我需要改变(或者在系统登录设置)来获得的属性保存工作?

更新:

由于本我得到它的工作。而困难的部分(至少对我来说)是理解是COM互操作永远不会调用Dispose或无法最终确定我PropertyHandler。这是留给我处理开到了GC运行文件。

幸运的是,财产处理协议的作品,这样当IInitializeWithSream.Initialize()被调用的ReadValue()的streamMode是只读的,而当它被称为一个的SetValue()的streamMode是读写和提交()将被称为在末端。

  INT IInitializeWithStream.Initialize(的IStream流,UINT grfMode)
{
    _stream =流;
    _streamMode =(Stgm)grfMode;

    加载();

    //我们在这里释放原因,如果这是一个读操作,我们不会得到回调,
    //我们finializer不叫。
    如果((_streamMode&安培;!Stgm.ReadWrite)= Stgm.ReadWrite)
    {
        对Marshal.ReleaseComObject(_stream);
        _stream = NULL;
    }
    返回HResult.S_OK;
}

INT IPropertyStore.Commit()
{
    布尔结果= FALSE;

    如果(_stream!= NULL)
    {
        结果= WriteStream(_stream);
        对Marshal.ReleaseComObject(_stream);
        _stream = NULL;
    }

    返回的结果? HResult.S_OK:HResult.E_FAIL;
}
 

解决方案

是的,你必须的AddRef()流,以保持它的开放和正确地保持基准活着。

请注意,该索引将使用你的财产处理程序打开该文件也是如此。所以,如果你漏流对象,该文件将继续开放。您可以使用Sysinternals的procexp告诉哪些进程打开了​​该文件,或将procmon告诉什么叫和参数它使用的。

Now that .NET CLR 4.0 supports side by side (SxS) operation it should now be possible to write shell extensions in managed code. I have attempted this and successfully coded a Property Handler that implements IPropertyStore, IInitializeWithStream and IPropertyStoreCapabilities.

The handler works fine and is called as expected when browsing files via the explorer. It also works fine in displaying the custom properties in the preview panel and the file properties "detail" panel.

However, when I attempt to edit a property in the preview panel, and then click "Save" I get a "File In Use" error saying that the file is open in Windows Explorer.

A few tidbits:

  1. When explorer calls IInitializeWithStream.Initialize the STGM property is set to STGM_SHARE_DENY_WRITE.
  2. And at no point did explorer call IPropertyStore.SetValue or IPropertyStore.Commit.
  3. I see repeated calls to my handler on different threads for the same file properties.

So what do I need to change (or set in the registery) to get the property save to work?

Update:

Thanks to Ben I've got it working. The "difficult part" (at least for me) was understanding that COM interop would never call Dispose or Finalize on my PropertyHandler. This was leaving the files I processed open till the GC ran.

Fortunately, the "property handler protocol" works such that when IInitializeWithSream.Initialize() is called for a ReadValue() the streamMode is ReadOnly, and when it is called for a SetValue() the streamMode is ReadWrite and Commit() will be called at the end.

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;
}

解决方案

Yes, you have to AddRef() the stream to keep it open and to keep the reference alive correctly.

Note that the indexer will use your property handler to open the file as well. So if you leak the stream object, the file will remain open. You can use the sysinternals procexp to tell what process has the file open, or procmon to tell what calls and parameters it used.

这篇关于什么是实行有管理的物业处理程序外壳扩展了正确的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆