EnumDisplayDevices from C#

  • Thread starter Thread starter Randy Beckwith
  • Start date Start date
R

Randy Beckwith

Has anyone successfully used EnumDisplayDevices from C# through the
compact framework?

I keep getting a return code of 0 and a GetLastError value of 87. This
is what I'm doing:

// My wrapper for the Win32 func below
public static int EnumDisplayDevices( ref string DeviceName,
ref string DeviceString,
ref string DeviceID,
ref string DeviceKey,
ref int LastError
)
{
int CB_LEN = Marshal.SizeOf(typeof(int)) ;
int NAME_START = CB_LEN ;
int NAME_LEN = Marshal.SizeOf(typeof(char)) * 32 ;
int STRING_START = NAME_START + NAME_LEN ;
int STRING_LEN = Marshal.SizeOf(typeof(char)) * 128 ;
int FLAGS_START = STRING_START + STRING_LEN ;
int FLAGS_LEN = Marshal.SizeOf(typeof(int)) ;
int ID_START = FLAGS_START + FLAGS_LEN ;
int ID_LEN = STRING_LEN ;
int KEY_START = ID_START + ID_LEN;
int KEY_LEN = STRING_LEN ;

byte[] dd = new byte[KEY_START + KEY_LEN] ;
byte[] buint = BitConverter.GetBytes(dd.Length);
Buffer.BlockCopy(buint, 0, dd, 0, buint.Length);

int result = EnumDisplayDevices(null, 0, ref dd, 0 ) ;
LastError = (int ) GetLastError() ;

DeviceName = UnicodeEncoding.Unicode.GetString( dd, NAME_START,
NAME_LEN) ;
DeviceString = UnicodeEncoding.Unicode.GetString( dd,
STRING_START, STRING_LEN) ;
DeviceID = UnicodeEncoding.Unicode.GetString( dd, ID_START,
ID_LEN) ;
DeviceKey = UnicodeEncoding.Unicode.GetString( dd, KEY_START,
KEY_LEN) ;

return result ;
}//EnumDisplayDevices

// Win32 declaration
[DllImport("Coredll.dll")]
public static extern int EnumDisplayDevices( String lpDevice,
int iDevNum,
ref byte[]
lpDisplayDevice,
int dwFlags
);

Thanks for any advice.

Randy Beckwith
 
Strings are already passed by ref, so using "ref string" essentially yeilds
a pointer to a pointer, which is likely the problem.

-Chris
 
The correct way to invoke it is:
[DllImport("coredll")]
public static bool EnumDisplayDevices(
string lpDevice,
int iDevNum,
byte[] lpDisplayDevice,
int dwFlags
);

byte[] dd = new byte[224];
BitConverter.GetBytes((int)224).Copy(dd, 0, 4); // Initialize size
int iDev = 0;
while( EnumDisplayDevices(null, iDev++, dd, 0) )
{
string DeviceName = Encoding.Unicode.GetBytes(dd, 4, 32);
string DeviceString = Encoding.Unicode.GetBytes(dd, 36, 128);
// etc
}
 
Tried it but the code didn't compile.

Just out of curiosity, how did you come up with the number 224 for the
buffer size? I figured it to be about 840 bytes since all the strings
are unicode.


Alex Feinman said:
The correct way to invoke it is:
[DllImport("coredll")]
public static bool EnumDisplayDevices(
string lpDevice,
int iDevNum,
byte[] lpDisplayDevice,
int dwFlags
);

byte[] dd = new byte[224];
BitConverter.GetBytes((int)224).Copy(dd, 0, 4); // Initialize size
int iDev = 0;
while( EnumDisplayDevices(null, iDev++, dd, 0) )
{
string DeviceName = Encoding.Unicode.GetBytes(dd, 4, 32);
string DeviceString = Encoding.Unicode.GetBytes(dd, 36, 128);
// etc
}

Randy Beckwith said:
Has anyone successfully used EnumDisplayDevices from C# through the
compact framework?

I keep getting a return code of 0 and a GetLastError value of 87. This
is what I'm doing:

// My wrapper for the Win32 func below
public static int EnumDisplayDevices( ref string DeviceName,
ref string DeviceString,
ref string DeviceID,
ref string DeviceKey,
ref int LastError
)
{
int CB_LEN = Marshal.SizeOf(typeof(int)) ;
int NAME_START = CB_LEN ;
int NAME_LEN = Marshal.SizeOf(typeof(char)) * 32 ;
int STRING_START = NAME_START + NAME_LEN ;
int STRING_LEN = Marshal.SizeOf(typeof(char)) * 128 ;
int FLAGS_START = STRING_START + STRING_LEN ;
int FLAGS_LEN = Marshal.SizeOf(typeof(int)) ;
int ID_START = FLAGS_START + FLAGS_LEN ;
int ID_LEN = STRING_LEN ;
int KEY_START = ID_START + ID_LEN;
int KEY_LEN = STRING_LEN ;

byte[] dd = new byte[KEY_START + KEY_LEN] ;
byte[] buint = BitConverter.GetBytes(dd.Length);
Buffer.BlockCopy(buint, 0, dd, 0, buint.Length);

int result = EnumDisplayDevices(null, 0, ref dd, 0 ) ;
LastError = (int ) GetLastError() ;

DeviceName = UnicodeEncoding.Unicode.GetString( dd, NAME_START,
NAME_LEN) ;
DeviceString = UnicodeEncoding.Unicode.GetString( dd,
STRING_START, STRING_LEN) ;
DeviceID = UnicodeEncoding.Unicode.GetString( dd, ID_START,
ID_LEN) ;
DeviceKey = UnicodeEncoding.Unicode.GetString( dd, KEY_START,
KEY_LEN) ;

return result ;
}//EnumDisplayDevices

// Win32 declaration
[DllImport("Coredll.dll")]
public static extern int EnumDisplayDevices( String lpDevice,
int iDevNum,
ref byte[]
lpDisplayDevice,
int dwFlags
);

Thanks for any advice.

Randy Beckwith
 
Duh! You are right of course.
Sorry. I haven't tested the code (which I usually do, but I was under time
constraints). Of course I provided it more for illustration purposes

In lieu of penance I've built a sample project that compiles and runs
(although it fails to retrive the monitor info - at least on the emulator).
It is available from
http://www.alexfeinman.com/download.asp?doc=EnumDispDevices.zip

--
Alex Feinman
---
Coming to MDC? make sure to stop by the session CLI345
on Thursday for OpenNETCF talk

Randy Beckwith said:
Tried it but the code didn't compile.

Just out of curiosity, how did you come up with the number 224 for the
buffer size? I figured it to be about 840 bytes since all the strings
are unicode.


"Alex Feinman [MVP]" <[email protected]> wrote in message
The correct way to invoke it is:
[DllImport("coredll")]
public static bool EnumDisplayDevices(
string lpDevice,
int iDevNum,
byte[] lpDisplayDevice,
int dwFlags
);

byte[] dd = new byte[224];
BitConverter.GetBytes((int)224).Copy(dd, 0, 4); // Initialize size
int iDev = 0;
while( EnumDisplayDevices(null, iDev++, dd, 0) )
{
string DeviceName = Encoding.Unicode.GetBytes(dd, 4, 32);
string DeviceString = Encoding.Unicode.GetBytes(dd, 36, 128);
// etc
}

Randy Beckwith said:
Has anyone successfully used EnumDisplayDevices from C# through the
compact framework?

I keep getting a return code of 0 and a GetLastError value of 87. This
is what I'm doing:

// My wrapper for the Win32 func below
public static int EnumDisplayDevices( ref string DeviceName,
ref string DeviceString,
ref string DeviceID,
ref string DeviceKey,
ref int LastError
)
{
int CB_LEN = Marshal.SizeOf(typeof(int)) ;
int NAME_START = CB_LEN ;
int NAME_LEN = Marshal.SizeOf(typeof(char)) * 32 ;
int STRING_START = NAME_START + NAME_LEN ;
int STRING_LEN = Marshal.SizeOf(typeof(char)) * 128 ;
int FLAGS_START = STRING_START + STRING_LEN ;
int FLAGS_LEN = Marshal.SizeOf(typeof(int)) ;
int ID_START = FLAGS_START + FLAGS_LEN ;
int ID_LEN = STRING_LEN ;
int KEY_START = ID_START + ID_LEN;
int KEY_LEN = STRING_LEN ;

byte[] dd = new byte[KEY_START + KEY_LEN] ;
byte[] buint = BitConverter.GetBytes(dd.Length);
Buffer.BlockCopy(buint, 0, dd, 0, buint.Length);

int result = EnumDisplayDevices(null, 0, ref dd, 0 ) ;
LastError = (int ) GetLastError() ;

DeviceName = UnicodeEncoding.Unicode.GetString( dd, NAME_START,
NAME_LEN) ;
DeviceString = UnicodeEncoding.Unicode.GetString( dd,
STRING_START, STRING_LEN) ;
DeviceID = UnicodeEncoding.Unicode.GetString( dd, ID_START,
ID_LEN) ;
DeviceKey = UnicodeEncoding.Unicode.GetString( dd, KEY_START,
KEY_LEN) ;

return result ;
}//EnumDisplayDevices

// Win32 declaration
[DllImport("Coredll.dll")]
public static extern int EnumDisplayDevices( String lpDevice,
int iDevNum,
ref byte[]
lpDisplayDevice,
int dwFlags
);

Thanks for any advice.

Randy Beckwith
 
Great! Thanks. And your sample answered another question that I didn't
even ask yet. I'd been having problems returning strings from
Win32APIs. There never seemed to be a terminating NULL. Your use of
..TrimEnd('\0\) showed me how to solve that problem.

Thanks.

Randy Beckwith


Alex Feinman said:
Duh! You are right of course.
Sorry. I haven't tested the code (which I usually do, but I was under time
constraints). Of course I provided it more for illustration purposes

In lieu of penance I've built a sample project that compiles and runs
(although it fails to retrive the monitor info - at least on the emulator).
It is available from
http://www.alexfeinman.com/download.asp?doc=EnumDispDevices.zip

--
Alex Feinman
---
Coming to MDC? make sure to stop by the session CLI345
on Thursday for OpenNETCF talk

Randy Beckwith said:
Tried it but the code didn't compile.

Just out of curiosity, how did you come up with the number 224 for the
buffer size? I figured it to be about 840 bytes since all the strings
are unicode.


"Alex Feinman [MVP]" <[email protected]> wrote in message
The correct way to invoke it is:
[DllImport("coredll")]
public static bool EnumDisplayDevices(
string lpDevice,
int iDevNum,
byte[] lpDisplayDevice,
int dwFlags
);

byte[] dd = new byte[224];
BitConverter.GetBytes((int)224).Copy(dd, 0, 4); // Initialize size
int iDev = 0;
while( EnumDisplayDevices(null, iDev++, dd, 0) )
{
string DeviceName = Encoding.Unicode.GetBytes(dd, 4, 32);
string DeviceString = Encoding.Unicode.GetBytes(dd, 36, 128);
// etc
}

Has anyone successfully used EnumDisplayDevices from C# through the
compact framework?

I keep getting a return code of 0 and a GetLastError value of 87. This
is what I'm doing:

// My wrapper for the Win32 func below
public static int EnumDisplayDevices( ref string DeviceName,
ref string DeviceString,
ref string DeviceID,
ref string DeviceKey,
ref int LastError
)
{
int CB_LEN = Marshal.SizeOf(typeof(int)) ;
int NAME_START = CB_LEN ;
int NAME_LEN = Marshal.SizeOf(typeof(char)) * 32 ;
int STRING_START = NAME_START + NAME_LEN ;
int STRING_LEN = Marshal.SizeOf(typeof(char)) * 128 ;
int FLAGS_START = STRING_START + STRING_LEN ;
int FLAGS_LEN = Marshal.SizeOf(typeof(int)) ;
int ID_START = FLAGS_START + FLAGS_LEN ;
int ID_LEN = STRING_LEN ;
int KEY_START = ID_START + ID_LEN;
int KEY_LEN = STRING_LEN ;

byte[] dd = new byte[KEY_START + KEY_LEN] ;
byte[] buint = BitConverter.GetBytes(dd.Length);
Buffer.BlockCopy(buint, 0, dd, 0, buint.Length);

int result = EnumDisplayDevices(null, 0, ref dd, 0 ) ;
LastError = (int ) GetLastError() ;

DeviceName = UnicodeEncoding.Unicode.GetString( dd, NAME_START,
NAME_LEN) ;
DeviceString = UnicodeEncoding.Unicode.GetString( dd,
STRING_START, STRING_LEN) ;
DeviceID = UnicodeEncoding.Unicode.GetString( dd, ID_START,
ID_LEN) ;
DeviceKey = UnicodeEncoding.Unicode.GetString( dd, KEY_START,
KEY_LEN) ;

return result ;
}//EnumDisplayDevices

// Win32 declaration
[DllImport("Coredll.dll")]
public static extern int EnumDisplayDevices( String lpDevice,
int iDevNum,
ref byte[]
lpDisplayDevice,
int dwFlags
);

Thanks for any advice.

Randy Beckwith
 
Back
Top