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.

Comments

  • Anonymous
    April 02, 2008
    Hi Gabe, I gave this a shot and ran into problems. The DLL I recompiled will not register (I am doing this on a dev system with the 2.5 sms client and Visual Studio 2005. I can load the binary into a project and see it however the code you provided does not work in my build....it complains at CreateMessage. Would it be possible to get a sample project posted as well? Thanks! Mike

  • Anonymous
    April 02, 2008
    Looks like I was assuming a static method there...on to the next phase. Thanks for the assistance.

  • Anonymous
    October 07, 2008
    I had one reader from Germany contact me regarding porting a sample section of my blog posting on using

  • Anonymous
    June 03, 2010
    Hi Gabe, Can you give me tips or help me with my problem? I am having trouble hosting it on IIS. I want to host it on IIS so that I can access it from a remote computer. The problem is, when I call it in IIS, I receive an Access Denied error. However, when I call it on Visual Studio 2008 or run a C++ console app version, it works. The documentation says this: 'When using HTTP, the caller must have access to the management point interfaces DLL and, when using certificates, access to the certificate private key. No other special account membership is required.' I am not sure what I did wrong. I registered the smsgapi.dll by using 'regsvr32 smsgapi.dll'. I am also sure that I have no certificates. Can you help me? Thank you very much and hope to hear from you!