0

我正在尝试为摄像头监控软件 Milestone XProtect 创建一些自动化代码,我需要一些帮助。我最初使用批处理脚本和 VBScript 来尝试我的目标,但它似乎对我不起作用

    #include <MsgBoxConstants.au3>                          ;Import Message Box

Local Const $milestone = "C:\Program Files\Milestone\XProtect Smart Client\Client.exe"  ;Local Variable $milestone set to file path

Local $iFileExists = FileExists($milestone)                     ;Variable that sees if file exists($milestone)

If $iFileExists Then
    Run($milestone)
>   ;[Unknown Variables]                                ;***Figure out the "Window Title", Class, and Instance***
    Send("{TAB}")
    Send("{TAB}")
    Send("[Insert Camera IP Address Here]")                     ;Between [] different for each .exe I'll create
    Send("{ENTER}")
>   ;[Unknown Variables]                    ;***Figure out items in camera window to see when its fully loaded***
Else
    MsgBox($MB_SYSTEMMODAL, "", "Milestone XProtect wasn't found on this computer" & @CRLF)     ;Error Message "File not Found"
EndIf

截至目前,我的代码在计算机上设置了 Milestone 的路径变量,if 语句检查文件是否存在。如果它存在,那么它将运行程序。下一行代码应该等到程序完全加载后再发送两个制表键,即 ip 地址到摄像机服务器,然后输入键。if 语句中的最后一行代码应该在结束程序之前检查相机是否已完全加载。

我需要帮助的是我的代码中标记为[Unknown Variables]的两个部分:

  1. 我需要知道程序何时加载到服务器选择屏幕
  2. 在我结束程序之前,我需要知道相机服务器何时完全加载

任何人都可以帮忙吗?

4

1 回答 1

0

解决方案

我已将您需要的一些缺失元素放在一起,以便在保持简单性的同时完成此任务,并添加注释以帮助描述每一行。

有几种方法可以继续自动化过程,例如提供不同 IP 地址的下拉列表或输入框,而不是硬编码地址。您只需要随着时间的推移不断发展脚本,一次添加一个元素。

AutoIt 脚本

#include <MsgBoxConstants.au3>

Local Const $milestone = "C:\Program Files\Milestone\XProtect Smart Client\Client.exe" ;Path to software

Local $iFileExists = FileExists($milestone)                                 ;Check if the file exists, returns a 1 or 0

If $iFileExists Then                                                        ;If FileExists = 1 (exists)
    ;$inputbox = InputBox("Title", "Enter the IP Address of the camera.", "127.0.0.1")  ;Uncomment out if you would like to prompt for input for the IP Address. Used on line 19.
    ;If @error Then Exit                                                    ;@Error can mean Cancel button was pushed, so exit if canceled.
    $iPID = Run($milestone)                                                 ;Runs the software and returns the Process ID
    Sleep(1000)                                                             ;sleep for 1 second
    If @error Then MsgBox(0, "Title", "The program could not launch.")      ;If Run returns a 0 or error, there was a problem
    $handle = _GetHandleFromPID($iPID)                                      ;Retrieve the handle of the program ran, jump to the function below
    If $handle = 0 Then MsgBox(0, "Title", "The handle could not be found.");If the Handle returned is 0, there was no match
    WinWaitActive($handle)                                                  ;Wait for the program to be activated
    Send("{TAB}")                                                           ;send keystrokes to active window
    Send("{TAB}")
    Send("[Insert Camera IP Address Here]")                                 ;Hardcoded IP Address
    ;Send($inputbox)                                                            ;Uncomment out this line and comment out the above line to utilize the input box method instead of hardcoding IP Addresses.
    Send("{ENTER}")
   ;[Unknown Variables]                                                     ;***Figure out items in camera window to see when its fully loaded***
Else
    MsgBox($MB_SYSTEMMODAL, "", "Milestone XProtect wasn't found on this computer" & @CRLF)
EndIf

func _GetHandleFromPID($PID)                                                ;Call function with the PID returned from Run function
    $WinList = WinList()                                                    ;Assign WinList to a variable
    for $i = 1 to $WinList[0][0]                                            ;Run through each Window in WinList, 2D array [titles][handles]
        If WinGetProcess($WinList[$i][1]) = $PID then                       ;Look for a Window with the correct PID
            Return $WinList[$i][1]                                          ;Assign the matching Windows handle to the variable
        EndIf
    Next
    Return 0                                                                ;Return 0 if no matches were found
EndFunc

窗把手

检索窗口句柄很重要,因为它可以确保将击键发送到 Milestone 软件的最后运行实例(如果有多个实例正在运行)。

关于重试的想法

至于第二个问题,有很多方法可以实现检查连接超时重试。但是,它主要取决于通过 AutoIt 提供的交互。AutoIt Window Info Tool 是一个很好的起点。您可以将十字准线拖放到窗口元素以识别控件。下图显示了聚焦 Windows 计算器时的工具。

Calculator.exe 示例

例子

如果在服务器无法连接时显示弹出窗口,您可以拦截该窗口以发出重试信号。如果您只需要一个空白的视频监视器,则可以选择在屏幕上搜索图像或像素。或者,一个良好的服务器连接可能会提供某种类型的警报,AuoIt 可以捕获并在满意时成功关闭,如果没有,则在 X 秒内重试。

更新

这是带有 GUI 和组合框选项的程序,它使用 2D 数组。

#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Local Const $milestone = "C:\Program Files\Milestone\XProtect Smart Client\Client.exe" ;Path to software

Local $iFileExists = FileExists($milestone)                                     ;Check if the file exists, returns a 1 or 0
Global $list = [["Austin, TX","192.168.0.0"], ["Memphis, TN","192.168.0.1"]]    ;Enter all your selections, this builds a 2D Array [X][0] is the name [X][1] is the IP

If $iFileExists Then                                                            ;If FileExists = 1 (exists) then
    Local $GUI = GUICreate("TITLE", 267, 115)                                   ;Create the GUI
    $button = GUICtrlCreateButton("Start", 96, 56, 65, 25)                      ;Create a button
    $server = GUICtrlCreateCombo("Select Server", 8, 8, 249, 25, $CBS_DROPDOWN) ;Create the combo box
    For $i = 0 To UBound($list) - 1                                             ;Populate combo box with first value (name) from array
        If $list[$i][0] <> "" Then $var = GUICtrlSetData($server, $list[$i][0]) ;Ensure array is not empty
    Next

    GUISetState(@SW_SHOW)

    While 1                                                                     ;Enter loop until user closes or presses button
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE                                               ;Exit when closed
                Exit
            Case $button                                                        ;Store selection into variable, delete the GUI, and run the start function
                $selection = GUICtrlRead($server)
                GUIDelete()
                start()
        EndSwitch
    WEnd
Else                                                                            ;otherwise, message
    MsgBox($MB_SYSTEMMODAL, "", "Milestone XProtect wasn't found on this computer" & @CRLF)
EndIf

Func start()
    $iPID = Run($milestone)                                                     ;Runs the software and returns the Process ID
    Sleep(1000)                                                                 ;sleep for 1 second
    If @error Then MsgBox(0, "Title", "The program could not launch.")          ;If Run returns a 0 or error, there was a problem
    $handle = _GetHandleFromPID($iPID)                                          ;Retrieve the handle of the program ran, jump to the function below
    If $handle = 0 Then MsgBox(0, "Title", "The handle could not be found.")    ;If the Handle returned is 0, there was no match
    WinWaitActive($handle)                                                      ;Wait for the program to be activated
    Send("{TAB}")                                                               ;send keystrokes to active window
    Send("{TAB}")
    For $i = 0 to UBound($list) - 1                                             ;Find the IP address that matches the selection and send it
        If $list[$i][0] = $selection Then Send($list[$i][1])
    Next
    Send("{ENTER}")
    Exit                                                                        ;Exit for now until you can capture a succesful run
   ;[Unknown Variables]                                                         ;***Figure out items in camera window to see when its fully loaded***
EndFunc

func _GetHandleFromPID($PID)                                                    ;Call function with the PID returned from Run function
    $WinList = WinList()                                                        ;Assign WinList to a variable
    for $i = 1 to $WinList[0][0]                                                ;Run through each Window in WinList, 2D array [titles][handles]
        If WinGetProcess($WinList[$i][1]) = $PID then                           ;Look for a Window with the correct PID
            Return $WinList[$i][1]                                              ;Assign the matching Windows handle to the variable
        EndIf
    Next
    Return 0                                                                    ;Return 0 if no matches were found
EndFunc

更新#2

  1. 我添加了一种将新服务器添加到列表并将它们存储在本地的方法。
  2. 如果需要进行更改或删除服务器,我制作了一个隐藏的热键来打开该文件,您可以通过按键盘上的 F1 键输入该文件。我会让你弄清楚如何进一步定制这个。
  3. 如果没有选择服务器,则不会发生任何事情,否则启动程序。
  4. 目前,这将启动程序失焦并等待它再次获得焦点以输入击键(以防有人想等待 1 秒或 100 秒再单击程序返回)。
  5. 如果这仍然不够,或者默认情况下在初始屏幕之后窗口获得控制,则将睡眠计时器从 1000(1 秒)更改为您想要的任何值。
  6. 注意脚本中的第一个区域,它需要一些自定义。设置程序的路径、这个程序的标题和一个图标文件。
  7. 要编译它只需使用 AutoIt 编译器,这将允许图标正常工作。

#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <ComboConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiComboBox.au3>

#Region EDIT THE BELOW INFORMATION-------------------------------------------------------------------------------------------------------------------------------------------
Local Const $milestone = "C:\Program Files\Milestone\XProtect Smart Client\Client.exe"  ;Path to software
Local $Title = "Program Title"                                                          ;Give me a name
Local $icon = "Full\Path\To\Icon.ico"
#EndRegion-------------------------------------------------------------------------------------------------------------------------------------------------------------------

#Region Script---------------------------------------------------------------------------------------------------------------------------------------------------------------
Local $iFileExists = FileExists($milestone)                                     ;Check if the file exists, returns a 1 or 0
Global $list = IniReadSection(@TempDir & "\" & $Title & "\config.ini","Server") ;Read the ini file, this builds a 2D Array [X][0] is the key [X][1] is the value
HotKeySet("{F1}", "help")

If $iFileExists Then                                                            ;If FileExists = 1 (exists) then
    If Not FileExists(@TempDir & "\" & $Title) Then                             ;If config directory does not exists then
        Do
        DirCreate(@TempDir & "\" & $Title)                                      ;Create a directory in TempDir for the config.ini file to be stored locally
        Until FileExists(@TempDir & "\" & $Title)
        IniWrite(@TempDir & "\" & $Title & "\config.ini", "Server", "", "")
    EndIf
    Local $GUI = GUICreate($Title, 267, 115)                                    ;Create the GUI
    GUISetIcon($icon, -1)                                                       ;Create icon
    $start = GUICtrlCreateButton("Start", 40, 72, 65, 25)                       ;Create a button
    $create = GUICtrlCreateButton("Add Server", 160, 72, 65, 25)
    $server = GUICtrlCreateCombo("Select Server", 8, 8, 249, 25, $CBS_DROPDOWN) ;Create the combo box
    For $i = 1 To UBound($list) - 1                                             ;Populate combo box with first value (name) from array
        If $list[$i][0] <> "" Then GUICtrlSetData($server, $list[$i][0])        ;Ensure array is not empty and fill combox with KEYS
    Next
    $servername = GUICtrlCreateInput("Server Name", 8, 40, 121, 21)
    GUICtrlSetState(-1, $GUI_HIDE)
    $serverip = GUICtrlCreateInput("IP Address", 136, 40, 121, 21)
    GUICtrlSetState(-1, $GUI_HIDE)

    GUISetState(@SW_SHOW)

    While 1                                                                     ;Enter loop until user closes or presses button
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE                                               ;Exit when closed
                Exit
            Case $start                                                         ;Store selection into variable, delete the GUI, and run the start function
                $selection = GUICtrlRead($server)
                If $selection <> "Select Server" Then
                    GUIDelete()
                    start()
                EndIf
            Case $create
                If GUICtrlRead($create) = "Add Server" Then
                    GUICtrlSetState($servername, $GUI_SHOW)
                    GUICtrlSetState($serverip, $GUI_SHOW)
                    GUICtrlSetData($create, "Create")
                Else
                    If (GUICtrlRead($servername) <> "" And GUICtrlRead($servername) <> "Server Name" And GUICtrlRead($serverip) <> "" And GUICtrlRead($serverip) <> "IP Address") Then
                        IniWrite(@TempDir & "\" & $Title & "\config.ini", "Server", GUICtrlRead($servername), GUICtrlRead($serverip))
                        GUICtrlSetState($servername, $GUI_HIDE)
                        GUICtrlSetState($serverip, $GUI_HIDE)
                        GUICtrlSetData($create, "Add Server")
                    Else
                        MsgBox($MB_ICONINFORMATION, $Title, "Invalid Server Name and IP Address.")
                    EndIf
                    For $i = UBound($list) - 1 To 0 Step -1
                        _GUICtrlComboBox_DeleteString($server, $i)
                    Next
                    Local $list = IniReadSection(@TempDir & "\" & $Title & "\config.ini","Server")
                    For $i = 1 To UBound($list) - 1
                        If $list[$i][0] <> "" Then GUICtrlSetData($server, $list[$i][0])
                    Next
                EndIf
        EndSwitch
    WEnd
Else                                                                            ;otherwise, message
    MsgBox($MB_SYSTEMMODAL, "", "Milestone XProtect wasn't found on this computer" & @CRLF)
EndIf

Func start()
    $iPID = Run($milestone,"", @SW_SHOWNOACTIVATE)                              ;Runs the software and returns the Process ID
    Sleep(1000)                                                                 ;sleep for 1 second
    If @error Then MsgBox(0, $Title, "The program could not launch.")           ;If Run returns a 0 or error, there was a problem
    $handle = _GetHandleFromPID($iPID)                                          ;Retrieve the handle of the program ran, jump to the function below
    If $handle = 0 Then MsgBox(0, $Title, "The handle could not be found.")     ;If the Handle returned is 0, there was no match
    Sleep(1000)
    WinWaitActive($handle)                                                      ;Wait for the program to be activated
    Send("{TAB}")                                                               ;send keystrokes to active window
    Send("{TAB}")
    For $i = 0 to UBound($list) - 1                                             ;Find the IP address that matches the selection and send it
        If $list[$i][0] = $selection Then Send($list[$i][1])
    Next
    Send("{ENTER}")
    Exit                                                                        ;Exit for now until you can capture a succesful run
EndFunc

func _GetHandleFromPID($PID)                                                    ;Call function with the PID returned from Run function
    $WinList = WinList()                                                        ;Assign WinList to a variable
    for $i = 1 to $WinList[0][0]                                                ;Run through each Window in WinList, 2D array [titles][handles]
        If WinGetProcess($WinList[$i][1]) = $PID then                           ;Look for a Window with the correct PID
            Return $WinList[$i][1]                                              ;Assign the matching Windows handle to the variable
        EndIf
    Next
    Return 0                                                                    ;Return 0 if no matches were found
EndFunc

Func help()
    ShellExecute(@TempDir & "\" & $Title & "\config.ini")
EndFunc
#EndRegion--------------------------------------------------------------------------------------------------------------------------------------------------------------------

于 2022-01-17T18:31:36.123 回答