Pass .NET SecureString to COM Interop
See the question and my original answer on StackOverflowLet's suppose you have that in .idl:
interface ITheComObjectDispatcher : IDispatch
{
HRESULT TheMethod(BSTR secret, [out, retval] BSTR *pOut);
};
This will become something like this with .NET's tlbimp (as you have seen):
[ComImport, TypeLibType((short) 0x10c0), Guid("D4089F1D-5D83-4D1C-92CD-5941B35D43AA")]
public interface ITheComObjectDispatcher
{
[return: MarshalAs(UnmanagedType.BStr)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60020000)]
string TheMethod([MarshalAs(UnmanagedType.BStr)] string secret);
}
So you cannot use this directly if you don't want to use unsafe string
arguments. The solution is to redefine the COM interface in C#, like this for example (note the InterfaceIsDual
option):
[InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D4089F1D-5D83-4D1C-92CD-5941B35D43AA")]
public interface ITheComObjectDispatcher2
{
[DispId(0x60020000)]
IntPtr TheMethod(IntPtr secret);
}
And use it like this:
var comObject = new TheComObject();
var comObjectDispatcher = (ITheComObjectDispatcher2)comObject;
var ptr = Marshal.SecureStringToBSTR(mySecureString);
try
{
var outPtr = doc.TheMethod(ptr);
// get the output string
var output = Marshal.PtrToStringBSTR(outPtr);
// free the callee-allocated BSTR
Marshal.FreeBSTR(outPtr);
}
finally
{
// free the secure string allocated BSTR
Marshal.ZeroFreeBSTR(ptr);
}