C# problem using the GetVersionExA API.

Hi.
I'm trying to determine if the operating system is a domain controller using the GetVersionExA function and OSVERSIONINFOEX struct
I tried the exact same code in VB.NET and it worked just fine, but it doesn't in C#.
Any ideas?

Here is the code I have:
[StructLayout(LayoutKind.Sequential)]
public struct OSVERSIONINFOEX
{
      [MarshalAs(UnmanagedType.U4)]
      public int dwOSVersionInfoSize;
      [MarshalAs(UnmanagedType.U4)]
      public int dwMajorVersion;
      [MarshalAs(UnmanagedType.U4)]
      public int dwMinorVersion;
      [MarshalAs(UnmanagedType.U4)]
      public int dwBuildNumber;
      [MarshalAs(UnmanagedType.U4)]
      public int dwPlatformId;
      [MarshalAs(UnmanagedType.LPTStr, SizeConst=128)]
      public string szCSDVersion;
      [MarshalAs(UnmanagedType.U2)]
      public short wServicePackMajor;
      [MarshalAs(UnmanagedType.U2)]
      public short wServicePackMinor;
      [MarshalAs(UnmanagedType.U2)]
      public short wSuiteMask;
      public byte wProductType;
      public byte wReserved;
}

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetVersionExA([MarshalAs(UnmanagedType.Struct)] ref OSVERSIONINFOEX lpVersionInfo);

public bool IsDomainController()
{
bool isDC = false;
OSVERSIONINFOEX os = new OSVERSIONINFOEX();
os.dwOSVersionInfoSize = Marshal.SizeOf(os);
if (GetVersionExA(ref os))
{
      isDC = (os.wProductType == 2);
}
else
{
      Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}

return isDC;
}

Any help would be greatly appreciated!
LVL 2
Balder1978Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
Bob LearnedConnect With a Mentor Commented:
Change to this:

      [MarshalAs(UnmanagedType.ByValArray , SizeConst=128)]
      public char[] szCSDVersion;

Bob
0
 
Bob LearnedCommented:
Try something like this instead:

string osVersion = Environment.OSVersion.Platform.ToString();

Bob
0
 
Balder1978Author Commented:
I don't need the OS version, I need to know if it's a Domain Controller or not.
But thanks for the input!
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
Bob LearnedCommented:
Do you still have the VB.NET code?

Bob
0
 
Balder1978Author Commented:
sure:

<StructLayout(LayoutKind.Sequential)> _
Public Structure OSVERSIONINFOEX
        <MarshalAs(UnmanagedType.U4)> _
        Public dwOSVersionInfoSize As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwMajorVersion As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwMinorVersion As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwBuildNumber As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwPlatformId As Integer
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> _
        Public szCSDVersion() As Char
        <MarshalAs(UnmanagedType.U2)> _
        Public wServicePackMajor As Short
        <MarshalAs(UnmanagedType.U2)> _
        Public wServicePackMinor As Short
        <MarshalAs(UnmanagedType.U2)> _
        Public wSuiteMask As Short
        Public wProductType As Byte
        Public wReserved As Byte
End Structure

Private Declare Function GetVersionEx Lib "kernel32.dll" Alias "GetVersionExA" (<MarshalAs(UnmanagedType.Struct)> ByRef ByReflpVersionInfo As OSVERSIONINFOEX) As Boolean

Usage:
Dim os As OSVERSIONINFOEX = New OSVERSIONINFOEX
os.dwOSVersionInfoSize = Marshal.SizeOf(os)
GetVersionEx(os)
0
 
Bob LearnedCommented:
In VB.NET, the os.dwOSVersionInfoSize = 156, and in C#, it is 32.  Investigating...

Bob
0
 
Balder1978Author Commented:
Exactly, and if I set it manually to 156 (which is too dirty programming), I get the OS version numbers, but not the wProductType wich is what I'm looking for.
Thanks!
0
 
Bob LearnedCommented:
The OSVERSIONINFOEX.szCSDVersion appears to be the problem.

In the VB.NET IL code:

szCSDVersion public marshal (fixed array[128]) char[]

In the C# IL code:

szCSDVersion public marshal (lptstr) string

There is clearly a size difference here.

Bob
0
 
Balder1978Author Commented:
that didn't work, but this did:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
public string szCSDVersion;

The size is now 156, but it still doesn't work...
0
 
Bob LearnedCommented:
It worked for me--return a false.  What .NET version do you have?  I have 2003.

Bob
0
 
Balder1978Author Commented:
I have 2003 with .NET 1.1 SP1 too... Strange...
0
 
Bob LearnedCommented:
What happened when you used this?

[MarshalAs(UnmanagedType.ByValArray , SizeConst=128)]
      public char[] szCSDVersion;


Bob
0
 
Balder1978Author Commented:
So sorry, didn't change public char[] szCSDVersion;
I'll test it and get back to u ASAP.
0
 
Balder1978Author Commented:
Thanks alot, man. Works great!
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.