代码之家  ›  专栏  ›  技术社区  ›  Ajay

即使存在msicCloseHandle,也需要msiViewClose调用吗?

  •  0
  • Ajay  · 技术社区  · 5 年前

    我使用打开MSI数据库视图 MsiDatabaseOpenView 然后打电话给 MsiViewExecute . 那我需要打电话吗 MsiViewClose 即使我打电话给 MsiCloseHandle ?威尔 msi闭合手柄 不打电话 msiView关闭 (或者做些什么来关闭所有需要的内部手柄)?

    我问这个的真正原因是: 有一个班 PMSIHANDLE 建议不要手动关闭句柄(析构函数将调用 msi闭合手柄 -源代码在VS中可见)。所以当我打开视图时 msi数据库打开视图 把把手包起来 PMSIhandle公司 ,我不用打电话了 msi闭合手柄 但是我必须(?)呼叫 msiView关闭 !?

    0 回复  |  直到 5 年前
        1
  •  3
  •   zett42    5 年前

    回答

    MsiViewClose() 不需要关闭手柄。仅当您要运行时才需要 MsiViewExecute() 再次在同一视图上,这对于向参数化SQL查询传递不同的参数非常有用。这在 documentation :

    必须在msiviewExecute之前调用msiviewClose函数 在视图上再次调用函数,除非结果的所有行 已使用msiViewFetch函数获取集合。

    在最常见的用例中,您只执行一个 msiView执行() 调用给定视图,不需要调用 msiView关闭() :

    PMSIHANDLE pView;
    UINT res = MsiDatabaseOpenViewW( hDatabase, L"SELECT * FROM `File`", &pView );
    if( res == ERROR_SUCCESS )
    {
        res = MsiViewExecute( pView, nullptr );
    }
    // Destructor of PMSIHANDLE calls MsiCloseHandle()
    

    旁注

    从现代C++的观点, PMSIHANDLE 似乎设计得不好。首先,它不提供防止意外复制句柄的保护,这将导致调用 msiView关闭() 在同一个手柄上两次。同时将隐式转换为 MSIHANDLE* 可以很方便,也很危险,因为这样可以意外地覆盖现有的句柄,而不必先关闭它。

    这里有一个替代 PMSIhandle公司 基于C++ 11S std::unique_ptr :

    // A deleter for MSIHANDLE.
    struct MsiHandleDeleter
    {
        // This alias enables us to actually store values of type MSIHANDLE in the unique_ptr
        // (by default it would be MSIHANDLE*).
        using pointer = MSIHANDLE;
    
        void operator()( MSIHANDLE h ) const { if( h ) ::MsiCloseHandle( h ); }
    };
    
    // A RAII wrapper for MSI handle. The destructor automatically closes the handle, if not 0.
    using UniqueMsiHandle = std::unique_ptr< MSIHANDLE, MsiHandleDeleter >;
    

    用法示例:

    UniqueMsiHandle record{ ::MsiCreateRecord( 1 ) };
    ::MsiRecordSetInteger( record.get(), 1, 42 );
    // Destructor takes care of calling MsiCloseHandle(), just like PMSIHANDLE.
    

    与…相比 PMSIhandle公司 将它与具有 msi句柄* 输出参数,但可以通过创建包装函数或使用 UnqiueMsiHandle .

    优势:

    • 减少做错事情的方法。
    • 清晰的所有权和 moveability .
    • 每个习惯的人 STD:UngQuyPPTR 将立即理解 UniqueMsiHandle .