Solved

C# problem using the GetVersionExA API.

Posted on 2004-09-28
14
1,055 Views
Last Modified: 2008-01-09
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!
0
Comment
Question by:Balder1978
  • 7
  • 7
14 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12173937
Try something like this instead:

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

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12180802
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
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181098
Do you still have the VB.NET code?

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181126
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
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181180
In VB.NET, the os.dwOSVersionInfoSize = 156, and in C#, it is 32.  Investigating...

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181203
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
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181246
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 96

Accepted Solution

by:
Bob Learned earned 125 total points
ID: 12181278
Change to this:

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

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181308
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
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181348
It worked for me--return a false.  What .NET version do you have?  I have 2003.

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181920
I have 2003 with .NET 1.1 SP1 too... Strange...
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181938
What happened when you used this?

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


Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181952
So sorry, didn't change public char[] szCSDVersion;
I'll test it and get back to u ASAP.
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12182176
Thanks alot, man. Works great!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
MVC5 Dataformat String for Phone not working 3 26
Linq Help 1 35
LINQ - C# to VB convertion 12 48
C# parent child form 5 19
In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

27 Experts available now in Live!

Get 1:1 Help Now