Windows 如何在AutoIt脚本中隐藏弹出窗口?

Windows 如何在AutoIt脚本中隐藏弹出窗口?,windows,autoit,Windows,Autoit,我使用下面的代码安装了一个文件 Run("file.exe", "", @SW_HIDE) WinWait("install", "") WinSetState("install", "", @SW_HIDE) Sleep(2000) ControlSend('install', '', '', 'E-mail') ControlSend('install', '', '', '{ENTER}') WinWait("install", "") WinSetState("install", "",

我使用下面的代码安装了一个文件

Run("file.exe", "", @SW_HIDE)
WinWait("install", "")
WinSetState("install", "", @SW_HIDE)
Sleep(2000)
ControlSend('install', '', '', 'E-mail')
ControlSend('install', '', '', '{ENTER}')
WinWait("install", "")
WinSetState("install", "", @SW_HIDE)
它可以隐藏控制台窗口,但几秒钟后

系统弹出窗口显示另一个安装窗口一段时间,然后隐藏,显示安装进度


我想知道如何隐藏此窗口以及控制台窗口。

有一种方法可以在windows中的隐藏桌面上运行带有autoit的应用程序,这样用户就永远看不到任何窗口。甚至可以通过内置的send()/click()/etc与此应用程序及其窗口交互。。。自动IT功能

是指向autoit代码的链接,可在autoit论坛上执行此操作

以下是链路失效时的代码:

hiddenDesktopInteract.au3:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <WinAPI.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>

;1st command line param that will launch seperate instance
Const $hdiParam = 'hiddenDesktopInteract'

;######DO NOT PUT ANY OTHER CODE ABOVE THIS THAT CALLS A 2ND INSTANCE OF THE SCRIPT OR ELSE YOU MAY END UP CALLING INFINITE INSTANCES AND CRASHING WINDOWS!!!!!!
;seperate process for hidden desktop interaction
;1st param should be 'hiddenDesktopInteract' and 2nd param is name of func to call for interaction code
;ex: "autoit.exe script.au3 hiddenDesktopInteract interactionfunc" or "compiledscript.exe hiddenDesktopInteract interactionfunc"
if $CmdLine[0] = 2 AND $CmdLine[1] = $hdiParam Then EXIT Call($CmdLine[2])

;credit to Decipher in thread https://www.autoitscript.com/forum/topic/152515-start-a-process-hidden/#comment-1095173 for code for running process on a hidden desktop
Func _hiddenDesktopInteract_run($sProgram, $sInteractionFunc, $sCommand = '')
    ;if the interaction function does not exist then don't do anything
    If Not IsFunc(Execute($sInteractionFunc)) Then
        ConsoleWrite('error: interaction function "' & $sInteractionFunc & '" for "' & $sProgram & '" does not exist' & @CRLF)
        Return
    EndIf

    ;create structs
    Local $tStartupInfo = DllStructCreate($tagStartupInfo)
    DllStructSetData($tStartupInfo, "Size", DllStructGetSize($tStartupInfo))
    Local $tProcessInfo_targetApp = DllStructCreate($tagPROCESS_INFORMATION)
    Local $tProcessInfo_interactionScript = DllStructCreate($tagPROCESS_INFORMATION)

    ; Create Desktop
    Local $hDesktop = _WinAPI_CreateDesktop('AutoItHidden', BitOR($DESKTOP_CREATEWINDOW, $DESKTOP_SWITCHDESKTOP))
    If Not $hDesktop Then
        MsgBox(0, 'Error', 'Unable to create desktop.')
        Exit
    EndIf

    ; Prep Process Info
    Local $nSuccess = DllStructSetData($tStartupInfo, "Desktop", _WinAPI_CreateString("AutoItHidden"))

    ;run target program on hidden desktop and get PID
    _WinAPI_CreateProcess('', '"' & $sProgram & '"' & ($sCommand ? ' ' & $sCommand : ''), 0, 0, 0, 0x00000200, 0, 0, DllStructGetPtr($tStartupInfo), DllStructGetPtr($tProcessInfo_targetApp))
    Local $aPID_targetApp = DllStructGetData($tProcessInfo_targetApp, 'ProcessID')
    ConsoleWrite('!>target app PID:' & $aPID_targetApp & @CRLF)

    ;run instance of this script on hidden desktop to interact with target program
    Local $sParams = '"' & @ScriptFullPath & '" ' & $hdiParam & ' ' & $sInteractionFunc
    Switch @Compiled
        case True
            Local $sAppName = @ScriptFullPath
            Local $sCommandLine = $sParams
        case False
            Local $sAppName = @AutoItExe
            Local $sCommandLine = '"' & @AutoItExe & '" ' & $sParams
    EndSwitch
    _WinAPI_CreateProcess('', $sCommandLine, 0, 0, 0, 0x00000200, 0, 0, DllStructGetPtr($tStartupInfo), DllStructGetPtr($tProcessInfo_interactionScript))

    ;and get PID of interaction instance so we can wait until it is finished
    Local $iPID_interactionScript = DllStructGetData($tProcessInfo_interactionScript, 'ProcessID')
    ConsoleWrite('!>Interaction Script PID: ' & $iPID_interactionScript & @CRLF)

    ;wait until interaction script instance is finished and get exit code (which is return value from interaction function)
    ProcessWaitClose($iPID_interactionScript)
    Local $exitcode_interactionScript = @extended
    ConsoleWrite("!>Interaction Script Exit Code: " & $exitcode_interactionScript & @CRLF)
    Local $sOutput = StdoutRead($iPID_interactionScript)
    ConsoleWrite("!>Interaction Script Stdout: " & $sOutput & @CRLF)

    ;close hidden desktop
    Local $aRet = DllCall("User32.dll", "int", "CloseDesktop", "handle", $hDesktop)
    ConsoleWrite("!>Close Desktop: " & $aRet[0] & @CRLF) ; Non-Zero is successfull!

    Return $exitcode_interactionScript
EndFunc

Func _hiddenDesktopInteract_cap($title, $imgfile, $Left = 0, $Top = 0, $Right = -1, $Bottom = -1)
    _GDIPlus_Startup()
    $hWnd = WinGetHandle($title)
    $iWidth = _WinAPI_GetWindowWidth($hWnd)
    $iHeight = _WinAPI_GetWindowHeight($hWnd)
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    $hBMPclone = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    if $Right = -1 then
        $iX = _GDIPlus_ImageGetWidth($hBMPclone) - $Left
    Else
        $iX = $Right - $Left
    EndIf
    if $Bottom = -1 then
        $iY = _GDIPlus_ImageGetHeight($hBMPclone) - $Top
    Else
        $iY = $Bottom - $Top
    EndIf
    ;convert from 32bit bitmap to 24bit bitmap b/c 32bit bitmap cannot display correctly in autoit GUI for some reason
    $hClone = _GDIPlus_BitmapCloneArea($hBMPclone, $Left, $Top, $iX, $iY, $GDIP_PXF24RGB)
    _GDIPlus_ImageSaveToFile($hClone, $imgfile)
    _WinAPI_DeleteObject($hBMP)
    _WinAPI_DeleteObject($hBMPclone)
    _WinAPI_DeleteObject($hClone)
    _GDIPlus_Shutdown()
EndFunc
#include "hiddenDesktopInteract.au3"

;test function for interacting with notepad app on hidden desktop
func notepadtest()
    opt('winwaitdelay', 0)  ;to make it run a little bit faster
    WinWait('[CLASS:Notepad]')
    $hwin = WinGetHandle('[CLASS:Notepad]')
    ControlSend($hwin, '', '[CLASS:Edit; INSTANCE:1]', 'hello{ENTER}')
    WinMenuSelectItem($hwin, '', '&Edit', 'Time/&Date')
    _hiddenDesktopInteract_cap($hwin, @DesktopDir & '\notepad_cap.jpg')
    ControlSend($hwin, '', '[CLASS:Edit; INSTANCE:1]', '^a')
    ControlSend($hwin, '', '[CLASS:Edit; INSTANCE:1]', '{DELETE}')
    WinClose($hwin)
EndFunc

;test function for interacting with cmd.exe on hidden desktop
func cmdtest()
    opt('winwaitdelay', 0)  ;to make it run a little bit faster
    WinWait('[CLASS:ConsoleWindowClass]')
    $hwin = WinGetHandle('[CLASS:ConsoleWindowClass]')
    ControlSend($hwin, '', '', 'dir{ENTER}')
    sleep(500)
    _hiddenDesktopInteract_cap($hwin, @DesktopDir & '\cmd_cap.jpg')
    ControlSend($hwin, '', '', 'exit{ENTER}')
EndFunc

_hiddenDesktopInteract_run("notepad.exe", 'notepadtest')
_hiddenDesktopInteract_run("cmd.exe", 'cmdtest')

这几乎只是autoit论坛帖子的复制粘贴,但我不认为这是一个问题,因为我是该帖子的作者。

您可以使用隐藏任何窗口,但自然您将无法再与该窗口的控件交互

; wait for the window to appear
Local $hWnd = WinWait("[CLASS:TheAppToHide]")

; hide the window using the handle returned from WinWait
WinSetState($hWnd, "", @SW_HIDE)

你是对的,但是当我发送ControlSend('install'、''、'{ENTER}')时,应用程序会打开一个新窗口,我想将其隐藏,然后你应该在弹出窗口上使用WinWait,并按照我写的那样使用WinSetState将其隐藏。或者你的意思是它不断地创建弹出窗口?我在那个弹出窗口上使用WinWait,但它会打开一会儿,然后隐藏