托管代码中的扩展.我试过这个并成功编写了一个属性处理程序
实现IPropertyStore,IInitializeWithStream和IPropertyStoreCapabilities.
处理程序
工作正常,并通过资源管理器浏览文件时按预期调用.它也可以正常显示
预览面板中的自定义属性和文件属性“详细信息”面板.
但是,当我尝试
在预览面板中编辑属性,然后单击“保存”我收到“正在使用文件”错误说明
该文件在Windows资源管理器中打开.
一些花絮:
>当资源管理器调用IInitializeWithStream.Initialize时,STGM属性设置为STGM_SHARE_DENY_WRITE.
>并且探测器决不会调用IPropertyStore.SetValue或IPropertyStore.Commit.
>我看到在不同线程上对我的处理程序重复调用相同的文件属性.
那么我需要更改(或设置在注册表中)以使属性保存工作?
更新:
感谢Ben,我已经开始工作了. “困难部分”(至少对我来说)是理解COM互操作永远不会在我的PropertyHandler上调用Dispose或Finalize.这使我处理的文件保持打开状态,直到GC运行.
幸运的是,“属性处理程序协议”的作用是,当为ReadValue()调用IInitializeWithSream.Initialize()时,streamMode是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; }
请注意,索引器也将使用您的属性处理程序来打开该文件.因此,如果泄漏流对象,文件将保持打开状态.您可以使用sysinternals procexp来告诉文件打开的进程,或procmon来告诉它使用了哪些调用和参数.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。