I'm playing around with these two native win32 functions:
[DllImport( "oleacc.dll" )]
public static extern int AccessibleObjectFromWindow(
IntPtr hwnd,
int dwObjectID,
ref Guid refID,
ref Accessibility.IAccessible ppvObject );
[DllImport( "oleacc.dll" )]
public static extern uint AccessibleChildren(
Accessibility.IAccessible paccContainer,
int iChildStart,
int cChildren,
[Out] object[] rgvarChildren,
out int pcObtained );
And I'm having a hard time figuring out if I should/need to call Marshal.ReleaseComObject on any of the returned objects. I would be thankful is someone could enlighten me on this topic! Here's a sample usage:
Accessibility.IAccessible test(
int hWnd,
string accessName )
{
Guid guidCOM = new Guid( 0x618736E0, 0x3C3D, 0x11CF, 0x81, 0xC, 0x0, 0xAA, 0x0, 0x38, 0x9B, 0x71 );
Accessibility.IAccessible a = null;
AccessibleObjectFromWindow(
new IntPtr( hWnd ),
-4,
ref guidCOM,
ref a );
object[] children = new object[a.accChildCount];
int z;
AccessibleChildren( a, 0, children.Length, children, out z );
foreach ( Accessibility.IAccessible a2 in children )
try
{
if ( a2.get_accName( 0 ) == accessName )
return a2;
}
catch
{
}
return null;
}
You should use this method to free the underlying COM object that holds references to resources in a timely manner or when objects must be freed in a specific order. Every time a COM interface pointer enters the common language runtime (CLR), it is wrapped in an RCW.
Marshal.ReleaseComObject
is a useful work-around if you really need to get the GC to apply the release immediately, instead of waiting for the GC to run. It is best to not use it unless you really need to, because it has a tendency to take over your code and you have to apply it every where, including places where you have created implicit references.
I suspect that the best method for COM interop in .Net is to write strongly typed wrapper classes around the methods you are using. This way there is no possibility of introducing implicit references, and it will simplify the code and ensure that the interfaces are more easily reachable for the GC. Some of my cow-orkers have reported better memory behaviour by using this methods - the objects are released in a timely fashion as GC runs without leaving any mystery references lying around.
Generally speaking, all COM objects referenced in .Net code are implemented in the form of an RCW object which holds the true COM reference - the call to ReleaseComObject
forces the RCW to decrement the reference by a count of one. In this way it is similar to just calling Release
on the actual IUnkown
instance. Probably in the example you have above, it is not necessary to make the call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With