API GetUserObjectInformation

All,

I am currently developing a program that will enable users to create and switch desktops as they so please. However, I am having a bit of trouble with the GetUserObjectInformation API. I either get a value of 0 being returned or so many errors I am about to go nuts. Does anyone know the correct way of calling this in VB.Net 2005. I have tried many different variations but none seem to work. I do know that I need to call it once to get the lpnLengthNeeded which will then ReDim pvInfo(lpnLengthNeeded - 1) so that it will be able to hold all of the data. Now nLength I am not sure exactly what needs to go their as I am so lost right now I don't know which way I'm going.

Here is the link to the documentation from MS in C. So if anyone knows how to do it please let me know. I am trying to get the Desktop Name in case you were wondering. Thanks.

http://msdn.microsoft.com/library/default.asp url=/library/en-us/dllproc/base/getuserobjectinformation.asp

Also, here is a link to EE that I have been trying to get some feedback on if you need what all I have tried.

http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21715367.html

Jason



Answer this question

API GetUserObjectInformation

  • Bruno Denuit - MSFT

    Okay. Here is my form load and the declaration

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _

    Public Function GetUserObjectInformation(ByVal hObj As IntPtr, ByVal nIndex As Int32, ByRef pvInfo As Byte(), ByVal nLength As Byte(), ByRef lpnLengthNeeded As Integer) As Boolean

    End Function

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim i As Short

    Dim tempDesktopName As String

    Dim tempDesktopHandle As Integer

    'Check to see if INI File Exists

    If System.IO.File.Exists(INIFILE) = False Then

    System.IO.File.Create(INIFILE).Close()

    End If

    GetDesktopName()

    'Get Desktop Count and Set Auto Switch to Value

    DesktopCount = GetFromINI("Main", "Desktop Count", 1, INIFILE)

    btnAutoSwitch.Checked = GetFromINI("Main", "Auto Switch", False, INIFILE)

    'Get Default Desktop Information

    Try

    tDefaultDesktop = GetThreadDesktop(GetCurrentThreadId())

    hDefaultDesktop = OpenInputDesktop(0, False, DESKTOP_SWITCHDESKTOP)

    sDefaultDesktop = "Default"

    Catch ex As Exception

    MsgBox("Error Code: " & Err.LastDllError, MsgBoxStyle.Critical, "Open Input Desktop Error")

    End Try

    'Setup Desktops

    If DesktopCount > 1 Then

    For i = 1 To DesktopCount - 1

    tempDesktopName = GetFromINI("Desktop" & i, "Desktop Name", Nothing, INIFILE)

    If tempDesktopName <> "" Then

    Try

    tempDesktopHandle = CreateDesktop(tempDesktopName, Nothing, 0, 0, GENERIC_ALL, 0)

    Catch ex As Exception

    MsgBox("Error Code: " & Err.LastDllError, MsgBoxStyle.Critical, "Create Desktop Error")

    End Try

    If tempDesktopHandle <> 0 Then

    btnToolStrip = New ToolStripButton

    With btnToolStrip

    .Text = tempDesktopName

    .ToolTipText = "Desktop" & i

    End With

    ToolStrip1.Items.Add(btnToolStrip)

    End If

    End If

    Next

    End If

    'Register Bar

    Try

    RegisterBar()

    Catch ex As Exception

    MsgBox("Error: " & ex.Message, MsgBoxStyle.Critical, "Register Bar Error")

    End Try

    'Disable btnDefaultDesktop since we always start here

    btnDefault.Enabled = False

    'Setup Current Desktop

    hCurrentDesktop = hDefaultDesktop

    sCurrentDesktop = "Default"

    End Sub

    Private Function GetDesktopName() As String

    Const ERROR_INSUFFICIENT_BUFFER& = 122

    Const ERROR_PROC_NOT_FOUND& = 127

    Dim buffer(15) As Byte

    Dim lpNeeded As Integer

    Dim threadID As Integer = GetCurrentThreadId()

    Dim desktop As IntPtr = GetThreadDesktop(threadID)

    Dim nLength() As Byte

    Try

    GetUserObjectInformation(desktop, UOI_NAME, Nothing, nLength, lpNeeded)

    Catch ex As Exception

    MsgBox(Err.LastDllError)

    End Try

    If lpNeeded <> 0 Then

    ReDim buffer(lpNeeded - 1)

    ReDim nLength(lpNeeded - 1)

    Try

    GetUserObjectInformation(desktop, UOI_NAME, buffer, nLength, lpNeeded + 1)

    Catch ex As Exception

    MsgBox(Err.LastDllError)

    End Try

    Dim i As Integer = 0

    For i = 0 To buffer.Length - 1

    MsgBox(buffer(i).ToString)

    Next

    End If

    End Function

    Now the thing is that in the GetDesktopName() Function is just a cluster. I am trying to do the best I can with it. Let me know if you need to see anymore of the code. But that is pretty much it. Basically what I need to do is get the desktopname on startup of the application since I can't move the process to a different desktop while it has hooks in a different one. So I have to Create another Process of the current application.

    Thanks.

    Jason


  • SujathaJaganathan

    Mattias,

    Thank you very much. We had tried the StringBuilder method before but we left nLength as an Integer. So we kept getting an error or it returned nothing. Any who. Here is the code again how I used it.

    API Declaration
    Public Declare Function GetUserObjectInformation Lib "user32" Alias "GetUserObjectInformationA" (ByVal hObj As IntPtr, ByVal nIndex As Int32, ByVal pvInfo As System.Text.StringBuilder, ByVal nLength As Byte, ByRef lpnLengthNeeded As Integer) As Boolean


    Form1_Load Event

    Dim lengthNeeded As Integer
    Dim pvInfo As New System.Text.StringBuilder

    GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, pvInfo, Nothing, lengthNeeded)

    If lengthNeeded <> 0 Then
    GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, pvInfo, lengthNeeded, lengthNeeded)
    MsgBox(pvInfo.ToString)
    End If

    Thanks again. Very much appreciate it. :)

    Jason


  • BPeck

    Your declaration is overly generic. If you know you're going to request UOI_NAME you may as well type the pvInfo parameter accordingly. I think this should work better

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _

    Public Function GetUserObjectInformation(ByVal hObj As IntPtr, ByVal nIndex As Int32, ByVal pvInfo As StringBuilder, ByVal nLength As Byte, ByRef lpnLengthNeeded As Integer) As Boolean



  • hal9000plus

    Sorry, nLength should be an Integer, I accidentally left it as Byte.

    You should also make sure your StringBuilder is large enough with the line

    pvInfo = New StringBuilder(lengthNeeded)



  • noahmattern

    Jason,

    Can we see the code around the call to getobject and it's declaration in your project



  • API GetUserObjectInformation