Need example of calling RegLoadMUIString from C# to retrieve service description and such

Hello - I am TRULY a fledgling at using C# - (writing a couple of memory management programs for music performace purposes).

OK - I wrote a C# program that ran under XP that displays service info from the registry as part of functionality for dynamic management of memory using profiles.  All was well until I upgraded to Windows 7.  The program runs fine, but under Win7 service description and some other info now may contain MUI strings and I need to adjust my C# program to call RegLoadMUIString in a C++ program to retrieve the needed info.  

So what I would like someone to help me with is a complete set of example code in C# that calls a C++ program that performs the RegLoadMUIString function to retrieve the translated string and pass it back to the calling C# program.

As an example, my C# program already gets all of the list of services running on my machine.  As it is populating a display screen with the service information, I need to take each service and - for those that use redirected strings (MUI), I need to call a C++ routine to take the redirected string information and use the RegLoadMUIString function (available only in C++) to retrieve the actual value (for service description for example) and return that value to the C# program for inclusion in the populated information for the services running on the machine.  DisplayName can also be valued as a redirected string - so I have to be able to retrieve one or more of these per service, depending on how many redirected string values are present for a given service in the list I am processing for display in my C# program.

Here is a for instance of what the issue is - for service 'Application Layer Gateway Service' the value stored for Description is: "@%SystemRoot%\system32\Alg.exe,-113" which if you looked at it using Services.MSC would show up translated to a value of "Provides support for 3rd party protocol plug-ins for Internet Connection Sharing".  I need to mimic what Services.msc does behind the scenes to retrieve the expanded Service Description value.

Thank you SOOOOO much

Bob Bone
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

käµfm³d 👽Commented:
I assume if you can make the call in C# without the C++ interface, you would use it (at least that's my hope with this post!).

Here is a demonstration using P\Inoke in C#. The test is for the "Universal Serial Bus controllers". Make sure your import of RegLoadMUIString uses the unicode version (RegLoadMUIStringW) and not the ANSI version (RegLoadMUIStringA) as the ANSI version is unsupported.
public partial class Form1 : Form
    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "RegOpenKeyExW", CallingConvention = CallingConvention.StdCall)]
    public static extern int RegOpenKeyEx(UIntPtr hKey, string lpSubKey, int ulOptions, int samDesired, out UIntPtr phkResult);

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "RegLoadMUIStringW", CallingConvention = CallingConvention.StdCall)]
    internal static extern int RegLoadMUIString(UIntPtr hKey, string pszValue, StringBuilder pszOutBuf, int cbOutBuf, out int pcbData, uint Flags, string pszDirectory);

    [DllImport("advapi32.dll", ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern int RegCloseKey(UIntPtr hKey);

    public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
    public static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);
    public const int READKEY = 131097;

    private void button1_Click(object sender, EventArgs e)
        const int BUFFSIZE = 1024;
        UIntPtr key;
        StringBuilder buffer = new StringBuilder(1024);
        int pcbData;

        long result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, @"SYSTEM\CurrentControlSet\Control\Class\{36FC9E60-C465-11CF-8056-444553540000}", 0, READKEY, out key);
        result = RegLoadMUIString(key, "ClassDesc", buffer, BUFFSIZE, out pcbData, 0, null);

    public Form1()

Open in new window


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
käµfm³d 👽Commented:

I tested the above on my Win 7 x64.
robert_e_boneAuthor Commented:
Wow - My thought that C++ was needed was due to what I found out there under RegLoadMUIString - It indicated that C++ was the only supported language for the function.

I am trying to copy your code into a new project to test it out - and am struggling through that (I REALLY am a fledgling at C#, on top of which I am firing up Visual Studio 2010 Premium for the first time).  Things really look quite different than what I saw using Visual Studio 2008 Pro.

I have to go wade through 42 errors - and will post a response after getting a successful test.

THANKS - Bob Bone
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

käµfm³d 👽Commented:
Partly my fault--I forgot to tell you to include the System.Runtime.InteropServices namespace. This is needed for the DllImport statements  :)
robert_e_boneAuthor Commented:
Hi - This sure has changed for VS 2010.  I tried mimicing other using statements, and typed it in as "using namespace System::Runtime.::nteropServices;" but got a bunch of errors doing that.  I am in the proces of figuring out the correct means of getting that included.  Sorry I am such a newbie.  I've been programming on the mainframe for 30+ years and it's a different world.

Bob Bone
robert_e_boneAuthor Commented:
Sorry - had a typo in there - I typed it in as: using namespace System::Runtime::InteropServices;

Bob Bone
robert_e_boneAuthor Commented:
Thank you soooooo much
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.