Blame | Last modification | View Log | Download
;==============================================================================;; Script version: 3.0; Script date: 12-06-2019; AutoIt Version: 3.0; Language: English; Platform: WinXP/2003/Vista/Win7/Win10; Author: Marcel Jordaan (mjordaan@rldautomation.eu);; Script Function:; Starts the FactoryLink webclient using graph.exe, and accepts the the same; commandline parameters as graph.exe.; This script will start the weblcient and close all popup messageboxes re-; porting errors, normally webclient will close after accepting popup; messages!;; Settings for this script are located in flweb.ini (same directory as; flweb.exe);; Note: the path variable should be set to the bin-directory where webclient; is installed;; Usage:; Calling this script in cmd or batch file makes it possible to auto-close; webclientafter an error, and restart the same or an alternative weblcient; connection.;==============================================================================;=======================================================================================; GLOBAL Options definitions;=======================================================================================; default is progam icon hidden, with option HIDE_ICON in flweb.ini the program; icon can beshown or hidden#NoTrayIcon;=======================================================================================; INCLUDE Files;=======================================================================================; include files#include <GUIConstantsEx.au3>#include <WindowsConstants.au3>#include <SendMessage.au3>#include <IE.au3>#Include <WinAPI.au3>#Include <Constants.au3>#include <Array.au3>#include <Process.au3>#include <_IsUACAdmin.au3>;=======================================================================================; OPTIONS for script;=======================================================================================; Set the different ptogam optionsOpt("TrayAutoPause", 0) ; Script pauses when click on tray iconOpt("TrayMenuMode", 1) ; Extend the behaviour of the script tray icon/menu; 1 = no default menuOpt("TrayOnEventMode", 1) ; Enable/disable OnEvent functions notifications for the tray;==============================================================================; Main flweb;==============================================================================; main variables$startup = -1$webclient = -1$GraphhWnd = 0$server = 0$single = 0 ;use all available servers;Create tray icon menu, only Exit$ExitId = TrayCreateItem("Exit")TrayItemSetState( $ExitId, $TRAY_UNCHECKED)TrayItemSetOnEvent( $ExitId, "WcExit");define and register exit functionOnAutoItExitRegister( "MyexitFunction");initialize the command line parameter string$params = ""$inifile = @ScriptDir & "/flweb.ini";Get the commandline and build the parameter list for webclientFor $i = 1 to $CmdLine[0] step 1$params = $params & " " & $CmdLine[$i]Next;if only one instance per user is allowed; check if we are already running$oneinst = Int( IniRead( $inifile, "WEBCLIENT", "ONE_INSTANCE" , "1"));show popup we are already running and Exitif $oneinst <> 0 then; current user's SessionId$sid = _WTSQuerySessionInformation(-1, 4);dbg( "Webclient: SessionId=" & $sid); get our process name and id$name = _ProcessGetName( @AutoItPID);dbg( "Webclient: scriptname=" & $name);If Not Ping(@ComputerName,200) Then SetError(1)$objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\CIMV2");If Not IsObj($objWMI) Then SetError(2)$query = "SELECT * FROM Win32_Process WHERE SessionId = " & $sid & "and Name Like '" & $name & "%'";dbg( "Webclient: WMI query=" & $query)$colItems = $objWMI.ExecQuery ($query);Dim $arrResults[1][3] = [["Processname","ProcessID","SessionID"]];For $objItem In $colItems; ReDim $arrResults[UBound($arrResults)+1][3]; $arrResults[UBound($arrResults)-1][0] = $objItem.Name; $arrResults[UBound($arrResults)-1][1] = $objItem.ProcessId; $arrResults[UBound($arrResults)-1][2] = $objItem.SessionId;Next;dbg( "Webclient: nr instances running=" & $colItems.Count);current script is nr 1, if there is already a script running it is the second oneif $colItems.Count > 1 thenSplashTextOn("FactoryLink Webclient", "Only one instance allowed, exiting", -1, 70, -1, -1, 18)Sleep( 3500)SplashOff()exitendifendif$UACadmin = _IsUACAdmin();look for registry settings for graph;check if webclient.reg existsif $UACadmin Then$test = StringCompare(@OSArch, "X86");msgbox(1, "UAC", "@OSarch = "& @OSArch & "test=" & $test)Switch $testCase 0$reg_stdfile = @ScriptDir & "\webclient3_x86.reg"Case Else$reg_stdfile = @ScriptDir & "\webclient3.reg"EndSwitch$reg_file = IniRead( $inifile, "WEBCLIENT", "GRAPH_REGFILE" , $reg_stdfile)if FileExists($reg_file) Then;add registry values, or overwrite;RunWait( "regedit /s " & $reg_file)IniWrite($inifile, "WEBCLIENT", "WEBCLIENT_SET", "1")ExitEndIfEndIf;check for the use of one server only: server_1if (StringCompare( StringStripWS($params, 3), "-s1") == 0) then$single = 1$params = ""EndIf;check for the use of one server only: server_2if (StringCompare( StringStripWS($params, 3), "-s2") == 0) then$single = 2$params = ""EndIf;array for two serverslocal $serverx[2];Server definitions are default empty$serverx[0] = ""$serverx[1] = "";dbg( "Webclient: $params = " & $params);dbg( "Webclient: $single = " & $single);Show splash screen$splash = Int( IniRead( $inifile, "WEBCLIENT", "SPLASH_SCREEN" , "0"))$splash_width = Int( IniRead( $inifile, "WEBCLIENT", "SPLASH_SCREEN_WIDTH" , "600"))$splash_height = Int( IniRead( $inifile, "WEBCLIENT", "SPLASH_SCREEN_HEIGHT" , "375"))$splash_x = Int( IniRead( $inifile, "WEBCLIENT", "SPLASH_SCREEN_X" , "-1"))$splash_y = Int( IniRead( $inifile, "WEBCLIENT", "SPLASH_SCREEN_Y" , "-1"))$splash_option = Int( IniRead( $inifile, "WEBCLIENT", "SPLASH_SCREEN_OPTION" , "18"))if $splash <> 0 thenSplashImageOn("FactoryLink Webclient", "web_splash.jpg", $splash_width, $splash_height, $splash_x, $splash_y, $splash_option)endifwhile (($webclient <> 0) or ($startup <> 0));dbg( "Webclient: $webclient=" & $webclient & "; $startup=" & $startup)if ($startup <> 0) then;if there is a command line, ignore settings in the ini-file;settings ignored are arguments and server definitions, mark;that from the comand line only one server can be defined!if ($params == "") then;read arguments and server definitions$params = IniRead( $inifile, "WEBCLIENT", "WEBCLIENT_ARGUMENTS" , "")$serverx[0] = "-h" & IniRead( $inifile, "WEBCLIENT", "WEBCLIENT_SERVER1" , "")$serverx[1] = "-h" & IniRead( $inifile, "WEBCLIENT", "WEBCLIENT_SERVER2" , "");dbg( "Webclient: $single = " & $single);dbg( "Webclient: $server = " & $server);dbg( "Webclient: $params = " & $params);dbg( "Webclient: $serverx[0] = " & $serverx[0]);dbg( "Webclient: $serverx[1] = " & $serverx[1]);active server is server1if ($single == 0) then$server = 0else$server = $single - 1endifif ($params <> "") then$params = $params & ","else$params = " "endifendif;Read settings from flweb.ini file in current working directory$WebCLientDir = IniRead( $inifile, "WEBCLIENT", "WEBCLIENT_DIR" , "C:\Program Files\Siemens\FactoryLink\Client\WebClient\Bin")$GraphSET = Int( IniRead( $inifile, "WEBCLIENT", "WEBCLIENT_SET" , "1"))if $GraphSET thenRunWait( $WebCLientDir & "/graphset.exe")IniWrite($inifile, "WEBCLIENT", "WEBCLIENT_SET", "0")EndIf$WebCLientClass = IniRead( $inifile, "WEBCLIENT", "WINCLASS" , "dispclass")$WebCLientWin = IniRead( $inifile, "WEBCLIENT", "MAINWIN_NAME" , "APPLICATION")$WebCLientStyle = IniRead( $inifile, "WEBCLIENT", "MAINWIN_STYLE" , "0x94000000")$WebCLientWinChange = Int( IniRead( $inifile, "WEBCLIENT", "MAINWIN_CHANGE" , "0"))$FullScreenChange = Int( IniRead( $inifile, "WEBCLIENT", "FULLSCREEN_CHANGE" , "0x94000000"))$FullScreenStyle = IniRead( $inifile, "WEBCLIENT", "FULLSCREEN_STYLE" , "0x94000000")$WebCLientAlwaysActive = Int( IniRead( $inifile, "WEBCLIENT", "WEBCLIENT_ALWAYS_ACTIVE" , "0"))$MainWin_X = Int( IniRead( $inifile, "WEBCLIENT", "MAINWIN_X" , "0"))$MainWin_Y = Int( IniRead( $inifile, "WEBCLIENT", "MAINWIN_Y" , "0"))$MainWin_Width = Int( IniRead( $inifile, "WEBCLIENT", "MAINWIN_WIDTH" , "0"))$MainWin_Height = Int( IniRead( $inifile, "WEBCLIENT", "MAINWIN_HEIGHT" , "0"))$ShowMyIcon = Int( IniRead( $inifile, "PROGRAM", "HIDE_ICON" , "1"))AutoItSetOption( "TrayIconHide", $ShowMyIcon);debug info for ini file parameters;dbg( "Webclient: INI file: WEBCLIENT_DIR = " & $WebCLientDir);dbg( "Webclient: INI file: MAINWIN_CHANGE = " & $WebCLientWinChange);dbg( "Webclient: INI file: WINCLASS = " & $WebCLientClass);dbg( "Webclient: INI file: MAINWIN_NAME = " & $WebCLientWin);dbg( "Webclient: INI file: MAINWIN_STYLE = " & $WebCLientStyle);dbg( "Webclient: INI file: FULLSCREEN_CHANGE = " & $FullScreenChange);dbg( "Webclient: INI file: FULLSCREEN_STYLE = " & $FullScreenStyle);read and set the hot keys$HotKeyMaximize = IniRead( $inifile, "HOTKEYS", "MAXIMIZE_KEY" , "");dbg( "Webclient: HotKey Maximize = " & $HotKeyMaximize)$idx = 0If StringLen( $HotKeyMaximize) > 0 ThenHotKeySet( $HotKeyMaximize, "Maximize")EndIf$HotKeyExit = IniRead( $inifile, "HOTKEYS", "WCEXIT_KEY" , "");dbg( "Webclient: HotKey Exit = " & $HotKeyExit)If StringLen( $HotKeyExit) > 0 ThenHotKeySet( $HotKeyExit, "WcExit");dbg( "Webclient: Hotkey for exit set")EndIf;start webclient with parameters;dbg( "Webclient: " & $params & $serverx[$server])$GraphPID = Run( $WebCLientDir & "/graph.exe" & " " & $params & $serverx[$server]);only switch server if single server is not setif ($single == 0) thenif ($server == 0) thenif ( $serverx[1] <> "-h") > 0 then$server = 1endIfelse$server = 0endifendif;get the PID for the webclient task$webclient = $GraphPID ;ProcessWait( "graph.exe", 20)If $webclient == 0 Then;only report with message box if defined in ini file$ReportExit = IniRead( $inifile, "WEBCLIENT", "ERROREXIT" , 0)If $ReportExit ThenMsgBox(0, "FactoryLink webclient", "'Graph' did not start. Bye!")if $splash <> 0 thenSplashOff()endif;Exit the scriptExitEndIfEndIf$startup = 0EndIf;do have to change the appearance of the main window?if ($WebCLientWinChange <> 0) or ($FullScreenChange <> 0) Then;dbg( "Webclient: Upfdating style for main window webclient");find the handle with the main window name and class$GraphhWnd = _GetHwndFromPID( $GraphPID);dbg( "Webclient: _GetHwndFromPID, window handle = " & $GraphhWnd)$GraphState = WinGetState( $GraphhWnd);dbg( "Webclient: WinGetState, window state = " & $GraphState)if ($GraphState >= 7) thenif ($WebCLientWinChange <> 0) then;dbg( "Webclient: wHnd graph = " & $GraphhWnd);change the window style accoriding to ini file settingsSetWindow( $WebCLientStyle, $GraphhWnd);we have changed the appeareance, do this only once$WebCLientWinChange = 0$FullScreenChange = 0else;change the window style accoriding to ini file settingsSetWindow( $FullScreenStyle, $GraphhWnd);we have changed the appeareance, do this only once$WebCLientWinChange = 0$FullScreenChange = 0endifendifEndIf;webclient uses standard messageboxes to report errors, other programs use the same;class names for the standard messageboxes.;if we find a standard message box, check if it is owned by webclient$var = WinList("[CLASS:#32770]");$array[0][0] = Number of windows returned;$array[1][0] = 1st window title;$array[1][1] = 1st window handle (HWND);$array[2][0] = 2nd window title;$array[2][1] = 2nd window handle (HWND)$keepgoing = 0;loop through all the standard messageboxesFor $i = 1 to $var[0][0] step 1;check if the messagebox is owned by webclient, if not just ignore$PidMsgBox = WinGetProcess($var[$i][1])If $webclient == $PidMsgBox Then;dbg( "Webclient: Number of matches = " & $var[0][0] & "; counter = " & $i);dbg( "Webclient: PID graph.exe: " & $webclient);dbg( "Webclient: PID message box: " & $PidMsgBox);dbg( "Webclient: Handle message box: " & $var[$i][1]);dbg( "Webclient: title message box: " & $var[$i][0]);messagebox is owned by webclient, give user 2.5 seconds to read....Sleep( 2500);close the message boxWinClose($var[$i][1]);dbg( "Webclient: Closed error message box from graph.exe: " & $var[$i][0])EndIfNext;do not use 100% CPU power, just go to sleep for tenth a secondSleep( 100);we are finished if webclient is shutdown or has ended after error$webclient = ProcessExists( $GraphPID)if ($webclient == 0) and ($WebCLientAlwaysActive <> 0) then$startup = -1endifWEnd; Finished!;Leave the scriptWcExit()Exit;=======================================================================================; FUNCTION definitions;=======================================================================================;=======================================================================================; FUNCTION dbg($msg);; debug function for use with Sysinternals DebugViewer (dbgview.exe);=======================================================================================Func dbg($msg)DllCall("kernel32.dll", "none", "OutputDebugString", "str", $msg)EndFunc ;==>dbg;=======================================================================================; FUNCTION Maximize();=======================================================================================Func Maximize()Local Const $SC_MAXIMIZE = 0xF030, $SC_RESTORE = 0xF120Local $sState$GraphhWnd = _GetHwndFromPID( $GraphPID)dbg( "Webclient: _GetHwndFromPID, window handle = " & $GraphhWnd)if ($GraphhWnd == 0) ThenReturnEndIfIf BitAND(WinGetState($GraphhWnd), 32) = 0 Then ; Not Maximised$sState = $SC_MAXIMIZESetWindow( 0, $GraphhWnd)Else$sState = $SC_RESTORESetWindow( $WebCLientStyle, $GraphhWnd)EndIfReturn _SendMessage($GraphhWnd, $WM_SYSCOMMAND, $sState)EndFunc ;==>Maximize;=======================================================================================; FUNCTION WcExit();=======================================================================================Func WcExit();dbg( "Webclient: Hotkey for exit script")if $splash <> 0 thenSplashOff()endifif ($webclient > 0) then ProcessClose( $webclient)ExitEndFunc ;==>WcExit;=======================================================================================; FUNCTION SetWindow( $WindowStyle, $hWnd);=======================================================================================Func SetWindow( $WindowStyle, $hWnd)$GraphhWnd = _GetHwndFromPID( $GraphPID)dbg( "Webclient: _GetHwndFromPID, window handle = " & $GraphhWnd)$wpLong = _WinAPI_SetWindowLong($GraphhWnd, $GWL_STYLE, $WindowStyle)dbg( "Webclient: _WinAPI_SetWindowLong returned = " & $wpLong)if ($hWnd > 0) Thenif ($MainWin_X == 0) and ($MainWin_Y == 0) and ($MainWin_Width == 0) and ($MainWin_Height == 0) then_WinAPI_SetWindowPos($hWnd,0,0,0,0,0,$SWP_FRAMECHANGED+$SWP_NOMOVE+$SWP_NOSIZE)else_WinAPI_SetWindowPos($hWnd,0,$MainWin_X,$MainWin_Y,$MainWin_Width,$MainWin_Height,$SWP_FRAMECHANGED)endif;redraw frame and client area_WinAPI_RedrawWindow($hWnd)EndIfEndFunc;==============================================================================; FUNCTION _GetHwndFromPID($PID);; _GetHwndFromPID : function to find window handle from process id;==============================================================================Func _GetHwndFromPID($PID)$hWnd = 0$stPID = DllStructCreate("int")Do$winlist2 = WinList()For $i = 1 To $winlist2[0][0]If $winlist2[$i][0] <> "" ThenDllCall("user32.dll", "int", "GetWindowThreadProcessId", "hwnd", $winlist2[$i][1], "ptr", DllStructGetPtr($stPID))If DllStructGetData($stPID, 1) = $PID Then$hWnd = $winlist2[$i][1]ExitLoopEndIfEndIfNextSleep(10)Until $hWnd <> 0Return $hWndEndFunc ;==>_GetHwndFromPID;==============================================================================; MyExitfunction;==============================================================================Func MyExitFunction();Leaving the main program, close our open graph.exe (if any)if ($webclient > 0) then ProcessClose( $webclient)EndFunc;==============================================================================; FUNCTION : _WTSQuerySessionInformation($SessionId, $WTSInfoClass = 10,; $iReturnAsIs = 0);; mod. of https://www.autoitscript.com/forum/topic/; 134679-get-hostname-of-the-client-connected-to-the-terminalserver-session/;; WMI Query function;==============================================================================Func _WTSQuerySessionInformation($SessionId, $WTSInfoClass = 10, $iReturnAsIs = 0)Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "Ptr", 0, "int", $SessionId, "int", $WTSInfoClass, "ptr*", 0, "dword*", 0)If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "")Local $ip = DllStructGetData(DllStructCreate("byte[" & $aResult[5] & "]", $aResult[4]), 1)DllCall("Wtsapi32.dll", "int", "WTSFreeMemory", "ptr", $aResult[4])If $iReturnAsIs Then Return $ipSwitch $WTSInfoClass ; https://docs.microsoft.com/en-us/windows/desktop/api/wtsapi32/ns-wtsapi32-_wts_client_addressCase 4 ; WTSSessionIdReturn Int('0x' & StringTrimRight(StringReverse($ip), 3))Case 14 ; WTSClientAddressIf Not (Int(StringLeft($ip, 4)) = 2) Then ; IPv4$ip = ""Else$ip = Dec(StringMid($ip, 15, 2)) & '.' & Dec(StringMid($ip, 17, 2)) & '.' & Dec(StringMid($ip, 19, 2)) & '.' & Dec(StringMid($ip, 21, 2))EndIfEndSwitchReturn StringReplace(BinaryToString($ip), Chr(0), "")EndFunc ;==>_GetWTSClientName