MWIProd Posted January 4 Share Posted January 4 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 Link to comment Share on other sites More sharing options...
SOLVE-SMART Posted January 4 Share Posted January 4 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! Stay innovative! 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) Link to comment Share on other sites More sharing options...
MWIProd Posted January 4 Author Share Posted January 4 (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 by MWIProd Link to comment Share on other sites More sharing options...
SOLVE-SMART Posted January 4 Share Posted January 4 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! Stay innovative! 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) Link to comment Share on other sites More sharing options...
rudi Posted January 5 Share Posted January 5 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! Link to comment Share on other sites More sharing options...
MWIProd Posted January 5 Author Share Posted January 5 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 - ... Link to comment Share on other sites More sharing options...
MWIProd Posted January 5 Author Share Posted January 5 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. 😞 Link to comment Share on other sites More sharing options...
MattHiggs Posted January 5 Share Posted January 5 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. Link to comment Share on other sites More sharing options...
MWIProd Posted January 6 Author Share Posted January 6 (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 by MWIProd Link to comment Share on other sites More sharing options...
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