MWIProd Posted January 4, 2023 Posted January 4, 2023 Hello everybody. Happy New Year ! May the AutoIt force be with you. 🙂 I created a function _RunPSHost() to launch and get output from Powershell commands/scripts. As you can see with my code, it works with powershell commands but not with scripts. Could you help me ? expandcollapse popup#include <AutoItConstants.au3> #include <FileConstants.au3> #include <WinAPIConv.au3> Global $g_iPSHost = 0 Global $g_sFilePS = @ScriptDir & '\TEST.ps1' Test() Func Test() Local $hFile = FileOpen($g_sFilePS, $FO_OVERWRITE) FileWriteLine($hFile, 'Write-Host test file') FileWriteLine($hFile, 'Write-Host END_OF_OUTPUT') FileClose($hFile) $g_iPSHost = Run('powershell.exe -ExecutionPolicy Bypass -NoProfile -command - ', @SystemDir, @SW_HIDE, BitOR($STDIN_CHILD, $STDERR_CHILD, $STDOUT_CHILD)) _RunPSHost($g_iPSHost, 'Write-Host test cmd', False, True) _RunPSHost($g_iPSHost, '. "' & $g_sFilePS & '"', True, True) EndFunc ;==>Test Func _RunPSHost($iPSHost, $sPSCmd, $bScript = False, $bVerbose = False) Local $sOutput = '', $sError = '' If $bScript = False Then $sPSCmd &= '; Write-Host END_OF_OUTPUT' & @CRLF If $bVerbose Then ConsoleWrite(@CRLF & '================================================== BEGIN RunPSHost ==================================================' & @CRLF) If $bVerbose Then ConsoleWrite('Commande : ' & $sPSCmd & @CRLF) StdinWrite($iPSHost, $sPSCmd) ;~ If $bScript Then StdinWrite($iPSHost, @CRLF & 'Write-Host END_OF_OUTPUT') If $bScript = False Then While 1 ; detects when data starts to stream in and then exits the loop $sOutput &= StdoutRead($iPSHost) If @extended > 0 Then ExitLoop Sleep(1000) WEnd EndIf If $bVerbose Then ConsoleWrite('Waiting text "END_OF_OUTPUT"' & @CRLF) While 1 ; data has begun to stream, wait text "END_OF_OUTPUT" which tells first command has completed $sError &= StderrRead($iPSHost) $sOutput &= StdoutRead($iPSHost) If $bVerbose And $sOutput <> '' Then ConsoleWrite($sOutput & @CRLF) If StringInStr($sOutput, 'END_OF_OUTPUT') Then ExitLoop Sleep(1000) WEnd If $bVerbose Then ConsoleWrite('Found text "END_OF_OUTPUT"' & @CRLF) If $sError <> '' Then ;~ ConsoleWrite($sError & @CRLF) $sError = _WinAPI_OemToChar($sError) $sError = StringRegExpReplace($sError, '(?s)(.*?)Au caractère.*', '$1') $sError = StringRegExpReplace($sError, '\R', ' ') Return SetError(1, 0, $sError) EndIf $sOutput = StringRegExpReplace(_WinAPI_OemToChar($sOutput), '\R*END_OF_OUTPUT\R', '') ConsoleWrite($sOutput & @CRLF) If $bVerbose Then ConsoleWrite('================================================== END RunPSHost ==================================================' & @CRLF) Return $sOutput EndFunc ;==>_RunPSHost
SOLVE-SMART Posted January 4, 2023 Posted January 4, 2023 Hi @MWIProd, how your TEST.ps1 looks like? What exactly doesn't work properly? How about to write your powershell scripts output to a file and read this? Best regardsSven________________Stay innovative! ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
MWIProd Posted January 4, 2023 Author Posted January 4, 2023 (edited) Hi @SOLVE-SMART, TEST.ps1 is created in my au3script. 😉 I prefer to read output from console. And I want understand why it doesn't work. 🙄 I omit to specify that I don't want launch another powershell instance to run PS script. I want to launch PS script(s) on the same PS instance. If I use this code, it works. But this is not what I want to do. $sCMD = "powershell.exe -file " & @ScriptDir & "\TEST.ps1" $iPID = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD) ... Edited January 4, 2023 by MWIProd
SOLVE-SMART Posted January 4, 2023 Posted January 4, 2023 1 minute ago, MWIProd said: Hi @SOLVE-SMART, TEST.ps1 is created in my au3script. 😉 I prefer to read output from console. And I want understand why it doesn't work. 🙄 I omit to specify that I don't want launch another powershell instance to run PS script. I want to launch PS script(s) on the same PS instance. If I use this code, it works. But this is not what I want to do. $sCMD = "powershell.exe -file " & @ScriptDir & "\TEST.ps1" $iPID = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD) ... Understood 👍 . I will have another look. Best regardsSven________________Stay innovative! ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
rudi Posted January 5, 2023 Posted January 5, 2023 Hello. Interesting idea, I picked it up for a task, that I had to solve anyway. Maybe this sample code is giving you a start: expandcollapse popup; *** Start added by AutoIt3Wrapper *** #include <GUIConstantsEx.au3> ; *** End added by AutoIt3Wrapper *** #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Add_Constants=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; *** Start added by AutoIt3Wrapper *** #include <AutoItConstants.au3> ; *** End added by AutoIt3Wrapper *** #include <Date.au3> $Output = "" $OutputOld=$Output $Gui_W = 600 $Gui_H = 900 $Ctrl_H = 20 $MyGUI = GUICreate("PS helper", $Gui_W, $Gui_H, 50, 50) $Input = GUICtrlCreateInput("", 20, 20, $Gui_W - 40, $Ctrl_H) Opt("Guicoordmode", 2) ; cell relative $BtnGo = GUICtrlCreateButton("Send command", -1, 10) Opt("Guicoordmode", 1) ; absolute $Edit = GUICtrlCreateEdit($Output, 20, 80, $Gui_W - 40, $Gui_H - 100) GUICtrlSetState($Edit, $GUI_DISABLE) GUISetState() WinSetOnTop($MyGUI, "", 1) $PSPID = Run("powershell.exe", @TempDir, @SW_HIDE, $STDIN_CHILD + $STDERR_MERGED) AdlibRegister("UpdateOutput") While ProcessExists($PSPID) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $BtnGo $Line = GUICtrlRead($Input) StdinWrite($PSPID,$Line & @CRLF) GUICtrlSetData($Input,"") EndSwitch WEnd MsgBox(0, "Powershell PID vanished", "PID " & $PSPID & " no longer exists.",5) Func UpdateOutput() $Output &= StdoutRead($PSPID) if $Output=$OutputOld Then ; nothing changed Else $OutputOld=$Output ClipPut($Output) ToolTip(_NowCalc() & @CRLF & $Output) GUICtrlSetData($Edit, $Output) EndIf EndFunc ;==>UpdateOutput Earth is flat, pigs can fly, and Nuclear Power is SAFE!
MWIProd Posted January 5, 2023 Author Posted January 5, 2023 Interesting... 🙂 But this is what I want to do. For example : - define PS variables - send PS command and get return - launch PS script and get return - send PS command and get return - ...
MWIProd Posted January 5, 2023 Author Posted January 5, 2023 If I use : FileWriteLine($hFile, 'Start-Transcript c:\temp\log.txt') FileWriteLine($hFile, 'Write-Host test file') FileWriteLine($hFile, 'Write-Host END_OF_OUTPUT') FileWriteLine($hFile, 'Stop-Transcript') I can see the output in log file : test file END_OF_OUTPUT So the script TEST.ps1 is launched but the output is not sent to console. 😞
MattHiggs Posted January 5, 2023 Posted January 5, 2023 Hey @MWIProd. can you try replacing your "fileopen" command with this instead? Local $hFile = FileOpen($g_sFilePS, 514) This modification will create the powershell script using ANSI reading and writing mode. I wrote a script once upon a time that would create powershell scripts using the contents of an edit box, but when I tried executing the script that was created, nothing would happen. Using the above code fixed that for me. Give it a shot.
MWIProd Posted January 6, 2023 Author Posted January 6, 2023 (edited) Hello @MattHiggs It doesn't work. This code is for AutoIt Forum members (help testing) Local $hFile = FileOpen($g_sFilePS, $FO_OVERWRITE) ;~ Local $hFile = FileOpen($g_sFilePS, 514) FileWriteLine($hFile, 'Start-Transcript c:\temp\log.txt') FileWriteLine($hFile, 'Write-Host test file') FileWriteLine($hFile, 'Write-Host END_OF_OUTPUT') FileWriteLine($hFile, 'Stop-Transcript') FileClose($hFile) In reality, my PS script is an external file (No BOM format). It doesn't work too. Edited January 6, 2023 by MWIProd
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now