Question Sending LAN messages using WTSSendMessage

fruitloopy

New member
Joined
Apr 22, 2014
Messages
1
Programming Experience
Beginner
I'm starting to lose the will to live...:crying:

I am developing a desktop support application for the team here and so far it is going well, even though I am a complete newbie to Visual Studio 2012.
The part I am stuck on is being able to send messages through the LAN to a remote PC. With some help I have managed to send it to my own PC using the WTSSendMessage function of wtsapi32.dll but I cannot figure out how to send it to a remote PC. I have been told it should use WTSOpenServer but I just cannot figure it out.

There seems to be no help out there in Google land and certainly none using VB.Net instead of C++.

Has anyone been able to puzzle this out? It seems like such a simple thing to want to do but so bloody complicated!

This is the original code that displays a message on my own PC:

VB.NET:
Public Class Message

    Private Sub Shutdown_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        txtPCName.Text = Main.txtHostName.Text()
    End Sub


    <DllImport("wtsapi32.dll", SetLastError:=True)> _
    Private Shared Function WTSSendMessage(ByVal hServer As IntPtr, ByVal SessionId As Int32, ByVal title As String, ByVal titleLength As UInt32, ByVal message As String, ByVal messageLength As UInt32, ByVal style As UInt32, ByVal timeout As UInt32, ByRef pResponse As UInt32, ByVal bWait As Boolean) As Boolean
    End Function




    Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
        If Main.Reachable(txtPCName.Text) Then
            Dim MyReg As Microsoft.Win32.RegistryKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, txtPCName.Text)
            Dim MyRegKey As Microsoft.Win32.RegistryKey
            MyRegKey = MyReg.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", True)
            MyRegKey.SetValue("PromptOnSecureDesktop", 1, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey = MyReg.OpenSubKey("SYSTEM\CurrentControlSet\Control\Terminal Server", True)
            MyRegKey.SetValue("AllowRemoteRPC", 1, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey.Close()
        End If
        'Dim Message = txtMessage.Text
        Dim result = MessageBox.Show("The computer " & txtPCName.Text & " will be sent the message you typed, are you sure you want to do this?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
        If result = Windows.Forms.DialogResult.Yes Then
            Dim errorCode As String
            Dim response As Integer = MessageService.SendMessage("Hello Kitty", "My name is Bob", errorCode)
        ElseIf result = Windows.Forms.DialogResult.No Then
            Dim MyReg As Microsoft.Win32.RegistryKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, txtPCName.Text)
            Dim MyRegKey As Microsoft.Win32.RegistryKey
            MyRegKey = MyReg.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", True)
            MyRegKey.SetValue("PromptOnSecureDesktop", 0, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey = MyReg.OpenSubKey("SYSTEM\CurrentControlSet\Control\Terminal Server", True)
            MyRegKey.SetValue("AllowRemoteRPC", 0, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey.Close()
        End If
    End Sub


    Public Class MessageService
        Public Shared Function SendMessage(title As String, message As String, ByRef errorCode As String) As Integer
            Dim WTS_CURRENT_SERVER_HANDLE As IntPtr = IntPtr.Zero
            Dim WTS_CURRENT_SESSION As Integer = -1
            Dim tlen As Integer = title.Length
            Dim mlen As Integer = message.Length
            Dim response As Integer = 0
            Dim result As Boolean = WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, title, tlen, message, mlen, _
                0, 0, response, False)
            Dim err As Integer = Marshal.GetLastWin32Error()
            Return response
        End Function
    End Class
End Class

And this is the code I have (poorly) attempted to use to send it to a remote PC:

VB.NET:
Public Class Message


    Private Sub Shutdown_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        txtPCName.Text = Main.txtHostName.Text()
    End Sub


    <DllImport("wtsapi32.dll", SetLastError:=True)> _
    Private Shared Function WTSSendMessage(ByVal hServer As IntPtr, ByVal SessionId As Int32, ByVal title As String, ByVal titleLength _
                                           As UInt32, ByVal message As String, ByVal messageLength As UInt32, ByVal style As UInt32, ByVal timeout _
                                           As UInt32, ByRef pResponse As UInt32, ByVal bWait As Boolean) As Boolean
    End Function
[B]    <DllImport("wtsapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _[/B]
[B]    Private Shared Function WTSOpenServer(ByVal pServer As String) As IntPtr[/B]
[B]    End Function[/B]


    Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
        If Main.Reachable(txtPCName.Text) Then
            Dim MyReg As Microsoft.Win32.RegistryKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, txtPCName.Text)
            Dim MyRegKey As Microsoft.Win32.RegistryKey
            MyRegKey = MyReg.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", True)
            MyRegKey.SetValue("PromptOnSecureDesktop", 1, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey = MyReg.OpenSubKey("SYSTEM\CurrentControlSet\Control\Terminal Server", True)
            MyRegKey.SetValue("AllowRemoteRPC", 1, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey.Close()
        End If
        'Dim Message = txtMessage.Text
        Dim result = MessageBox.Show("The computer " & txtPCName.Text & " will be sent the message you typed, are you sure you want to do this?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
        If result = Windows.Forms.DialogResult.Yes Then


            Dim errorCode As String
            Dim response As String = MessageService.SendMessage(txtPCName.Text, "Hello Kitty", "My name is Bob", errorCode)
        ElseIf result = Windows.Forms.DialogResult.No Then
            Dim MyReg As Microsoft.Win32.RegistryKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, txtPCName.Text)
            Dim MyRegKey As Microsoft.Win32.RegistryKey
            MyRegKey = MyReg.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", True)
            MyRegKey.SetValue("PromptOnSecureDesktop", 0, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey = MyReg.OpenSubKey("SYSTEM\CurrentControlSet\Control\Terminal Server", True)
            MyRegKey.SetValue("AllowRemoteRPC", 0, Microsoft.Win32.RegistryValueKind.DWord)
            MyRegKey.Close()
        End If
    End Sub


    Public Class MessageService
        Public Shared Function SendMessage([B]pServerName As String, [/B]title As String, message As String, ByRef errorCode As String) As Integer
[B]            Dim txtPCName = Main.txtHostName.Text()[/B]
[B]            Dim pServer As String = WTSOpenServer(txtPCName)[/B]
            Dim WTS_CURRENT_SESSION As Integer = -1
            Dim tlen As Integer = title.Length
            Dim mlen As Integer = message.Length
            Dim response As Integer = 0
            Dim result As Boolean = WTSSendMessage([B]pServer[/B], WTS_CURRENT_SESSION, title, tlen, message, mlen, 0, 0, response, False)
            Dim err As Integer = Marshal.GetLastWin32Error()
            Return response
        End Function
    End Class
End Class

Nothing happens when I test it. Any thoughts?
 
Back
Top