Using the (SMS) ConfigMgr 2007 MPAPI with .NET

The MP API is a SDK component that can be used to communicate with a ConfigMgr (Formerly SMS) Management Point to:

  • Register clients
  • Send Data Discovery Records
  • Request Policy Assignments
  • Send Status Messages
  • and more...

From a developers perspective, this SDK is a COM binary that currently only has documentation for C++.  This tutorial will show users how to use the MP API in .NET

Step 1 : Create a .NET Wrapper for the COM Binary

We will use the Type Library Importer tool that will allow us to import COM types into native .NET types without having to make messy PInvoke calls.  In order to get the type libraries, we first need to install the ConfigMgr SDK which is publicly available on Connect. Once the SDK is installed, open a command prompt and navigate to the folder where smsmsgapi.tlb is located.  (Usually in SDKFOLDER\Samples\Management Point API)

In the command prompt run tlbimp.exe like below:

 tlbimp smsmsgapi.tlb /out:SmsMsgApiNet.dll
Microsoft (R) .NET Framework Type Library to Assembly Converter 2.0.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.

Type library imported to C:\Program Files\Microsoft System Center Configuration
Manager 2007 SDK\Samples\Management Point API\SmsMsgApiNet.dll

If all goes well, a binary will be created in the same folder called SmsMsgApiNet.dll

Step 2 : Correcting Bug in TlbImp.exe for Pointers

Currently, TlbImp.exe has an issue with arrays that will convert pointers to arrays as a single item by reference.  In order to correct the problem, we have to dis-assemble SmsMsgApiNet.dll and re-assemble the binary with the correct data type.  It sounds confusing, but it's really easy to do.

In the command prompt, run ildasm SmsMsgApiNet.dll /out=SmsMsgApiNet.il.  This command de-compiles the binary we just produced using the Type Library Importer so we can change the crucial parameters we need.

Using Visual Studio or your favorite code editor of choice, open SmsMsgApiNet.il to change the parameter.  Look for the instance that looks like below:

.method public hidebysig newslot abstract virtual
instance void SetClientCertificate([in] valuetype SmsMsgApiNet.MPAPI_CERT_STORE_LOCATION StoreLocation,
[in] string marshal( lpwstr) szStoreName,
[in] uint8& pCertHashBlob) runtime managed internalcall

The parameter uint8& is incorrect, since this is an array not a single uint8 passed by reference.  Change this data type to uint8* and save and close.  (Note: There are lots of other places where uint8& is used incorrectly, but we're focusing on a critical once for simplicity. For your specific needs, you may need to replace more instances than just the one we're changing.)

In the command prompt, run ilasm SmsMsgApiNet.il /DLL /OUTPUT=SmsMsgApiNet.dll.   This will take the modified de-compiled binary and re-compile it into a DLL with the corrected parameter.  This should now let you reference the binary in your projects correctly.  You can do this by adding this binary as a reference in your .NET projects.

Step 3 : Prepare the Project

Using Visual Studio, add a reference to the binary created in step 2 called SmsMsgApiNet.DLL. This allows us to find the objects defined within the SDK. In addition, we need
to register the COM binary with windows so it knows how to create the
interface.  In a command prompt run the following the command in the
same folder as SmsMsgApi.dll.  'regsvr32 SmsMsgApi.dll'.  If ran correctly, it should show a pop-up box saying the command completed successfully. The binary can be obtained from the SDK in the redistributables folder in the 'mpapi.msi' installer. That will install the MpApi to C:\SMS_SDK.

Step 4 : Creating the First Message

Now
that we have the COM binary references in Visual Studio with our custom
wrapper, lets look at a simple way to send a simple message to the Management
Point.  Because the SDK uses COM to pass memory around, the
SmsMessagingClass will have to create the message object using
CreateMessage() method so that is can pass between memory boundaries. 

 SmsMessagingClass messaging = new SmsMessagingClass();
ISmsMessage4 message, reply;
smsMessaging.CreateMessage(out message);
message.SetTargetEndpoint("MyDummyEndpoint");
message.SetPort(80);
message.SetBodyFromString("MyMessageBody");
 // Send the message using HTTP
messaging.Invoke("https://myHostname", message, out reply); 
 // Do something with the reply here...

Step 5 : Make Somthing Cool

This is a really simple example on how to use the MP API to send messages to the Management Point.  Other points to consider are how to using signing to ensure messages are accepted by the management point.  To send specific messages, refer to the Management Point API for more information on sending specific messages.