Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FormatMessage (in C#) only looks for system messages

793 views
Skip to first unread message

roberto patane via .NET 247

unread,
Apr 23, 2004, 12:55:10 AM4/23/04
to
Hello,

I am trying (for my project in college) to use the functions LoadLibraryEx(..) and FormatMessage(..) in C# in order to read messages stored in custom message files. Let's say the message associated with the event ID: 1008 for the Source: Perflib, found in prflbmsg.dll

I have modified the code suggested in the message "FormatMessage Call in C#" without success.
Basically, the function will always return a message taken from the Kernel32.dll, (I guess) the system message table, even if I pass the option FORMAT_MESSAGE_FROM_HMODULE, and a valid handle (returned by LoadLibraryEx(..)).

Here is the code:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace RobertoProject
{
class FormatMessageClass
{
public const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
public const uint FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
public const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
public const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
public const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;

[STAThread]
static void Main()
{
int id = 1008;
string dllFile = "prflbmsg.dll"; // message file registered for source "Perflib"
Console.WriteLine("\n > Trying with ID: " + id + " with DLL: " + dllFile);
Console.WriteLine( "\n - Description: " + GetMessage( id, dllFile ) );
Console.ReadLine();
}

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr LoadLibraryEx(
[MarshalAs(UnmanagedType.LPTStr)] string lpFileName, IntPtr hFile, uint dwFlags );

[DllImport( "kernel32.dll", CharSet=CharSet.Auto )]
private static extern int FormatMessageW(
uint dwFormatFlags, IntPtr lpSource, int dwMessageId,
int dwLanguageId, out IntPtr MsgBuffer, int nSize, IntPtr Arguments );

public static string GetMessage( int id, string dllFile )
{
IntPtr hModule = IntPtr.Zero;
IntPtr pMessageBuffer;
int dwBufferLength;
string sMsg = "";
uint dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS;

hModule = LoadLibraryEx( dllFile, // dll or exe file
IntPtr.Zero, // null for future use
LOAD_LIBRARY_AS_DATAFILE); // only to extract messages

if(IntPtr.Zero != hModule)
{
dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
Console.WriteLine("\n > Found hmodule for: " + dllFile );
}

dwBufferLength = FormatMessageW( dwFormatFlags, // formatting options
hModule, // dll file message
id, // Message identifier
0, // Language identifier
out pMessageBuffer, // Pointer to a buffer
0, // Minimum number of chars to write in pMessageBuffer
IntPtr.Zero ); /*Pointer to an array of insertion strings
if(0 != dwBufferLength)
{
sMsg = Marshal.PtrToStringUni(pMessageBuffer);
Marshal.FreeHGlobal(pMessageBuffer);
}
return sMsg;
}
}
}


The output I get:

> Trying with ID: 1008 with DLL: prflbmsg.dll

> Found hmodule for: prflbmsg.dll

- Description: An attempt was made to reference a token that does not exist.

I should get the description: The Open Procedure for service "%1" in DLL "%2" failed. Performance data for this service will not be available. Status code returned is data DWORD 0.

Am I setting the wrong flags or whatelse?
My project is due for soon and I am stuck with this issue.
Could someone, please help me with this?

Thanks,
Roberto
roberto...@yahoo.com

-----------------------
Posted by a user from .NET 247 (http://www.dotnet247.com/)

<Id>7vVrS3zWok+cm+ii2uoj8w==</Id>

David Gutierrez[MSFT]

unread,
Apr 28, 2004, 12:50:33 PM4/28/04
to
Since you're using FORMAT_MESSAGE_FROM_SYSTEM, it looks like FormatMessage
can't find the resource in your dll and is instead using the system
resources. Try removing FORMAT_MESSAGE_FROM_SYSTEM and see if you get a
meaningful error.

If the problem is that FormatMessage can't find your resourcecheck the
resource id carefully. If you added a severity modifier, this can change
the id. I believe the message compiler (mc.exe) will generate a .h file
with the exact ids in it, so that's a place to start.

David

JLoyd

unread,
Apr 29, 2004, 1:36:03 PM4/29/04
to
David,

We are using FormatMessage() with great success, except that we were hoping to get messages in langugaes other than English. We've even tried the MUI extentions, but everything only comes back in English. We are getting the feeling that messages are stored at installation time, MUI or not.

I'm thinking that even if MUI provides localized error strings, they might be in a different dll or exe. If I knew which dll or exe to try, I'd be happy to change our code to not use FORMAT_MESSAGE_FROM_SYSTEM, and instead pass in a module handle.

Do you know how we might find out which dll or exe to try? I've searched a lot, but this approach may take forever.

Thanks for any pointers you might be able to provide,

Jerry Loyd


----- David Gutierrez[MSFT] wrote: -----

David Gutierrez[MSFT]

unread,
Apr 30, 2004, 12:33:34 PM4/30/04
to
I believe you also need to tell the MUI extensions that you want to install
resources for your particular language. I'm not much of an expert on the
MUI extensions, though, so you might try asking on one of the Windows
newgroups - Microsoft.public.windows.* or microsoft.public.windowsxp.*

David

0 new messages