加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

.net – 实现托管属性处理程序Shell扩展的正确方法是什么?

发布时间:2020-12-15 17:00:42 所属栏目:安全 来源:网络整理
导读:既然.NET CLR 4.0支持并行(SxS)操作,现在应该可以编写 shell 托管代码中的扩展.我试过这个并成功编写了一个属性处理程序 实现IPropertyStore,IInitializeWithStream和IPropertyStoreCapabilities. 处理程序 工作正常,并通过资源管理器浏览文件时按预期调用.
既然.NET CLR 4.0支持并行(SxS)操作,现在应该可以编写 shell
托管代码中的扩展.我试过这个并成功编写了一个属性处理程序
实现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;
}
是的,你必须使用AddRef()流来保持它打开并保持引用正确.

请注意,索引器也将使用您的属性处理程序来打开该文件.因此,如果泄漏流对象,文件将保持打开状态.您可以使用sysinternals procexp来告诉文件打开的进程,或procmon来告诉它使用了哪些调用和参数.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读