现在,.NET CLR 4.0支持并行(SxS)操作,现在应该可以编写shell 托管代码中的扩展。我试过这个并成功编写了一个属性处理程序 实现IPropertyStore,IInitializeWithStream和IPropertyStoreCapabilities。
处理程序 工作正常,并通过资源管理器浏览文件时按预期调用。它也可以正常显示 预览面板中的自定义属性和文件属性“详细信息”面板。
但是,当我尝试时 在预览面板中编辑属性,然后单击“保存”我收到“正在使用文件”错误说明 该文件在Windows资源管理器中打开。
一些花絮:
那么我需要更改(或在注册中设置)以使属性保存才能工作?
更新
感谢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;
}
答案 0 :(得分:3)
是的,您必须使用AddRef()流来保持它的打开并保持引用正常运行。
请注意,索引器也将使用属性处理程序来打开文件。因此,如果泄漏流对象,文件将保持打开状态。您可以使用sysinternals procexp来告诉文件打开的进程,或procmon来告诉它使用了哪些调用和参数。
答案 1 :(得分:1)
资源管理器尝试确保它不会干扰可能打开文件的其他应用程序。该文件是否可以被另一个应用程序合法使用?是否有预览处理程序打开?
有时,我们会看到属性处理程序保持其流的打开时间超过必要时间(或者使用限制性权限打开文件的基于文件的处理程序)。您能否验证是否及时发布了流?
最后,我不认为这与您的直接问题有关,但不支持使用.NET shell扩展。我们建议不要将其纳入任何产品中。
-Ben