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
robert_e_boneAsked:
Who is Participating?
 
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);
        RegCloseKey(key);
    }

    public Form1()
    {
        InitializeComponent();
    }
}

Open in new window

0
 
käµfm³d 👽Commented:
P.S.

I tested the above on my Win 7 x64.
0
 
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
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
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  :)
0
 
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
0
 
robert_e_boneAuthor Commented:
Sorry - had a typo in there - I typed it in as: using namespace System::Runtime::InteropServices;

Bob Bone
0
 
robert_e_boneAuthor Commented:
Thank you soooooo much
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.