Has Anyone Used GetCurrentHWProfile under VB .NET 2002?

  • Thread starter Thread starter Brian Worth
  • Start date Start date
B

Brian Worth

Hi,

I've just upgraded a program from VB4 to VB .NET 2002. The program would use
the GetCurrentHWProfile API to tell if my laptop was docked or undocked.
I've tried converting this call without success as I haven't found anything
in .NET Framework yet that will give this information.

The converted program gives a SystemExecutionEngineException. The code is
currently as follows:

REM------------------------------
REM API for checking docked state
REM------------------------------
Private Const HW_PROFILE_GUIDLEN = 39 ' 36-characters plus NULL
terminator
Private Const MAX_PROFILE_LEN = 80
Private Const DOCKINFO_UNDOCKED = 1
Private Const DOCKINFO_DOCKED = 2
Private Const DOCKINFO_USER_SUPPLIED = 4
Private Const DOCKINFO_USER_UNDOCKED = (DOCKINFO_USER_SUPPLIED And
DOCKINFO_UNDOCKED)
Private Const DOCKINFO_USER_DOCKED = (DOCKINFO_USER_SUPPLIED And
DOCKINFO_DOCKED)
<StructLayout(LayoutKind.Sequential)> Private Structure tHW_PROFILE_INFO
Dim dwDockInfo As Integer
Dim szHwProfileGuid As String
Dim szHwProfileName As String
End Structure
Private Declare Function GetCurrentHwProfile Lib "advapi32.dll" _
Alias "GetCurrentHwProfileA" _
(ByRef lpHwProfileInfo As tHW_PROFILE_INFO) As Boolean
Public Const PCDesktop = 0 ' Docking state doesn't apply - PC is a
desktop machine
Public Const PCUndocked = 1
Public Const PCDocked = 2
Public Const PCDockUndetermined = 12

Public Function PCDockingStatus(ByRef MSG As String) As Integer
Dim uHW As tHW_PROFILE_INFO
Dim buffer As New System.Text.StringBuilder(" ", HW_PROFILE_GUIDLEN)
uHW.szHwProfileGuid = buffer.ToString
Dim buffer2 As New System.Text.StringBuilder(" ", MAX_PROFILE_LEN)
uHW.szHwProfileName = buffer2.ToString ' Expand the string area
Try
If GetCurrentHwProfile(uHW) <> 0 Then ' If the call worked?
If uHW.dwDockInfo And DOCKINFO_DOCKED Then ' If "Docked"
returned
PCDockingStatus = PCDocked
MSG = "DOCKED LAPTOP PC"
ElseIf uHW.dwDockInfo And DOCKINFO_UNDOCKED Then ' If
"Undocked" returned
PCDockingStatus = PCUndocked
MSG = "UNDOCKED LAPTOP PC"
Else ' Something else was returned
MSG = "GetCurrentHwProfile RETURNED UNEXPECTED VALUE - "
& uHW.dwDockInfo
End If
Else
MSG = "GetCurrentHwProfile FAILED"
End If
Catch
MsgBox(Err.Description)
End Try

End Function


The exception occurs at the line If GetCurrentHwProfile(uHW) <> 0 Then ' If
the call worked?
I have tried variants of the above e.g. Defining the function as Auto and
then Ascii, defining the buffer and buffer2 variables as ordinary strings
instead of using Stringbuilder and pointing the uHW.szHwProfile.... fields
directly at the variables etc but whatever I do I get
SystemExecutionEngineException...

I suspect it is something to do with strings because when I look at the uHW
structure contents after the crash, a number has appeared in the dwDockInfo
field but the two string fields that follow are empty.

Regards,

Brian.
 
Hi,

I've just upgraded a program from VB4 to VB .NET 2002. The program would use
the GetCurrentHWProfile API to tell if my laptop was docked or undocked.
I've tried converting this call without success as I haven't found anything
in .NET Framework yet that will give this information.

The converted program gives a SystemExecutionEngineException. The code is
currently as follows:

REM------------------------------
REM API for checking docked state
REM------------------------------
Private Const HW_PROFILE_GUIDLEN = 39 ' 36-characters plus NULL
terminator
Private Const MAX_PROFILE_LEN = 80
Private Const DOCKINFO_UNDOCKED = 1
Private Const DOCKINFO_DOCKED = 2
Private Const DOCKINFO_USER_SUPPLIED = 4
Private Const DOCKINFO_USER_UNDOCKED = (DOCKINFO_USER_SUPPLIED And
DOCKINFO_UNDOCKED)
Private Const DOCKINFO_USER_DOCKED = (DOCKINFO_USER_SUPPLIED And
DOCKINFO_DOCKED)
<StructLayout(LayoutKind.Sequential)> Private Structure tHW_PROFILE_INFO
Dim dwDockInfo As Integer
Dim szHwProfileGuid As String
Dim szHwProfileName As String
End Structure
Private Declare Function GetCurrentHwProfile Lib "advapi32.dll" _
Alias "GetCurrentHwProfileA" _
(ByRef lpHwProfileInfo As tHW_PROFILE_INFO) As Boolean
Public Const PCDesktop = 0 ' Docking state doesn't apply - PC is a
desktop machine
Public Const PCUndocked = 1
Public Const PCDocked = 2
Public Const PCDockUndetermined = 12

Public Function PCDockingStatus(ByRef MSG As String) As Integer
Dim uHW As tHW_PROFILE_INFO
Dim buffer As New System.Text.StringBuilder(" ", HW_PROFILE_GUIDLEN)
uHW.szHwProfileGuid = buffer.ToString
Dim buffer2 As New System.Text.StringBuilder(" ", MAX_PROFILE_LEN)
uHW.szHwProfileName = buffer2.ToString ' Expand the string area
Try
If GetCurrentHwProfile(uHW) <> 0 Then ' If the call worked?
If uHW.dwDockInfo And DOCKINFO_DOCKED Then ' If "Docked"
returned
PCDockingStatus = PCDocked
MSG = "DOCKED LAPTOP PC"
ElseIf uHW.dwDockInfo And DOCKINFO_UNDOCKED Then ' If
"Undocked" returned
PCDockingStatus = PCUndocked
MSG = "UNDOCKED LAPTOP PC"
Else ' Something else was returned
MSG = "GetCurrentHwProfile RETURNED UNEXPECTED VALUE - "
& uHW.dwDockInfo
End If
Else
MSG = "GetCurrentHwProfile FAILED"
End If
Catch
MsgBox(Err.Description)
End Try

End Function


The exception occurs at the line If GetCurrentHwProfile(uHW) <> 0 Then ' If
the call worked?
I have tried variants of the above e.g. Defining the function as Auto and
then Ascii, defining the buffer and buffer2 variables as ordinary strings
instead of using Stringbuilder and pointing the uHW.szHwProfile.... fields
directly at the variables etc but whatever I do I get
SystemExecutionEngineException...

I suspect it is something to do with strings because when I look at the uHW
structure contents after the crash, a number has appeared in the dwDockInfo
field but the two string fields that follow are empty.

Regards,

Brian.

Brian,

Without testing it... It looks to me like the problem is the
declarations - especially the structure. I would think it should
look more like:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Private Structure tHW_PROFILE_INFO
Dim dwDockInfo As Integer

// set size const for this
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=HW_PROFILE_GUIDLEN)> _
Dim szHwProfileGuid As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PROFILE_LEN)> _
Dim szHwProfileName As String
End Structure

Private Declare Auto Function GetCurrentHwProfile Lib "advapi32.dll" _
(ByRef lpHwProfileInfo As tHW_PROFILE_INFO) As Boolean

Public Function PCDockingStatus(ByRef MSG As String) As Integer
Dim uHW As tHW_PROFILE_INFO

Try
If GetCurrentHwProfile(uHW) <> 0 Then ' If the call worked?
If uHW.dwDockInfo And DOCKINFO_DOCKED Then ' If "Docked" returned
PCDockingStatus = PCDocked
MSG = "DOCKED LAPTOP PC"
ElseIf uHW.dwDockInfo And DOCKINFO_UNDOCKED Then ' If "Undocked" returned
PCDockingStatus = PCUndocked
MSG = "UNDOCKED LAPTOP PC"
Else ' Something else was returned
MSG = "GetCurrentHwProfile RETURNED UNEXPECTED VALUE - " & uHW.dwDockInfo
End If
Else
MSG = "GetCurrentHwProfile FAILED"
End If
Catch
MsgBox(Err.Description)
End Try
End Function

See the structure contains fixed lenght strings, so it needs special
marshalling. I removed the alias, and am letting the system call the
most appropriate version. Anyway, I haven't tested this code, but there
you have it :)

HTH
 
Back
Top