trancexx Posted March 31, 2009 Share Posted March 31, 2009 Here's the thing. I would like to have option with compiled script (GUI EXE) to be able to communicate with console if that script (exe) is run with command prompt or by another process (except explorer.exe). So, if parent is explorer.exe GUI mode is on and if parent is anything else CUI mode is forced.This is what I have:expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=Test.exe #AutoIt3Wrapper_UseUpx=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #NoTrayIcon Opt("MustDeclareVars", 1) Global $sParent = _GetParent() If @Compiled Then Switch $sParent Case "explorer.exe" Run("Test.exe") Case "cmd.exe" _ExecuteCommandLineAttachConsole($CmdLineRaw) Case Else _ExecuteCommandLine($CmdLineRaw) EndSwitch Else Switch $sParent Case "cmd.exe" _ExecuteCommandLine($CmdLineRaw) Case Else Run("Test.exe", "", @SW_SHOW, 1) ; $STDIN_CHILD EndSwitch EndIf Func _GetParent() Local $sParent Local $aCall = DllCall("kernel32.dll", "int", "GetCurrentProcess") If @error Or Not $aCall[0] Then Return SetError(1, 0, "") EndIf Local $hProcess = $aCall[0] Local $tPROCESS_BASIC_INFORMATION = DllStructCreate("dword ExitStatus;" & _ "ptr PebBaseAddress;" & _ "dword AffinityMask;" & _ "dword BasePriority;" & _ "dword UniqueProcessId;" & _ "dword InheritedFromUniqueProcessId") Local $aCall = DllCall("ntdll", "int", "NtQueryInformationProcess", _ "hwnd", $hProcess, _ "dword", 0, _ "ptr", DllStructGetPtr($tPROCESS_BASIC_INFORMATION), _ "dword", DllStructGetSize($tPROCESS_BASIC_INFORMATION), _ "dword*", 0) If @error Then Return SetError(2, 0, "") EndIf Local $iParentPID = DllStructGetData($tPROCESS_BASIC_INFORMATION, "InheritedFromUniqueProcessId") $aCall = DllCall("kernel32.dll", "hwnd", "OpenProcess", _ "dword", 1040, _ ; PROCESS_QUERY_INFORMATION|PROCESS_VM_READ "int", 0, _ "dword", $iParentPID) If @error Or Not $aCall[0] Then Return SetError(3, 0, "") EndIf Local $hParentHandle = $aCall[0] $aCall = DllCall("psapi.dll", "dword", "GetModuleBaseNameW", _ "hwnd", $hParentHandle, _ "ptr", 0, _ "wstr", "", _ "dword", 65536) If @error Or Not $aCall[0] Then DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hParentHandle) Return SetError(4, 0, "") EndIf $sParent = $aCall[3] DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hParentHandle) Return SetError(0, 0, $sParent) EndFunc ;==>_GetParent Func _ExecuteCommandLine($sCommandLine) If $sCommandLine Then _ExecuteCommandLineAttachConsole($sCommandLine) Return SetError(@error, 1, "") EndIf Local $aCall = DllCall("kernel32.dll", "int", "AllocConsole") If @error Or Not $aCall[0] Then Return SetError(1, 0, "") EndIf Local $hConIn = FileOpen("CONIN$", 4) ; reading handle ; _WinAPI_GetStdHandle(0) Local $hConOut = FileOpen("CONOUT$", 1) ; _WinAPI_GetStdHandle(1) FileWrite($hConOut, "Resources Viewer And Compiler >") FileClose($hConOut) Local $sPrintString While 1 Sleep(100) Switch BinaryToString(FileRead($hConIn, 512)) Case "?" & @CRLF $sPrintString = @CRLF & "... help string goes here ..." & @CRLF & @CRLF ConsoleWrite($sPrintString) ; write to the STDOUT stream $sPrintString &= "Resources Viewer And Compiler >" $hConOut = FileOpen("CONOUT$", 1) ; writing handle FileWrite($hConOut, $sPrintString) ; write to a console FileClose($hConOut) ; flush Case "gui mode" & @CRLF $sPrintString = "Switching to GUI mode..." & @CRLF ConsoleWrite($sPrintString) $hConOut = FileOpen("CONOUT$", 1) FileWrite($hConOut, $sPrintString) FileClose($hConOut) Sleep(300) DllCall("kernel32.dll", "int", "FreeConsole") Exit Case "exit" & @CRLF, "quit" & @CRLF Exit Case Else $sPrintString = @CRLF & "Invalid input. Type ? for help." & @CRLF & @CRLF ConsoleWrite($sPrintString) $sPrintString &= "Resources Viewer And Compiler >" $hConOut = FileOpen("CONOUT$", 1) FileWrite($hConOut, $sPrintString) FileClose($hConOut) EndSwitch WEnd FileClose($hConIn) Return EndFunc ;==>_ExecuteCommandLine Func _ExecuteCommandLineAttachConsole($sCommandLine) Local $aCall = DllCall("kernel32.dll", "int", "AttachConsole", _ "dword", -1) ; ATTACH_PARENT_PROCESS If @error Or Not $aCall[0] Then Return SetError(1, 0, "") EndIf Local $sPrintString Switch $sCommandLine ; let's say this is ok Case True $sPrintString = @CRLF & "Something was typed." & @CRLF & @CRLF Case Else $sPrintString = @CRLF & "Nothing typed." & @CRLF & @CRLF EndSwitch ConsoleWrite($sPrintString) Local $hConOut = FileOpen("CONOUT$", 1) FileWrite($hConOut, $sPrintString) FileClose($hConOut) ;Send("{ENTER}"); <- this is complete shit EndFunc ;==>_ExecuteCommandLineAttachConsoleHalf of the script works as I expect it to. The problem is with _ExecuteCommandLineAttachConsole() function. If you compile that script without changing AutoIt3Wrapper_GUI directives you and run exe from command prompt you will see what I mean. I need proper way of doing Send("{ENTER}") and before that I need not to lose console when I hit ENTER to run it (this sentence sounds dumb even to me, but I cannot explain it any better, so please just run it as I said).You don't even need to compile the script, you can run it from command prompt to see the issues.Any help is appreciated, of course. Mugen 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
simulation11 Posted May 6, 2009 Share Posted May 6, 2009 (edited) Very nice work. Thank u for sharing simulation rachat credit Edited May 6, 2009 by simulation11 Link to comment Share on other sites More sharing options...
quelareine Posted May 9, 2009 Share Posted May 9, 2009 very interesting! thank you for sharingsimulation rachat de credit Link to comment Share on other sites More sharing options...
meow44 Posted May 30, 2009 Share Posted May 30, 2009 interesting work. thanks for sharing simulation assurance vie Link to comment Share on other sites More sharing options...
trancexx Posted May 30, 2009 Author Share Posted May 30, 2009 Ok, I'm puzzled now. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
martin Posted May 30, 2009 Share Posted May 30, 2009 I compiled the script even though you said I don't need to, then I ran it from the command prompt like this ..>test dir_ then it says something was typed What do you want to happen after that? I assume that you want the parameter passed to test.exe to be written on th ecommand line then Enter pressed. What is wrong with Send($sCommandLine & "{ENTER}") ? Or do I not get it? Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
trancexx Posted May 30, 2009 Author Share Posted May 30, 2009 (edited) I compiled the script even though you said I don't need to, then I ran it from the command prompt like this ..>test dir_ then it says something was typed What do you want to happen after that? I assume that you want the parameter passed to test.exe to be written on th ecommand line then Enter pressed. What is wrong with Send($sCommandLine & "{ENTER}") ? Or do I not get it?Script works well if you run it (compiled) by double-click. It acts like it was compiled as CUI (I call that interactive mode - like telnet.exe for example). But if it's run thru command prompt it's not ok. It look like this with me (copy/paste): C:\Documents and Settings\trancexx>"C:\Documents and Settings\trancexx\Desktop\T est.exe" C:\Documents and Settings\trancexx> Nothing typed And it should be (like with normal CUI): C:\Documents and Settings\trancexx>"C:\Documents and Settings\trancexx\Desktop\T est.exe" Nothing typed. C:\Documents and Settings\trancexx> I drop out of warp. edit: ... I forgot to say that I'm not all that eager to find the solution to this because I really don't have much use for it now like I did back then. Maybe just as a curiosity now. I would have bumped this thread otherwise. My puzzleness was about three bumps by french girl. Edited May 30, 2009 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
wraithdu Posted June 2, 2009 Share Posted June 2, 2009 (edited) I think the problem is that 'cmd.exe' is a command interpreter, and interprets the @CRLF as an input command (pressing the enter key), which displays the current directory. I *think* when compiling to CUI that the child process has its own screen buffer, so this doesn't happen.Maybe after attaching to the console, tryCreateConsoleScreenBufferSetConsoleActiveScreenBufferGetStdHandle to get STD_OUTPUT_HANDLEwrite stuff with WriteConsoleACloseHandle on the new screen bufferFreeConsole to detach...untested, might also be crap :/ Edited June 2, 2009 by wraithdu Link to comment Share on other sites More sharing options...
wraithdu Posted June 2, 2009 Share Posted June 2, 2009 Ok, this mostly works, except it covers whatever you have there already, then the old buffer shows again when you close the handle. Close enough? Func _ExecuteCommandLineAttachConsole($sCommandLine) Local $aCall = DllCall("kernel32.dll", "int", "AttachConsole", "dword", -1) If @error Or Not $aCall[0] Then Return SetError(1, 0, "") EndIf Local $sPrintString Switch $sCommandLine ; let's say this is ok Case True $sPrintString = @CRLF & "Something was typed." & @CRLF & @CRLF Case Else $sPrintString = @CRLF & "Nothing typed." & @CRLF & @CRLF EndSwitch $aCall = DllCall("kernel32.dll", "ptr", "CreateConsoleScreenBuffer", "dword", BitOR(0x40000000, 0x80000000), "dword", 0, "ptr", 0, "dword", 1, "ptr", 0) Local $hBuff = $aCall[0] ;~ MsgBox(0, "Create", "hBuff: " & $hBuff) $aCall = DllCall("kernel32.dll", "int", "SetConsoleActiveScreenBuffer", "ptr", $hBuff) ;~ MsgBox(0, "Active", "Set active: " & $aCall[0]) $aCall = DllCall("kernel32.dll", "int", "WriteConsoleA", "ptr", $hBuff, "str", $sPrintString, "dword", StringLen($sPrintString), "dword*", 0, "ptr", 0) ;~ MsgBox(0, "Write", "Chars written: " & $aCall[4]) Sleep(5000) DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hBuff) DllCall("kernel32.dll", "int", "FreeConsole") EndFunc ;==>_ExecuteCommandLineAttachConsole Link to comment Share on other sites More sharing options...
trancexx Posted June 3, 2009 Author Share Posted June 3, 2009 Yes close. It's something like missing link. Thanks, will see how to bend it. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Valuater Posted June 3, 2009 Share Posted June 3, 2009 Very nice work. Thank u for sharing simulation rachat creditLast Seen: 5th May 2009 - 05:40 PMLocal Time: Jun 3 2009, 07:24 PMvery interesting! thank you for sharingsimulation rachat de credit Last Seen: 11th May 2009 - 07:59 AMLocal Time: Jun 3 2009, 07:24 PMinteresting work. thanks for sharing simulation assurance vie Last Seen: 30th May 2009 - 09:24 AMLocal Time: Jun 3 2009, 07:24 PM... and, all have just "one post" and, All are from the "same time zone" as yours.... Hmmmm??? Maybe you got some girl after you!!!8) Link to comment Share on other sites More sharing options...
wraithdu Posted June 3, 2009 Share Posted June 3, 2009 (edited) I did some googling about this general idea, and no one on the net has come up with a good workaround to integrate a GUI app (/SUBSYSTEM:WINDOWS) into the console when launched by cmd.exe. As you can see my workaround provides you with a screen buffer to display data, but it seems very difficult (impossible?) to *read* data from cmd's STD_INPUT. I tried and failed. Even managed to BSOD Win7 once in the process :/ Options I saw: 1) create a console app and FreeConsole() or hide the window if it's not needed (get HWND with GetConsoleWindow()) 2) create a GUI app and use AllocConsole() to create a console window if needed 3) create two versions of the app, on GUI and one console, and launch / relaunch appropriately Edited June 3, 2009 by wraithdu Link to comment Share on other sites More sharing options...
trancexx Posted June 3, 2009 Author Share Posted June 3, 2009 I did some googling about this general idea, and no one on the net has come up with a good workaround to integrate a GUI app (/SUBSYSTEM:WINDOWS) into the console when launched by cmd.exe. As you can see my workaround provides you with a screen buffer to display data, but it seems very difficult (impossible?) to *read* data from cmd's STD_INPUT. I tried and failed. Even managed to BSOD Win7 once in the process :/Options I saw:1) create a console app and FreeConsole() or hide the window if it's not needed (get HWND with GetConsoleWindow())2) create a GUI app and use AllocConsole() to create a console window if needed3) create two versions of the app, on GUI and one console, and launch / relaunch appropriatelyNow you are teasing me to take this again and work on it. @Valuater, no doubt about that ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
AJStevens Posted August 17, 2010 Share Posted August 17, 2010 I did some googling about this general idea, and no one on the net has come up with a good workaround to integrate a GUI app (/SUBSYSTEM:WINDOWS) into the console when launched by cmd.exe. As you can see my workaround provides you with a screen buffer to display data, but it seems very difficult (impossible?) to *read* data from cmd's STD_INPUT. I tried and failed. Even managed to BSOD Win7 once in the process :/Options I saw:1) create a console app and FreeConsole() or hide the window if it's not needed (get HWND with GetConsoleWindow())2) create a GUI app and use AllocConsole() to create a console window if needed3) create two versions of the app, on GUI and one console, and launch / relaunch appropriatelySounds similiar to what I wanted: http://www.autoitscript.com/forum/index.php?showtopic=118552Now you are teasing me to take this again and work on it. @Valuater, no doubt about that trancexx, don't suppose you got anywhere with this did you?To be honest, all I want is to display text back to the console window at the moment, so that if the exe is run from a commandline ConsoleWrite will output to the commandline. As per that thread, thanks to UEZ, got some logic to work out if it's been run from a console window or not, if not then default to using MsgBox instead of course.Although, I can see that being able to send back into it, would be useful, a full CUI while still being a GUI too, would save on having to make two seperate executables. Link to comment Share on other sites More sharing options...
trancexx Posted August 18, 2010 Author Share Posted August 18, 2010 trancexx, don't suppose you got anywhere with this did you?I remember that I have forgotten the answer to that question.Lost interest back there since I've managed to approach the problem differently.Now that I think of general idea I can't not think about thread context manipulation. (Not this thread of course) ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
AJStevens Posted August 18, 2010 Share Posted August 18, 2010 I remember that I have forgotten the answer to that question.Lost interest back there since I've managed to approach the problem differently.Now that I think of general idea I can't not think about thread context manipulation. (Not this thread of course)Errr..... Ok... ???Out of interest, what was your different approach, did it work out? Link to comment Share on other sites More sharing options...
trancexx Posted August 18, 2010 Author Share Posted August 18, 2010 Errr..... Ok... ??? Out of interest, what was your different approach, did it work out? Yes it did. Conclusion of intensive thinking (yeah right!) was that it's not CUI I want. It's non-GUI. So that if explorer.exe runs my app GUI creation is forced. And is some other program runs it, it would skip GUI creation and proceed with command line interpretation an execution through function called _ExecuteCommandLine(). ConsoleWrite() and ConsoleWriteError() are used for communication (one way, obviously). Had this as part of the comments/code:;Suggestion for parents: # Local $hResourcesExe = Run("Resources.exe -add -compile MyRes.dll -res SomeAnimated.gif -type GIF -name 1 -lang 0", "", @SW_HIDE, 6); $STDERR_CHILD + $STDOUT_CHILD # Local $sLine, $sLineError # # While 1 # $sLineError = StderrRead($hResourcesExe) # If @error Then ExitLoop # If $sLineError Then # ConsoleWrite($sLineError) # EndIf # Sleep(100) # WEnd # # While 1 # $sLine = StdoutRead($hResourcesExe) # If @error Then ExitLoop # If $sLine Then # ConsoleWrite($sLine) # EndIf # Sleep(100) # WEnd ; End suggestion ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
AJStevens Posted August 18, 2010 Share Posted August 18, 2010 (edited) Yes it did.Conclusion of intensive thinking (yeah right!) was that it's not CUI I want. It's non-GUI. So that if explorer.exe runs my app GUI creation is forced. And is some other program runs it, it would skip GUI creation and proceed with command line interpretation an execution through function called _ExecuteCommandLine(). ConsoleWrite() and ConsoleWriteError() are used for communication (one way, obviously). Had this as part of the comments/code:Indeed, I didn't realise how full blown CUI is in autoit, at the moment I definately don't need that, just Consolewrite as you said, basically for outputting results to console window if launched from it with commandline switches but if double clicked run a GUI, pretty sure many exes are capable of this.Unfortunately I don't see how your code snippet helps with that, what is resources.exe ?PS. I found compiling as a CUI gives the functionality but when running by a double-click/explorer or not run from within a command window then you get an extra command window behind the GUI, which you can hide or free, but don't want it to appear at all really. Plus I get the feeling I should be compiling as a GUI as it's not really a CUI in the strict sense. Edited August 18, 2010 by AJStevens Link to comment Share on other sites More sharing options...
trancexx Posted August 18, 2010 Author Share Posted August 18, 2010 Unfortunately I don't see how your code snippet helps with that, what is resources.exe ?Compiled script that's run in either GUI or non-GUI mode depending on what starts it.That's ok, I do. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
AJStevens Posted August 19, 2010 Share Posted August 19, 2010 Compiled script that's run in either GUI or non-GUI mode depending on what starts it.That's ok, I do.Gee, thanks... 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