Update: UltraVNC 1.4.3.6 and UltraVNC SC 1.4.3.6: viewtopic.php?t=37885
Important: Please update to latest version before to create a reply, a topic or an issue: viewtopic.php?t=37864

Join us on social networks and share our announcements:
- Website: https://uvnc.com/
- GitHub: https://github.com/ultravnc
- Mastodon: https://mastodon.social/@ultravnc
- Facebook: https://www.facebook.com/ultravnc1
- X/Twitter: https://twitter.com/ultravnc1
- Reddit community: https://www.reddit.com/r/ultravnc
- OpenHub: https://openhub.net/p/ultravnc

Service installation if supported user is no admin

Simple, Free, Open Source UltraVNC Wrapper Supporting Windows and Mac OSX
Post Reply
mas
Posts: 4
Joined: 2014-11-22 21:45

Service installation if supported user is no admin

Post by mas »

Based on ChunkVNC 3.3.1 I tried to enhance the InstantSupport.au3 as suggested in the thread "UAC - how to interact with UAC or disable it?". But this solution didn't elevate at least with win7 and win8.

The changed InstantSupport.au3 will do the following:

When starting to install as service, the user is asked for an admin user (and domain and password). I user is left empty, the installation starts with the current user.
Additionally it ask, whether installation should be permament. If not, the script keeps running and will allow to uninstall the service later (with the given credentials). It will also ask to uninstall, when leaving the script. After uninstallation the normal vnc-server is restartet, perhaps with the changed ID.

I also included a public key file "InstantSupport.pubkey", so that the communication will be encrypted. Of course you have to generate a pair and include the private key in the viewer\bin directory.

Third, I added german messages (simply change the "If False Then" into "If True Then" or remove the unwanted messages) and an additional german "firewall close".

Here is the complete and tested InstantSupport.au3

Code: Select all

#AutoIt3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/StripOnly

; Disable the scripts ability to pause.
Break(0)

#include "Aut2Exe\Include\GUIConstantsEx.au3"
#include "Aut2Exe\Include\StaticConstants.au3"
#include "Aut2Exe\Include\WindowsConstants.au3"
#include "Aut2Exe\Include\ServiceControl.au3"


; Exit if the script hasn't been compiled
If Not @Compiled Then
        MsgBox(0, "ERROR", 'Script must be compiled before running!', 5)
        Exit
EndIf


; Language strings.
If False Then
$str_Program_Title =                                    "Fernwartung"
$str_Button_InstallService =                            "Als Dienst installieren"
$str_Button_UninstallService =                          "Dienst deinstallieren"
$str_Button_Exit =                                      "Ende"
$str_MsgBox_Information =                               "Information"
$str_MsgBox_ServiceInstallation =                       "Dienst installieren"
$str_MsgBox_Error =                                     "Fehler"
$str_MsgBox_RemoveService =                             "Dienst entfernen und deinstallieren?"
$str_ServiceEnterAnIDNumber =                           "ID eingeben:"
$str_ServiceAdminRequirerd =                            "Adminrechte erforderlich"
$str_ServiceUsername =                                  "Benutzername des Administrators (oder leer, falls Administrator bereits angemeldet):"
$str_ServiceDomain =                                    "Domainname or Computername bei lokalem Account:"
$str_ServicePassword =                                  "Passwort:"
$str_ServicePermanent =                                 "Dienst dauerhaft installieren?"
$str_ServiceInvalidID =                                 "Falsche ID, Dienstinstallation abgebrochen."
$str_ServiceInstallFailed =                             "Dienstinstallation gescheitert, Supportmodul wieder gestartet."
$str_ServiceProxy =                                     "Installation als Dienst mit HTTP-Proxy nicht möglich."
$str_ErrorInstallService =                              "Installation als Dienst benötigt Administratorrechte."
$str_ErrorStopService =                                 "Um den VNC-Dienst zu stoppen, werden Administratorrechte benötigt."
$str_ErrorUnknownCommand =                              "Unbekanntes Kommando."
$str_ErrorRepeaterConnectionFailed =                    "Verbindung zum Repeater gescheitert."
$str_EndSupportSession =                                "Wollen Sie die Fernwartungssitzung tatsächlich beenden?"
$str_CloseOtherVNCServers =                             "Ein anderer VNC-Server läuft und muß gestoppt werden. Soll ich versuchen, den zu stoppen?"
Else
$str_Program_Title =                                    "Instant Support"
$str_Button_InstallService =                            "Install As Service"
$str_Button_UninstallService =                          "Uninstall Service"
$str_Button_Exit =                                      "Exit"
$str_MsgBox_Information =                               "Information"
$str_MsgBox_ServiceInstallation =                       "Service Installation"
$str_MsgBox_Error =                                     "Error"
$str_MsgBox_RemoveService =                             "Remove Service and Uninstall?"
$str_ServiceEnterAnIDNumber =                           "Enter an ID number:"
$str_ServiceAdminRequirerd =                            "Adminrights required"
$str_ServiceUsername =                                  "Username of an administrator (oder empty, if logged in user is admin):"
$str_ServiceDomain =                                    "Domain or Computername (when local admin account):"
$str_ServicePassword =                                  "Password:"
$str_ServicePermanent =                                 "Install service permanent?"
$str_ServiceInvalidID =                                 "Invalid ID entered, service installation canceled."
$str_ServiceInstallFailed =                             "Service installation failed, InstantSupport restarted."
$str_ServiceProxy =                                     "Service installation not supported when using HTTP Proxy."
$str_ErrorInstallService =                              "Installing service requires administrator privileges."
$str_ErrorStopService =                                 "Stopping VNC services requires administrator privileges."
$str_ErrorUnknownCommand =                              "Unknown command."
$str_ErrorRepeaterConnectionFailed =                    "Connection to the repeater was not possible."
$str_EndSupportSession =                                "Are you sure you want to end this support session?"
$str_CloseOtherVNCServers =                             "Another VNC server is running which must be stopped. Try to stop other VNC server?"
EndIf


; Global Vars.
Global $ExtractFiles = True
Global $GenerateID = True
Global $LanMode = False
Global $IDNumber = 123456
Global $WorkingPath = @AppDataDir & "\InstantSupport_Temp_Files"
Global $ProxyEnabled = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable")


; Create unique working path if our default directory already exists. (Possible InstantSupport is already running)
If FileExists( @AppDataDir & "\InstantSupport_Temp_Files" ) Then
        $WorkingPath = @AppDataDir & "\InstantSupport_Temp_Files_" & Random( 100000, 999999,1 )
EndIf


; Command line args.
If $cmdline[0] > 0 Then
        Switch $cmdline[1]

                Case "-elevateinstall"
                        InstallElevated()
                        Exit

                Case "-installservice"
                        If IsAdmin() Then

                                InstallService()
                                Exit

                        Else

                                MsgBox( 0, $str_MsgBox_Error, $str_ErrorInstallService, 30 )
                                Exit

                        EndIf

                Case "-removeservice"
                        If IsAdmin() Then

                                RemoveService()
                                Exit

                        Else
                                UninstallElevated ()
                                Exit

                        EndIf

                Case "-stopservices"
                        If IsAdmin() Then

                                StopServices()
                                Exit

                        Else

                                MsgBox( 0, $str_MsgBox_Error, $str_ErrorStopService, 30 )
                                Exit

                        EndIf

                Case Else
                        MsgBox( 0 , $str_MsgBox_Error, $str_ErrorUnknownCommand, 30 )
                        Exit

        EndSwitch
EndIf


; Extract files.
If $ExtractFiles Then

        DirCreate( $WorkingPath )
        FileInstall( "InstantSupport_Files\instantsupport.ini", $WorkingPath & "\instantsupport.ini", 1 )
        FileInstall( "InstantSupport_Files\logo.jpg", $WorkingPath & "\logo.jpg", 1 )
        FileInstall( "InstantSupport_Files\SecureVNCPlugin.dsm", $WorkingPath & "\SecureVNCPlugin.dsm", 1 )
        FileInstall( "InstantSupport_Files\ultravnc.ini", $WorkingPath & "\ultravnc.ini", 1 )
        FileInstall( "InstantSupport_Files\winvnc.exe", $WorkingPath & "\InstantSupportVNC.exe", 1 )
        FileInstall( "InstantSupport_Files\unblock.js", $WorkingPath & "\unblock.js", 1 )
        FileInstall( "InstantSupport_Files\InstantSupport.pubkey", $WorkingPath & "\InstantSupport.pubkey", 1 )

        ; Unblock InstantSupport.exe to prevent "Windows Security" messages.
        ShellExecuteWait($WorkingPath & "\unblock.js", "", @ScriptDir, "")

        FileCopy( @ScriptDir & "\" & @ScriptName, $WorkingPath & "\InstantSupport.exe", 9 )

EndIf


; Close known VNC servers. --NEEDS WORK--
If ProcessExists( "InstantSupportVNC.exe" ) Or ProcessExists( "WinVNC.exe" ) Then

        If MsgBox( 4, $str_Program_Title, $str_CloseOtherVNCServers ) = 6 Then

                ; Stop services if running.
                If _ServiceRunning("", "uvnc_service") or _ServiceRunning("", "winvnc") Then
                        If IsAdmin() Then

                                ShellExecuteWait($WorkingPath & "\InstantSupport.exe", "-stopservices", @ScriptDir, "")

                        Else

                                ShellExecuteWait($WorkingPath & "\InstantSupport.exe", "-stopservices", @ScriptDir, "runas")

                        EndIf
                        Sleep(10000)
                EndIf

                ; Kill user mode VNC servers.
                Run( $WorkingPath & "\InstantSupportVNC.exe -kill" )
                Sleep(10000)

                ; Kill InstantSupport if running.
                If WinExists( $str_Program_Title ) Then

                                WinClose( $str_Program_Title )
                                Sleep( 500 )
                                Send( "{ENTER}" ) ; Let the other InstantSupport process close normally so it can cleanup.
                                Sleep( 500 )
                EndIf

        Else

                InstantSupportExit( True )

        EndIf

EndIf


; Read server settings from instantsupport.ini.
$RepeaterAddress = IniRead( $WorkingPath & "\instantsupport.ini", "Repeater", "Address", "" )
$RepeaterAddressLAN = IniRead( $WorkingPath & "\instantsupport.ini", "Repeater", "AddressLAN", "" )
$RepeaterServerPort = IniRead( $WorkingPath & "\instantsupport.ini", "Repeater", "ServerPort", "" )


; Generate a random ID Number between 200,000 and 999,999 or read the installed ID number.
If $GenerateID Then

        $LowerLimit = 200000
        $UpperLimit = 999999
        $IDNumber = Random( $LowerLimit,$UpperLimit,1 )

Else

        $IDNumber = IniRead( $WorkingPath & "\instantsupport.ini", "InstantSupport", "ID", "" )

EndIf


; Create the GUI.
$InstantSupport = GUICreate( $str_Program_Title, 450, 200, -1, -1, BitOR( $WS_SYSMENU,$WS_CAPTION,$WS_POPUP,$WS_POPUPWINDOW,$WS_BORDER,$WS_CLIPSIBLINGS,$WS_MINIMIZEBOX ) )
GUISetBkColor( 0xFFFFFF )
$Label2 = GUICtrlCreateLabel( $IDNumber, 0, 100, 450, 100, $SS_CENTER )
GUICtrlSetFont( -1, 50, 800, 0, "Arial Black" )
$Pic1 = GUICtrlCreatePic( $WorkingPath & "\logo.jpg", 0, 0, 450, 90, BitOR( $SS_NOTIFY,$WS_GROUP,$WS_CLIPSIBLINGS ) )
GUISetState( @SW_SHOW )
WinSetOnTop( $str_Program_Title, "",1)


; Check to see if the repeater exists unless there is a proxy.
If $ProxyEnabled = False Then

        TCPStartUp()

        ; Test WAN address first.
        $socket = TCPConnect( TCPNameToIP( $RepeaterAddress ), $RepeaterServerPort )
        If $socket = -1 Then $LanMode = True

        ; Test LAN Address because WAN failed.
        If $LanMode = True Then

                $socket = TCPConnect( TCPNameToIP( $RepeaterAddressLAN ), $RepeaterServerPort )

                If $socket = -1 Then

                        ; No connections possible, exit.
                        WinSetOnTop( $str_Program_Title, "",0 )
                        MsgBox( 48, $str_MsgBox_Error, $str_ErrorRepeaterConnectionFailed, 10 )
                        InstantSupportExit( True )

                EndIf

        EndIf

        TCPShutdown()

EndIf

StartWinVNC()

$ServiceTemporarilyInstalled = False

; Create the tray icon. Default tray menu items (Script Paused/Exit) will not be shown.
Opt( "TrayMenuMode", 1 )
$InstallItem = TrayCreateItem( $str_Button_InstallService )
$ExitItem = TrayCreateItem( $str_Button_Exit )

; Enable the scripts ability to pause. (otherwise tray menu is disabled)
Break(1)

; Main loop.
While 1

        ; Close any windows firewall messages that popup. The windows firewall doesn't block outgoing connections anyways. ----Does the OS language change this?----
        If WinExists( "Windows Security Alert" ) Then WinClose( "Windows Security Alert" )
        If WinExists( "Windows-Sicherheitshinweis" ) Then WinClose( "Windows-Sicherheitshinweis" )

        ; If UltraVNC can't connect to the repeater then exit.
        If WinExists( "Initiate Connection" ) Then

                ; Stop the VNC server
                ProcessClose( "InstantSupportVNC.exe" )
                ProcessWaitClose( "InstantSupportVNC.exe" )
                WinSetOnTop( $str_Program_Title, "",0 )
                MsgBox( 48, $str_MsgBox_Error, $str_ErrorRepeaterConnectionFailed )
                InstantSupportExit( True )

        EndIf

        ; Check for form events.
        $nMsg = GUIGetMsg()
        Switch $nMsg

                Case $GUI_EVENT_CLOSE

                        WinSetOnTop( $str_Program_Title, "",0 )
                        If MsgBox( 4, $str_Program_Title, $str_EndSupportSession ) = 6 Then

                                InstantSupportExit( True )

                        EndIf

        EndSwitch

        ; Tray events.
        $nMsg = TrayGetMsg()
        Switch $nMsg

                Case $InstallItem

                        If $ServiceTemporarilyInstalled Then
                              UninstallService ()
                              ;reactivate install option
                              TrayItemSetText( $InstallItem, $str_Button_InstallService )
                              $ServiceTemporarilyInstalled = False
      
                              StartWinVNC()
                        Else                  
                              ; Service installation unavailable if using an HTTP Proxy (UltraVNC limitation).
                              If $ProxyEnabled = True Then
      
                                      WinSetOnTop( $str_Program_Title, "",0 )
                                      MsgBox( 48, $str_MsgBox_Error, $str_ServiceProxy, 10 )
      
                              Else
                                      ; Choose ID for service installation.
                                      WinSetOnTop( $str_Program_Title, "",0 )
                                      $NewIDNumber = InputBox( $str_MsgBox_ServiceInstallation, $str_ServiceEnterAnIDNumber, $IDNumber ) +0                                
      
                                      If @error = 0 and IsNumber($NewIDNumber) and $NewIDNumber > 200000 and $NewIDNumber < 999999 Then
      
                                              $IDNumber = $NewIDNumber
                                              GUICtrlSetData ( $label2, $IDNumber )
                                              
                                              ; Configure ultravnc.ini
                                              If $LanMode = True Then
      
                                                      IniWrite( $WorkingPath & "\ultravnc.ini", "admin", "service_commandline", '-autoreconnect ID:' & $IDNumber & ' -connect ' & $RepeaterAddressLAN & ":" & $RepeaterServerPort )
      
                                              Else
      
                                                      IniWrite( $WorkingPath & "\ultravnc.ini", "admin", "service_commandline", '-autoreconnect ID:' & $IDNumber & ' -connect ' & $RepeaterAddress & ":" & $RepeaterServerPort )
      
                                              EndIf
      
                                              ; Configure instantsupport.ini
                                              IniWrite( $WorkingPath & "\instantsupport.ini", "InstantSupport", "ID", $IDNumber )
      
                                              $Cancelled = False
                                              $Username = InputBox( $str_ServiceAdminRequirerd, $str_ServiceUsername, "administrator" )
                                              If $Username <> "" Then
                                                    $Domain = InputBox( $str_ServiceAdminRequirerd, $str_ServiceDomain, @ComputerName)
                                                    If $Domain > "" Then
                                                          $Password = InputBox( $str_ServiceAdminRequirerd, $str_ServicePassword, "", "*" )
                                                          If $Password = "" Then
                                                                $Cancelled = (@error > 0)
                                                          EndIf
                                                    Else
                                                          $Cancelled = (@error > 0)
                                                    EndIf
                                              Else
                                                    $Cancelled = (@error > 0)                                             
                                              EndIf
                                    
                                              If Not $Cancelled Then
                                                    $InstallPermanent = (MsgBox( 4, $str_MsgBox_ServiceInstallation, $str_ServicePermanent ) = 6)
                                                    ; Kill the VNC server
                                                    $PID = Run( $WorkingPath & "\InstantSupportVNC.exe -kill" )
            
                                                    ; Wait for the winvnc server to close.
                                                    ProcessWaitClose( $PID, 15 )
            
                                                    ; Run installer after the server exits.
                                                    ProcessWaitClose( "InstantSupportVNC.exe" )
            
                                                    If $Username = "" Then
                                                          InstallElevated ($WorkingPath)
                                                    Else
                                                          ShellExecuteWait("icacls", $WorkingPath & " /grant " & $Domain & "\" & $Username & ":(CI)(OI)(F)")
                                                          RunAsWait($Username, $Domain, $Password, 0, $WorkingPath & "\InstantSupport.exe -elevateinstall", $WorkingPath)
                                                    EndIf
                                                    If ProcessWait ( "InstantSupportVNC.exe", 15 ) Then
                                                          ;service is running
                                                          If $InstallPermanent Then
                                                                ;Ok, we're done
                                                                InstantSupportExit( True )
                                                          Else
                                                                ;replace tray-option with uninstall
                                                                TrayItemSetText( $InstallItem, $str_Button_UninstallService )
                                                                $ServiceTemporarilyInstalled = True
                                                                WinSetOnTop( $str_Program_Title, "",1)
      
                                                          EndIf
                                                    Else
                                                          ;installation failed, restart VNC then inform user
                                                          StartWinVNC ()
                                                          MsgBox (0, $str_MsgBox_Information, $str_ServiceInstallFailed )
                                                    EndIf
                                              EndIf
      
                                      Else
                                              If @error = 0 Then
                                                    WinSetOnTop( $str_Program_Title, "",0 )
                                                    MsgBox( 0, $str_MsgBox_Information, $str_ServiceInvalidID )
                                              EndIf
      
                                      EndIf
      
                              EndIf
                        EndIf

                              
                Case $ExitItem

                        WinSetOnTop( $str_Program_Title, "",0 )
                        If MsgBox( 4, $str_Program_Title, $str_EndSupportSession ) = 6 Then

                                InstantSupportExit( True )

                        EndIf

        EndSwitch

WEnd

Func StartWinVNC ()

        ; Start the VNC server and make a reverse connection to the repeater.
        If $LanMode = True Then
                ShellExecute( $WorkingPath & "\InstantSupportVNC.exe", "-httpproxy -autoreconnect ID:" & $IDNumber & " -connect " & $RepeaterAddressLAN & ":" & $RepeaterServerPort & " -run" )
        Else
                ShellExecute( $WorkingPath & "\InstantSupportVNC.exe", "-httpproxy -autoreconnect ID:" & $IDNumber & " -connect " & $RepeaterAddress & ":" & $RepeaterServerPort & " -run" )
        EndIf
EndFunc      

Func InstallElevated($Path = @ScriptDir)
        ShellExecuteWait($Path & "\InstantSupport.exe", "-installservice", $Path, "runas")
EndFunc

Func UninstallElevated()
        ShellExecuteWait(@ProgramFilesDir & "\InstantSupport\InstantSupport.exe", "-removeservice", @ProgramFilesDir & "\InstantSupport\", "runas")
EndFunc

Func UninstallService ()
        ; remove temporarily installed service 
        If $Username = "" Then
              UninstallElevated ()
        Else
              RunAsWait($Username, $Domain, $Password, 0, $WorkingPath & "\InstantSupport.exe -removeservice", $WorkingPath)
        EndIf
EndFunc                              

Func InstallService()

        ; Copy files.
        FileCopy( @ScriptDir & "\*.*", @ProgramFilesDir & "\InstantSupport\", 9 )

        ; Create uninstall link on All Users desktop.
        FileCreateShortcut( @ProgramFilesDir & '\InstantSupport\InstantSupport.exe', @DesktopCommonDir & '\Uninstall Instant Support.lnk', "", "-removeservice" )

        ; Install VNC Service.
        ShellExecuteWait( @ProgramFilesDir & "\InstantSupport\InstantSupportVNC.exe", "-install" )

EndFunc


Func RemoveService()

        WinSetOnTop( $str_Program_Title, "",0 )
        If MsgBox( 4, $str_Program_Title, $str_MsgBox_RemoveService ) = 6 Then

                ; Remove Uninstaller
                FileDelete( @DesktopCommonDir & '\Uninstall Instant Support.lnk"' )

                ; Remove VNC Service.
                ShellExecuteWait( @ProgramFilesDir & "\InstantSupport\InstantSupportVNC.exe", "-uninstall" )
                
                ProcessWaitClose ( "InstantSupportVNC.exe", 15 )

                ; Remove the InstantSupport Service.
                _DeleteSelf( @ProgramFilesDir & "\InstantSupport", 10 )

        EndIf

EndFunc


Func _DeleteSelf( $Path, $iDelay = 5 )

        Local $sCmdFile

        FileDelete( @TempDir & "\scratch.bat" )


        $sCmdFile = 'PING -n ' & $iDelay & ' 127.0.0.1 > nul' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\InstantSupportVNC.exe"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\InstantSupport.exe"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\SecureVNCPlugin.dsm"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\ultravnc.ini"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\instantsupport.ini"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\logo.jpg"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\unblock.js"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\InstantSupport.pubkey"' & @CRLF _
                        & 'RMDIR "' & $Path & '"' & @CRLF _
                        & 'DEL "' & @TempDir & '\scratch.bat"'

        FileWrite( @TempDir & "\scratch.bat", $sCmdFile )

        Run( @TempDir & "\scratch.bat", @TempDir, @SW_HIDE )

EndFunc


Func InstantSupportExit( $DeleteFiles = False )

        If $ServiceTemporarilyInstalled Then
              UninstallService ()
        Else
              ; Kill the VNC server
              $PID = Run( $WorkingPath & "\InstantSupportVNC.exe -kill" )
      
              ; Wait for the winvnc server to close.
              ProcessWaitClose( $PID, 15 )
        EndIf

        ; Remove temp files.
        If $DeleteFiles Then _DeleteSelf( $WorkingPath, 5)

        Exit

EndFunc


Func StopServices()

        _StopService("", "uvnc_service")
        _StopService("", "winvnc")

EndFunc


I hope you enjoy the changes. Simply replace the original InstantSupport.au3, install the encryption files (or remove them from the script) and generate again.
mas
Posts: 4
Joined: 2014-11-22 21:45

Re: Service installation if supported user is no admin

Post by mas »

Found just two of the remaining errors in the script. First, a variable was initialized too late, so an error occured, when stopping a running vnc-server was not accepted. Second, changing the ID but aborting the afterwards altered the shown ID without restarting the vnc-server with this new ID. Now, the ID changes only if starting the service doesn't work and is then used for the vnc-server.

I add the complete file, there are several lines moved, which could be difficult to tell.

Code: Select all

#AutoIt3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/StripOnly

; Disable the scripts ability to pause.
Break(0)

#include "Aut2Exe\Include\GUIConstantsEx.au3"
#include "Aut2Exe\Include\StaticConstants.au3"
#include "Aut2Exe\Include\WindowsConstants.au3"
#include "Aut2Exe\Include\ServiceControl.au3"


; Exit if the script hasn't been compiled
If Not @Compiled Then
        MsgBox(0, "ERROR", 'Script must be compiled before running!', 5)
        Exit
EndIf


; Language strings.
If False Then
$str_Program_Title =                                    "Fernwartung"
$str_Button_InstallService =                            "Als Dienst installieren"
$str_Button_UninstallService =                          "Dienst deinstallieren"
$str_Button_Exit =                                      "Ende"
$str_MsgBox_Information =                               "Information"
$str_MsgBox_ServiceInstallation =                       "Dienst installieren"
$str_MsgBox_Error =                                     "Fehler"
$str_MsgBox_RemoveService =                             "Dienst entfernen und deinstallieren?"
$str_ServiceEnterAnIDNumber =                           "ID eingeben:"
$str_ServiceAdminRequirerd =                            "Adminrechte erforderlich"
$str_ServiceUsername =                                  "Benutzername des Administrators (oder leer, falls Administrator bereits angemeldet):"
$str_ServiceDomain =                                    "Domainname oder Computername bei lokalem Account:"
$str_ServicePassword =                                  "Passwort:"
$str_ServicePermanent =                                 "Dienst dauerhaft installieren?"
$str_ServiceInvalidID =                                 "Falsche ID, Dienstinstallation abgebrochen."
$str_ServiceInstallFailed =                             "Dienstinstallation gescheitert, Supportmodul wieder gestartet."
$str_ServiceProxy =                                     "Installation als Dienst mit HTTP-Proxy nicht möglich."
$str_ErrorInstallService =                              "Installation als Dienst benötigt Administratorrechte."
$str_ErrorStopService =                                 "Um den VNC-Dienst zu stoppen, werden Administratorrechte benötigt."
$str_ErrorUnknownCommand =                              "Unbekanntes Kommando."
$str_ErrorRepeaterConnectionFailed =                    "Verbindung zum Repeater gescheitert."
$str_EndSupportSession =                                "Wollen Sie die Fernwartungssitzung tatsächlich beenden?"
$str_CloseOtherVNCServers =                             "Ein anderer VNC-Server läuft und muß gestoppt werden. Soll ich versuchen, den zu stoppen?"
Else
$str_Program_Title =                                    "Instant Support"
$str_Button_InstallService =                            "Install As Service"
$str_Button_UninstallService =                          "Uninstall Service"
$str_Button_Exit =                                      "Exit"
$str_MsgBox_Information =                               "Information"
$str_MsgBox_ServiceInstallation =                       "Service Installation"
$str_MsgBox_Error =                                     "Error"
$str_MsgBox_RemoveService =                             "Remove Service and Uninstall?"
$str_ServiceEnterAnIDNumber =                           "Enter an ID number:"
$str_ServiceAdminRequirerd =                            "Adminrights required"
$str_ServiceUsername =                                  "Username of an administrator (oder empty, if logged in user is admin):"
$str_ServiceDomain =                                    "Domain or Computername (when local admin account):"
$str_ServicePassword =                                  "Password:"
$str_ServicePermanent =                                 "Install service permanent?"
$str_ServiceInvalidID =                                 "Invalid ID entered, service installation canceled."
$str_ServiceInstallFailed =                             "Service installation failed, InstantSupport restarted."
$str_ServiceProxy =                                     "Service installation not supported when using HTTP Proxy."
$str_ErrorInstallService =                              "Installing service requires administrator privileges."
$str_ErrorStopService =                                 "Stopping VNC services requires administrator privileges."
$str_ErrorUnknownCommand =                              "Unknown command."
$str_ErrorRepeaterConnectionFailed =                    "Connection to the repeater was not possible."
$str_EndSupportSession =                                "Are you sure you want to end this support session?"
$str_CloseOtherVNCServers =                             "Another VNC server is running which must be stopped. Try to stop other VNC server?"
EndIf


; Global Vars.
Global $ExtractFiles = True
Global $GenerateID = True
Global $LanMode = False
Global $IDNumber = 123456
Global $WorkingPath = @AppDataDir & "\InstantSupport_Temp_Files"
Global $ProxyEnabled = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable")


; Create unique working path if our default directory already exists. (Possible InstantSupport is already running)
If FileExists( @AppDataDir & "\InstantSupport_Temp_Files" ) Then
        $WorkingPath = @AppDataDir & "\InstantSupport_Temp_Files_" & Random( 100000, 999999,1 )
EndIf


; Command line args.
If $cmdline[0] > 0 Then
        Switch $cmdline[1]

                Case "-elevateinstall"
                        InstallElevated()
                        Exit

                Case "-installservice"
                        If IsAdmin() Then

                                InstallService()
                                Exit

                        Else

                                MsgBox( 0, $str_MsgBox_Error, $str_ErrorInstallService, 30 )
                                Exit

                        EndIf

                Case "-removeservice"
                        If IsAdmin() Then

                                RemoveService()
                                Exit

                        Else
                                UninstallElevated ()
                                Exit

                        EndIf

                Case "-stopservices"
                        If IsAdmin() Then

                                StopServices()
                                Exit

                        Else

                                MsgBox( 0, $str_MsgBox_Error, $str_ErrorStopService, 30 )
                                Exit

                        EndIf

                Case Else
                        MsgBox( 0 , $str_MsgBox_Error, $str_ErrorUnknownCommand, 30 )
                        Exit

        EndSwitch
EndIf


; Extract files.
If $ExtractFiles Then

        DirCreate( $WorkingPath )
        FileInstall( "InstantSupport_Files\instantsupport.ini", $WorkingPath & "\instantsupport.ini", 1 )
        FileInstall( "InstantSupport_Files\logo.jpg", $WorkingPath & "\logo.jpg", 1 )
        FileInstall( "InstantSupport_Files\SecureVNCPlugin.dsm", $WorkingPath & "\SecureVNCPlugin.dsm", 1 )
        FileInstall( "InstantSupport_Files\ultravnc.ini", $WorkingPath & "\ultravnc.ini", 1 )
        FileInstall( "InstantSupport_Files\winvnc.exe", $WorkingPath & "\InstantSupportVNC.exe", 1 )
        FileInstall( "InstantSupport_Files\unblock.js", $WorkingPath & "\unblock.js", 1 )
        FileInstall( "InstantSupport_Files\InstantSupport.pubkey", $WorkingPath & "\InstantSupport.pubkey", 1 )

        ; Unblock InstantSupport.exe to prevent "Windows Security" messages.
        ShellExecuteWait($WorkingPath & "\unblock.js", "", @ScriptDir, "")

        FileCopy( @ScriptDir & "\" & @ScriptName, $WorkingPath & "\InstantSupport.exe", 9 )

EndIf

$ServiceTemporarilyInstalled = False

; Close known VNC servers. --NEEDS WORK--
If ProcessExists( "InstantSupportVNC.exe" ) Or ProcessExists( "WinVNC.exe" ) Then

        If MsgBox( 4, $str_Program_Title, $str_CloseOtherVNCServers ) = 6 Then

                ; Stop services if running.
                If _ServiceRunning("", "uvnc_service") or _ServiceRunning("", "winvnc") Then
                        If IsAdmin() Then

                                ShellExecuteWait($WorkingPath & "\InstantSupport.exe", "-stopservices", @ScriptDir, "")

                        Else

                                ShellExecuteWait($WorkingPath & "\InstantSupport.exe", "-stopservices", @ScriptDir, "runas")

                        EndIf
                        Sleep(10000)
                EndIf

                ; Kill user mode VNC servers.
                Run( $WorkingPath & "\InstantSupportVNC.exe -kill" )
                Sleep(10000)

                ; Kill InstantSupport if running.
                If WinExists( $str_Program_Title ) Then

                                WinClose( $str_Program_Title )
                                Sleep( 500 )
                                Send( "{ENTER}" ) ; Let the other InstantSupport process close normally so it can cleanup.
                                Sleep( 500 )
                EndIf

        Else

                InstantSupportExit( True )

        EndIf

EndIf


; Read server settings from instantsupport.ini.
$RepeaterAddress = IniRead( $WorkingPath & "\instantsupport.ini", "Repeater", "Address", "" )
$RepeaterAddressLAN = IniRead( $WorkingPath & "\instantsupport.ini", "Repeater", "AddressLAN", "" )
$RepeaterServerPort = IniRead( $WorkingPath & "\instantsupport.ini", "Repeater", "ServerPort", "" )


; Generate a random ID Number between 200,000 and 999,999 or read the installed ID number.
If $GenerateID Then

        $LowerLimit = 200000
        $UpperLimit = 999999
        $IDNumber = Random( $LowerLimit,$UpperLimit,1 )

Else

        $IDNumber = IniRead( $WorkingPath & "\instantsupport.ini", "InstantSupport", "ID", "" )

EndIf


; Create the GUI.
$InstantSupport = GUICreate( $str_Program_Title, 450, 200, -1, -1, BitOR( $WS_SYSMENU,$WS_CAPTION,$WS_POPUP,$WS_POPUPWINDOW,$WS_BORDER,$WS_CLIPSIBLINGS,$WS_MINIMIZEBOX ) )
GUISetBkColor( 0xFFFFFF )
$Label2 = GUICtrlCreateLabel( $IDNumber, 0, 100, 450, 100, $SS_CENTER )
GUICtrlSetFont( -1, 50, 800, 0, "Arial Black" )
$Pic1 = GUICtrlCreatePic( $WorkingPath & "\logo.jpg", 0, 0, 450, 90, BitOR( $SS_NOTIFY,$WS_GROUP,$WS_CLIPSIBLINGS ) )
GUISetState( @SW_SHOW )
WinSetOnTop( $str_Program_Title, "",1)

$ServiceTemporarilyInstalled = False

; Check to see if the repeater exists unless there is a proxy.
If $ProxyEnabled = False Then

        TCPStartUp()

        ; Test WAN address first.
        $socket = TCPConnect( TCPNameToIP( $RepeaterAddress ), $RepeaterServerPort )
        If $socket = -1 Then $LanMode = True

        ; Test LAN Address because WAN failed.
        If $LanMode = True Then

                $socket = TCPConnect( TCPNameToIP( $RepeaterAddressLAN ), $RepeaterServerPort )

                If $socket = -1 Then

                        ; No connections possible, exit.
                        WinSetOnTop( $str_Program_Title, "",0 )
                        MsgBox( 48, $str_MsgBox_Error, $str_ErrorRepeaterConnectionFailed, 10 )
                        InstantSupportExit( True )

                EndIf

        EndIf

        TCPShutdown()

EndIf

StartWinVNC()

; Create the tray icon. Default tray menu items (Script Paused/Exit) will not be shown.
Opt( "TrayMenuMode", 1 )
$InstallItem = TrayCreateItem( $str_Button_InstallService )
$ExitItem = TrayCreateItem( $str_Button_Exit )

; Enable the scripts ability to pause. (otherwise tray menu is disabled)
Break(1)

; Main loop.
While 1

        ; Close any windows firewall messages that popup. The windows firewall doesn't block outgoing connections anyways. ----Does the OS language change this?----
        If WinExists( "Windows Security Alert" ) Then WinClose( "Windows Security Alert" )
        If WinExists( "Windows-Sicherheitshinweis" ) Then WinClose( "Windows-Sicherheitshinweis" )

        ; If UltraVNC can't connect to the repeater then exit.
        If WinExists( "Initiate Connection" ) Then

                ; Stop the VNC server
                ProcessClose( "InstantSupportVNC.exe" )
                ProcessWaitClose( "InstantSupportVNC.exe" )
                WinSetOnTop( $str_Program_Title, "",0 )
                MsgBox( 48, $str_MsgBox_Error, $str_ErrorRepeaterConnectionFailed )
                InstantSupportExit( True )

        EndIf

        ; Check for form events.
        $nMsg = GUIGetMsg()
        Switch $nMsg

                Case $GUI_EVENT_CLOSE

                        WinSetOnTop( $str_Program_Title, "",0 )
                        If MsgBox( 4, $str_Program_Title, $str_EndSupportSession ) = 6 Then

                                InstantSupportExit( True )

                        EndIf

        EndSwitch

        ; Tray events.
        $nMsg = TrayGetMsg()
        Switch $nMsg

                Case $InstallItem

                        If $ServiceTemporarilyInstalled Then
                              UninstallService ()
                              ;reactivate install option
                              TrayItemSetText( $InstallItem, $str_Button_InstallService )
                              $ServiceTemporarilyInstalled = False
      
                              StartWinVNC()
                        Else                  
                              ; Service installation unavailable if using an HTTP Proxy (UltraVNC limitation).
                              If $ProxyEnabled = True Then
      
                                      WinSetOnTop( $str_Program_Title, "",0 )
                                      MsgBox( 48, $str_MsgBox_Error, $str_ServiceProxy, 10 )
      
                              Else
                                      ; Choose ID for service installation.
                                      WinSetOnTop( $str_Program_Title, "",0 )
                                      $NewIDNumber = InputBox( $str_MsgBox_ServiceInstallation, $str_ServiceEnterAnIDNumber, $IDNumber ) +0                                
      
                                      If @error = 0 and IsNumber($NewIDNumber) and $NewIDNumber > 200000 and $NewIDNumber < 999999 Then
            
                                              $Cancelled = False
                                              $Username = InputBox( $str_ServiceAdminRequirerd, $str_ServiceUsername, "administrator" )
                                              If $Username <> "" Then
                                                    $Domain = InputBox( $str_ServiceAdminRequirerd, $str_ServiceDomain, @ComputerName)
                                                    If $Domain > "" Then
                                                          $Password = InputBox( $str_ServiceAdminRequirerd, $str_ServicePassword, "", "*" )
                                                          If $Password = "" Then
                                                                $Cancelled = (@error > 0)
                                                          EndIf
                                                    Else
                                                          $Cancelled = (@error > 0)
                                                    EndIf
                                              Else
                                                    $Cancelled = (@error > 0)                                             
                                              EndIf
                                    
                                              If Not $Cancelled Then
                                                    $IDNumber = $NewIDNumber
                                                    GUICtrlSetData ( $label2, $IDNumber )
                                                    
                                                    ; Configure ultravnc.ini
                                                    If $LanMode = True Then
            
                                                            IniWrite( $WorkingPath & "\ultravnc.ini", "admin", "service_commandline", '-autoreconnect ID:' & $IDNumber & ' -connect ' & $RepeaterAddressLAN & ":" & $RepeaterServerPort )
            
                                                    Else
            
                                                            IniWrite( $WorkingPath & "\ultravnc.ini", "admin", "service_commandline", '-autoreconnect ID:' & $IDNumber & ' -connect ' & $RepeaterAddress & ":" & $RepeaterServerPort )
            
                                                    EndIf
            
                                                    ; Configure instantsupport.ini
                                                    IniWrite( $WorkingPath & "\instantsupport.ini", "InstantSupport", "ID", $IDNumber )

                                                    $InstallPermanent = (MsgBox( 4, $str_MsgBox_ServiceInstallation, $str_ServicePermanent ) = 6)
                                                    ; Kill the VNC server
                                                    $PID = Run( $WorkingPath & "\InstantSupportVNC.exe -kill" )
            
                                                    ; Wait for the winvnc server to close.
                                                    ProcessWaitClose( $PID, 15 )
            
                                                    ; Run installer after the server exits.
                                                    ProcessWaitClose( "InstantSupportVNC.exe" )
            
                                                    If $Username = "" Then
                                                          InstallElevated ($WorkingPath)
                                                    Else
                                                          ShellExecuteWait("icacls", $WorkingPath & " /grant " & $Domain & "\" & $Username & ":(CI)(OI)(F)")
                                                          RunAsWait($Username, $Domain, $Password, 0, $WorkingPath & "\InstantSupport.exe -elevateinstall", $WorkingPath)
                                                    EndIf
                                                    If ProcessWait ( "InstantSupportVNC.exe", 15 ) Then
                                                          ;service is running
                                                          If $InstallPermanent Then
                                                                ;Ok, we're done
                                                                InstantSupportExit( True )
                                                          Else
                                                                ;replace tray-option with uninstall
                                                                TrayItemSetText( $InstallItem, $str_Button_UninstallService )
                                                                $ServiceTemporarilyInstalled = True
                                                                WinSetOnTop( $str_Program_Title, "",1)
      
                                                          EndIf
                                                    Else
                                                          ;installation failed, restart VNC then inform user
                                                          StartWinVNC ()
                                                          MsgBox (0, $str_MsgBox_Information, $str_ServiceInstallFailed )
                                                    EndIf
                                              EndIf
      
                                      Else
                                              If @error = 0 Then
                                                    WinSetOnTop( $str_Program_Title, "",0 )
                                                    MsgBox( 0, $str_MsgBox_Information, $str_ServiceInvalidID )
                                              EndIf
      
                                      EndIf
      
                              EndIf
                        EndIf

                              
                Case $ExitItem

                        WinSetOnTop( $str_Program_Title, "",0 )
                        If MsgBox( 4, $str_Program_Title, $str_EndSupportSession ) = 6 Then

                                InstantSupportExit( True )

                        EndIf

        EndSwitch

WEnd

Func StartWinVNC ()

        ; Start the VNC server and make a reverse connection to the repeater.
        If $LanMode = True Then
                ShellExecute( $WorkingPath & "\InstantSupportVNC.exe", "-httpproxy -autoreconnect ID:" & $IDNumber & " -connect " & $RepeaterAddressLAN & ":" & $RepeaterServerPort & " -run" )
        Else
                ShellExecute( $WorkingPath & "\InstantSupportVNC.exe", "-httpproxy -autoreconnect ID:" & $IDNumber & " -connect " & $RepeaterAddress & ":" & $RepeaterServerPort & " -run" )
        EndIf
EndFunc      

Func InstallElevated($Path = @ScriptDir)
        ShellExecuteWait($Path & "\InstantSupport.exe", "-installservice", $Path, "runas")
EndFunc

Func UninstallElevated()
        ShellExecuteWait(@ProgramFilesDir & "\InstantSupport\InstantSupport.exe", "-removeservice", @ProgramFilesDir & "\InstantSupport\", "runas")
EndFunc

Func UninstallService ()
        ; remove temporarily installed service 
        If $Username = "" Then
              UninstallElevated ()
        Else
              RunAsWait($Username, $Domain, $Password, 0, $WorkingPath & "\InstantSupport.exe -removeservice", $WorkingPath)
        EndIf
EndFunc                              

Func InstallService()

        ; Copy files.
        FileCopy( @ScriptDir & "\*.*", @ProgramFilesDir & "\InstantSupport\", 9 )

        ; Create uninstall link on All Users desktop.
        FileCreateShortcut( @ProgramFilesDir & '\InstantSupport\InstantSupport.exe', @DesktopCommonDir & '\Uninstall Instant Support.lnk', "", "-removeservice" )

        ; Install VNC Service.
        ShellExecuteWait( @ProgramFilesDir & "\InstantSupport\InstantSupportVNC.exe", "-install" )

EndFunc


Func RemoveService()

        WinSetOnTop( $str_Program_Title, "",0 )
        If MsgBox( 4, $str_Program_Title, $str_MsgBox_RemoveService ) = 6 Then

                ; Remove Uninstaller
                FileDelete( @DesktopCommonDir & '\Uninstall Instant Support.lnk"' )

                ; Remove VNC Service.
                ShellExecuteWait( @ProgramFilesDir & "\InstantSupport\InstantSupportVNC.exe", "-uninstall" )
                
                ProcessWaitClose ( "InstantSupportVNC.exe", 15 )

                ; Remove the InstantSupport Service.
                _DeleteSelf( @ProgramFilesDir & "\InstantSupport", 10 )

        EndIf

EndFunc


Func _DeleteSelf( $Path, $iDelay = 5 )

        Local $sCmdFile

        FileDelete( @TempDir & "\scratch.bat" )


        $sCmdFile = 'PING -n ' & $iDelay & ' 127.0.0.1 > nul' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\InstantSupportVNC.exe"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\InstantSupport.exe"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\SecureVNCPlugin.dsm"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\ultravnc.ini"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\instantsupport.ini"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\logo.jpg"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\unblock.js"' & @CRLF _
                        & 'DEL /F /Q "' & $Path & '\InstantSupport.pubkey"' & @CRLF _
                        & 'RMDIR "' & $Path & '"' & @CRLF _
                        & 'DEL "' & @TempDir & '\scratch.bat"'

        FileWrite( @TempDir & "\scratch.bat", $sCmdFile )

        Run( @TempDir & "\scratch.bat", @TempDir, @SW_HIDE )

EndFunc


Func InstantSupportExit( $DeleteFiles = False )

        If $ServiceTemporarilyInstalled Then
              UninstallService ()
        Else
              ; Kill the VNC server
              $PID = Run( $WorkingPath & "\InstantSupportVNC.exe -kill" )
      
              ; Wait for the winvnc server to close.
              ProcessWaitClose( $PID, 15 )
        EndIf

        ; Remove temp files.
        If $DeleteFiles Then _DeleteSelf( $WorkingPath, 5)

        Exit

EndFunc


Func StopServices()

        _StopService("", "uvnc_service")
        _StopService("", "winvnc")

EndFunc


Post Reply