首页 > 解决方案 > How can I run AutoIT scripts from powershell

问题描述

I have this script:

#Region
#AutoIt3Wrapper_UseUpx=n
#EndRegion

Global $SUPERBARPOS
$SUPERBARPOS = WinGetPos("[CLASS:Shell_TrayWnd]")

MsgBox(0, "Testing...", _
    "Taskbar's attributes: x:" & $SUPERBARPOS[0] & _
    " y:" & $SUPERBARPOS[1] & _
    " w:" & $SUPERBARPOS[2] & _
    " h:" & $SUPERBARPOS[3] & @CRLF & _
    "Superbar condition: " & _taskbarHidden())

Func _taskbarHidden()
    Local Const $ABM_GETSTATE = 4, $ABS_AUTOHIDE = 1, $ABS_ONTOP = 2
    Local $ARETURN

    $ARETURN = DllCall("shell32.dll", "uint", "SHAppBarMessage", "dword", $ABM_GETSTATE, "ptr*",  0)
    If @error Then Return SetError(1, 0, 0)

    If BITAND($ARETURN[0], $ABS_AUTOHIDE) Then
        Return "Auto hide is enabled"
    Else
        Return "Auto hide is disabled"
    EndIf
EndFunc

Func _getSuperbarPos2()
    Local Const $ABM_GETTASKBARPOS = 5
    Local Const $ABE_LEFT          = 0
    Local Const $ABE_TOP           = 1
    Local Const $ABE_RIGHT         = 2
    Local Const $ABE_BOTTOM        = 3

    Local $ARETURN

    Global $_POSITIONS[4]  = ["Left", "Top", "Right", "Bottom"]
    Global $TAG_APPBARDATA = "LONG;HWND;INT;INT;STRUCT;INT;INT;INT;INT;ENDSTRUCT"

    Local $PDATA = DllStructCreate($TAG_APPBARDATA)

    DllStructSetData($PDATA, 1, DllStructGetSize($PDATA))
    DllStructSetData($PDATA, 2, WinGetHandle("[CLASS:Shell_TrayWnd]", ""))

    Local $ARESULT = DllCall("Shell32.dll", "BOOL", "SHAppBarMessage", "DWORD", $ABM_GETTASKBARPOS, "ptr", DllStructGetPtr($PDATA))
    If @error Then Return SetError(@error, 0, -1)

    If Not $ARESULT[0] Then Return SetError($ARESULT[0], 0, -2)

    Return $_POSITIONS[DllStructGetData($PDATA, 4)]
EndFunc

Is there a way to convert it to Powershell, or if this isn't possible, how can I extract for example "&$SUPERBARPOS[1]&" using, again, powershell? More specific, I want to write a command in the powershell and see the outcome printed in powershell using that AutoIT script.

标签: powershellautoit

解决方案


从 Powershell 调用 Autoit 脚本之一

这是最简单的选择。

PowerShell 允许通过函数调用运算符&后跟程序路径及其参数来执行任意程序:

& "c:\path\to\program.exe" "parameter1" "parameter2" "parameter3"

因此,如果 AutoIT 运行脚本,您需要编写:

在 64 位系统上:

& "${env:ProgramFiles(x86)}\AutoIt3\AutoIt3.exe" "/AutoIt3ExecuteScript" "c:\your_script.au3"

在 32 位系统上:

& "${env:ProgramFiles}\AutoIt3\AutoIt3.exe" "/AutoIt3ExecuteScript" "c:\your_script.au3"

${env:ProgramFiles(x86)}被替换为具有文件夹完整路径的环境变量,Program files (x86)很可能c:\Program files (x86)

AutoIt3.exe是实际执行未编译的 autoit 脚本(au3文本文件)的程序。/AutoIt3ExecuteScript告诉它以脚本的形式执行下一个参数,但通常可以省略。

通过文件将数据从 AutoIT 传递到 PowerShell

有很多方法可以将数据从一个脚本传递到另一个脚本,但是最可靠的初学者友好方式似乎是将数据存储在一个临时文本文件中,尽管它有点效率低下。

在 AutoIT 脚本中,替换以以下开头的行MSGBOX

FileDelete("c:\myfile.txt")
FileWrite("c:\myfile.txt", $SUPERBARPOS[1])

如果文件已经存在,则第一行删除文件 - 否则将被附加。

第二行将 的内容写入$SUPERBARPOS[1]文件。

脚本完成后,您可以使用记事本打开文件,以检查该文件是否包含您想要的内容。

在 Powershell 中读取文件也很容易:

$myvar = [IO.File]::ReadAllText("c:\myfile.txt")

这会将整个文件的内容复制到一个名为$myvar

在不创建文件的情况下传递数据

当然,用临时文件乱扔硬盘并不是最好的主意。

在按顺序执行的程序之间传递数据的一种好方法是管道,尤其是 STDIN 和 STDOUT。

要做到这一点:

  1. 将 AutoIT 脚本编译为控制台应用程序(请参阅Autoit2exe 命令行文档和/或#AutoIt3Wrapper_Change2CUI=y 编辑器指令)
  2. 用类似或类似的东西替换该MSGBOX行 。ConsoleWrite($SUPERBARPOS[1] & @CRLF)默认情况下,这应该将变量作为文本转储到控制台窗口(除非您从命令行或 powershell 窗口运行脚本,否则您不会看到它)
  3. 要将文本重定向到变量中,只需像这样调用您的脚本:

    $myvar = & c:\your_script.exe
    
  4. 如果需要传递多个变量,则需要在 PowerShell 端将它们分开。为此,您可能需要执行以下操作:

    $a = $myvar -split "`r`n"
    

将脚本转换为 PowerShell

因为 AutoIT 和 PowerShell 是两种完全不同的语言,所以没有自动转换工具。要翻译代码,您需要了解 AutoIT 代码并在 PowerShell 中手动编写类似代码。为此,您显然需要足够了解 AutoIT 和 PowerShell 语言。

据我所知,这个脚本基本上调用了几个 WinAPI DLL 函数。在DllCall()中很好地描述了进程的 autoit 方面。PowerShell 似乎允许使用Add-Type进行此操作。

如果您在进行转换时遇到障碍,请提出更具体的问题。


推荐阅读