Importing COM Service into VB.net

Asked by At

I have a COM Service Interface that elevates a program so that it can run with Realtime priority. I have code in C++ that calls this service and works. I am now trying to implement something similar in VB.net

This is the C++ code that works:

bool SetPriority()
{
HRESULT                    hr(S_OK);
CString                    errStr;
CComPtr<IIncreasePriority> pPriorityService;

  hr = pPriorityService.CoCreateInstance(__uuidof(IncreasePriority));
  if (FAILED(hr))
  {
    errStr.Format(_T("IIncreasePriority.CoCreateInstance failed %X"), hr);
    OutputDebugString(errStr);
    MessageBox(NULL, errStr, _T("Error"), MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
    goto Exit;
  }

  hr = pPriorityService->SetPriority(GetCurrentProcessId(), REALTIME_PRIORITY_CLASS);
  if (FAILED(hr))
  {
    errStr.Format(_T("pPriorityService->SetPriority failed %d"), hr);
    OutputDebugString(errStr);
    MessageBox(NULL, errStr, _T("Error"), MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
    goto Exit;
  }

Exit:
  return SUCCEEDED(hr);
}

This is what I have so far in VB.net

Public Const REALTIME_PRIORITY_CLASS As Long = &H100&
Public Const CLSCTX_INPROC_SERVER As Integer = 1
Public Const CLSCTX_INPROC_HANDLER As Integer = 2
Public Const CLSCTX_LOCAL_SERVER As Integer = 4
Public Const CLSCTX_REMOTE_SERVER As Integer = 16

Public Const CLSCTX_ALL As Integer = CLSCTX_INPROC_SERVER + CLSCTX_INPROC_HANDLER + CLSCTX_LOCAL_SERVER + CLSCTX_REMOTE_SERVER

Declare Function GetCurrentProcessId Lib "Kernel32.dll" () As Long
Declare Function CoCreateInstance Lib "Ole32.dll" (ByRef rclsid As Guid, ByVal pUnkOuter As Long, ByVal dwClsContext As Long, ByRef riid As Guid, ByRef ppv As Object) As Long


Private Sub frmMenuBar_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim pPriorityService As IIncreasePriority
  Dim CLASS_IncreasePriority As Guid = New Guid("1E540BCE-C431-11E5-81F6-002215AB8805")
  Dim IID_IIncreasePriority As Guid = New Guid("13E6855E-C431-11E5-81F6-002215AB8805")

  On Error GoTo frmMenuBar_Load_Exit

  ' Set the Priority of the main process/thread
  CoCreateInstance(CLASS_IncreasePriority, 0, CLSCTX_ALL, IID_IIncreasePriority, pPriorityService)
  pPriorityService.SetPriority(GetCurrentProcessId(), REALTIME_PRIORITY_CLASS)

frmMenuBar_Load_Exit:
End Sub

While it compiles, it fails when I call CoCreateInstance. I truly don't know what to try next.

1 Answers

2
R.J. Dunnill On Best Solutions

Try decorating the function with marshalling attributes, like this:

Declare Function CoCreateInstance Lib "Ole32.dll" (
        <[In], MarshalAs(UnmanagedType.LPStruct)>
        ByRef rclsid As Guid,
        <MarshalAs(UnmanagedType.IUnknown)>
        ByVal pUnkOuter As Object,
        ByVal dwClsContext As UInteger,
         <[In], MarshalAs(UnmanagedType.LPStruct)>
        ByRef riid As Guid,
        <MarshalAs(UnmanagedType.[Interface])>
        ByRef ppv As Object) As UInt32

Alternatively, you could use the DllImportAttribute; here it's demonstrated with CoCreateInstanceEx (which has several parameter types):

    <StructLayout(LayoutKind.Sequential)>
    Friend Structure MULTI_QI
        <MarshalAs(UnmanagedType.LPStruct)>
        Public pIID As Guid
        <MarshalAs(UnmanagedType.[Interface])>
        Public pItf As Object
        Public hr As Integer
    End Structure

    <Flags>
    Friend Enum CLSCTX As UInteger
        CLSCTX_INPROC_SERVER = &H1
        CLSCTX_INPROC_HANDLER = &H2
        CLSCTX_LOCAL_SERVER = &H4
        CLSCTX_INPROC_SERVER16 = &H8
        CLSCTX_REMOTE_SERVER = &H10
        CLSCTX_INPROC_HANDLER16 = &H20
        CLSCTX_RESERVED1 = &H40
        CLSCTX_RESERVED2 = &H80
        CLSCTX_RESERVED3 = &H100
        CLSCTX_RESERVED4 = &H200
        CLSCTX_NO_CODE_DOWNLOAD = &H400
        CLSCTX_RESERVED5 = &H800
        CLSCTX_NO_CUSTOM_MARSHAL = &H1000
        CLSCTX_ENABLE_CODE_DOWNLOAD = &H2000
        CLSCTX_NO_FAILURE_LOG = &H4000
        CLSCTX_DISABLE_AAA = &H8000
        CLSCTX_ENABLE_AAA = &H10000
        CLSCTX_FROM_DEFAULT_CONTEXT = &H20000
        CLSCTX_ACTIVATE_32_BIT_SERVER = &H40000
        CLSCTX_ACTIVATE_64_BIT_SERVER = &H80000
        CLSCTX_INPROC = CLSCTX_INPROC_SERVER Or CLSCTX_INPROC_HANDLER
        CLSCTX_SERVER = CLSCTX_INPROC_SERVER Or CLSCTX_LOCAL_SERVER Or CLSCTX_REMOTE_SERVER
        CLSCTX_ALL = CLSCTX_SERVER Or CLSCTX_INPROC_HANDLER
    End Enum

Public Module NativeMethods
    <DllImport("ole32.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=False)>
    Private Sub CoCreateInstanceEx(
        <[In], MarshalAs(UnmanagedType.LPStruct)> ByVal rclsid As Guid,
        <MarshalAs(UnmanagedType.IUnknown)> ByVal pUnkOuter As Object,
        ByVal dwClsCtx As CLSCTX,
        ByVal pServerInfo As IntPtr,
        ByVal cmq As UInteger,
        <[In], Out> ByVal pResults As MULTI_QI())
    End Sub
End Module