none
Howto create a safe handle for a uint handle RRS feed

  • Question

  • When interoping with Windows Installers MSIHANDLE (defined as unsigned long, i.e. a 32 bit value), I cannot use SafeHandle derived classes since they become 64-bit on x64.

    How do I create a MsiSafeHandle class that captures the value of the method in the following example even in case of asynchronous exceptions

    UINT MsiOpenPackage(
      __in   LPCTSTR szPackagePath,
      __out  MSIHANDLE *hProduct
    );

    Regards,

    /Staffan

     

    • Moved by SamAgain Wednesday, October 13, 2010 9:41 AM not a BCL question (From:.NET Base Class Library)
    • Moved by Kira Qian Friday, October 15, 2010 2:08 AM (From:ClickOnce and Setup & Deployment Projects)
    Monday, October 11, 2010 10:18 PM

Answers

  • Looking at the documentation for MsiCloseHandle I would say that the use of CriticalFinalizerObject is out of the question anyway. The documentation states

    "MsiCloseHandle must be called from the same thread that requested the creation of the handle."

    CriticalFinalizerObject is not appropriate here because the whole point is to ensure that the finalizer runs to perform essential cleanup, and the finalizer will run on its own thread. I think your options here are to either accept that you can leak MSI handles or use catch/finally blocks running under CERs to ensure that MsiCloseHandle gets called on the correct thread.

    • Marked as answer by StaffanGu Friday, October 15, 2010 6:36 PM
    Friday, October 15, 2010 4:18 PM

All replies

  • Sam, I beleive this is a question of a more general nature that just Setup and Deployment.

    The general question is how to create a SafeHandle type class for a native handle who's size is constant between architechtures, i.e. where the handle is defined as an 4-byte integer and not as a pointer.

    Wednesday, October 13, 2010 10:09 AM
  • Sam, I beleive this is a question of a more general nature that just Setup and Deployment.

    The general question is how to create a SafeHandle type class for a native handle who's size is constant between architechtures, i.e. where the handle is defined as an 4-byte integer and not as a pointer.


    I agree. This is more like a CLR discussion. I'll have a mod to move it to CLR. Sorry for that. :(

    BTW, could you elaborate on 'captures the value of the method in the following example even in case of asynchronous exceptions'?

    Thanks!
    Jie


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The All-In-One Code Framework Project
    My Blog (in Simplified Chinese)
    Thursday, October 14, 2010 3:38 PM
    Moderator
  • Oh, I see that I was a bit unclear there...

    In case of a stack overflow, out of memory or a thread abort, I wont to be able to capture the value of the MSIHANDLE from the out parameter in a class who's finalizer is guaranteed to be executed, like the SafeHandle derivatives.

    If I use

    static extern uint MsiOpenPackage(string package, out uint handle), there is always a gap before I can assign it to a a class with a critical finalizer where an asynchronous exception could occurr.

    Thursday, October 14, 2010 8:03 PM
  • You could manually create a CER using PrepareConstrainedRegions. This would allow you to make the call to MsiOpenPackage and assign the allocated handle to a custom SafeHandle within a CER.
    Friday, October 15, 2010 11:42 AM
  • Yes, but that means I would have to do it every time I call any Msi Function that outputs a handle. A SafeHandle of uint-size would be much more elegant.

     

    Friday, October 15, 2010 12:25 PM
  • Looking at the documentation for MsiCloseHandle I would say that the use of CriticalFinalizerObject is out of the question anyway. The documentation states

    "MsiCloseHandle must be called from the same thread that requested the creation of the handle."

    CriticalFinalizerObject is not appropriate here because the whole point is to ensure that the finalizer runs to perform essential cleanup, and the finalizer will run on its own thread. I think your options here are to either accept that you can leak MSI handles or use catch/finally blocks running under CERs to ensure that MsiCloseHandle gets called on the correct thread.

    • Marked as answer by StaffanGu Friday, October 15, 2010 6:36 PM
    Friday, October 15, 2010 4:18 PM