现在,.NET CLR 4.0并排支持(SXS)操作,现在应该可以写入shell 托管代码中的扩展。我尝试过这个并成功编码了属性处理程序 这实现了IPropertyStore,iInitializeWithStream和IPropertyStoreCapabilities。

处理程序 工作正常,并通过资源管理器浏览文件时被称为预期。它还适用于显示 预览面板和“文件属性”详细信息“面板中的自定义属性。

但是,当我试图 在预览面板中编辑属性,然后单击“保存”,我得到“使用中的文件”错误说明 该文件在Windows资源管理器中打开。

几个tidbits:

  1. 当资源管理器调用iinitializewithstream时.Initialize stgm属性设置为stgm_share_deny_write。
  2. 和在没有点,deproverer调用ipropertystore.setValue或iPropertyStore.Commit。
  3. 我会在不同的线程上对我的处理程序重复调用相同的文件属性。
  4. 那么我需要什么需要更改(或在注册表中设置)来获取属性保存到工作?

    更新:

    谢谢你,我已经工作了。 “困难的部分”(至少对我)是理解,COM互操作永远不会呼叫处置或最终确定我的楼章。这将离开我处理的文件,直到gc ran。

    幸运的是,“属性处理程序协议”工作,即当IinitializeWithSream.Initialize()调用ReadValue()是ReadOnly的,并且当调用setValue()时,StreamMode是ReadWrite和Commit()将在最后调用。

    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()流以保持打开并正确保持参考。

请注意,索引器将使用您的属性处理程序打开文件。因此,如果泄露流对象,则该文件将保持打开状态。您可以使用sysinternals procexp来判断文件打开的过程,或者procmon告诉它使用的调用和参数。

其他提示

资源管理器试图确保它不会干扰可能打开文件的其他应用程序。该文件可以合法地使用其他申请吗?是否有预览处理程序打开?

有时,我们会看到属性处理程序,以保持其流的流开放时间长于必要的(或打开具有限制权限的文件的基于文件的处理程序)。您是否可以及时释放流释放流?

最后,我不认为这与您的直接问题有关,但使用.NET shell扩展不支持。我们建议这不纳入任何产品。

-ben

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top