Opened 15 months ago
Last modified 13 months ago
#3970 new Feature Request
Macro @IsConsole
Reported by: | Alecsis1 | Owned by: | |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | Severity: | None | |
Keywords: | Cc: |
Description
Hi all!
Sometimes there's need to distinguish, is a script compiled as Console or
GUI Application. For example, having compiled our script as GUI app we won't see any output from ConsoleWrite/ConsoleWriteError, so we should use MsgBox or smth other way.
Thus such macro I'd like to offer could be rather useful.
Thank you for attention!
Attachments (0)
Change History (4)
comment:1 Changed 15 months ago by TicketCleanup
- Version 3.3.14.0 deleted
comment:2 Changed 13 months ago by Andreik
Now we need macros for everything. This can be achieved easily without any macro.
If IsConsole() Then ConsoleWrite('Yayyy! I am a console application.' & @CRLF) Else MsgBox(0, 'Yayyy!', 'I am a GUI application.') EndIf Func IsConsole() If Not @Compiled Then Return SetError(1, 0, Null) Local $IMAGE_SUBSYSTEM_WINDOWS_CUI = 3 Local $tagIMAGE_DOS_HEADER = 'WORD e_magic; WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_cparhdr; ' & _ 'WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; ' & _ 'WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oemid; WORD e_oeminfo; WORD e_res2[10]; LONG e_lfanew;' Local $tagIMAGE_FILE_HEADER = 'WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; ' & _ 'DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics;' If @AutoItX64 Then Local $tagIMAGE_OPTIONAL_HEADER = 'WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; ' & _ 'DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; ' & _ 'DWORD BaseOfCode; PTR ImageBase; DWORD SectionAlignment; DWORD FileAlignment; ' & _ 'WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; ' & _ 'WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; ' & _ 'DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; ' & _ 'WORD Subsystem; WORD DllCharacteristics; PTR SizeOfStackReserve; PTR SizeOfStackCommit; ' & _ 'PTR SizeOfHeapReserve; PTR SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes;' Else Local $tagIMAGE_OPTIONAL_HEADER = 'WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; ' & _ 'DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; ' & _ 'DWORD BaseOfCode; DWORD BaseOfData; PTR ImageBase; DWORD SectionAlignment; DWORD FileAlignment; ' & _ 'WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; ' & _ 'WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; ' & _ 'DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; ' & _ 'WORD Subsystem; WORD DllCharacteristics; PTR SizeOfStackReserve; PTR SizeOfStackCommit; ' & _ 'PTR SizeOfHeapReserve; PTR SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes;' EndIf Local $tagIMAGE_NT_HEADER = 'DWORD Signature;' & $tagIMAGE_FILE_HEADER & $tagIMAGE_OPTIONAL_HEADER Local $hFile = FileOpen(@AutoItExe, 16) Local $dBytes = FileRead($hFile) FileClose($hFile) Local $tExe = DllStructCreate('byte Data[' & BinaryLen($dBytes) & ']') Local $pExe = DllStructGetPtr($tExe) DllStructSetData($tExe, 'Data', $dBytes) Local $tIMAGE_DOS_HEADER = DllStructCreate($tagIMAGE_DOS_HEADER, $pExe) If DllStructGetData($tIMAGE_DOS_HEADER, 'e_magic') <> 0x5A4D Then Return SetError(2, 0, Null) EndIf Local $pPEHeader = $pExe + DllStructGetData($tIMAGE_DOS_HEADER, 'e_lfanew') Local $tIMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $pPEHeader) If DllStructGetData($tIMAGE_NT_HEADER, 'Signature') <> 0x4550 Then Return SetError(3, 0, Null) EndIf Return DllStructGetData($tIMAGE_NT_HEADER, 'Subsystem') == $IMAGE_SUBSYSTEM_WINDOWS_CUI EndFunc
comment:3 Changed 13 months ago by jchd18
Yes that, or simpler: always use CW() in place of ConsoleWrite() like this:
Func CW($s = "") If @Compiled Then _CUI_ConsoleWrite($s) Else _ConsoleWrite($s) EndIf EndFunc ;==>CW Func _CUI_ConsoleWrite(ByRef $s) Local Static $hDll = DllOpen("kernel32.dll") Local Static $hCon = __CUI_ConsoleInit($hDll) DllCall($hDll, "bool", "WriteConsoleW", "handle", $hCon, "wstr", $s & @LF, "dword", StringLen($s) + 1, "dword*", 0, "ptr", 0) Return EndFunc ;==>_CUI_ConsoleWrite ; internal use only Func __CUI_ConsoleInit(ByRef $hDll) DllCall($hDll, "bool", "AllocConsole") ;~ The following 2 lines don't work for compiled scripts due to a MS bug ;~ see last post in thread https://developercommunity.visualstudio.com/t/setconsoleoutputcpcp-utf8-results-in-code-page-850/413190 ;~ where MS support acknowledges it's a (still unfixed) bug in Windows itself ;~ So you can only display current locale codepage using current console font in a console when your script is compiled ;~ When running your script from SciTE, the UTF8 setting of SciTE overrides this bug and Unicode can be displayed ;~ DllCall("Kernel32.dll", "bool", "SetConsoleCP", "uint", 65001) ;~ DllCall("Kernel32.dll", "bool", "SetConsoleOutputCP", "uint", 65001) Return DllCall($hDll, "handle", "GetStdHandle", "int", -11)[0] EndFunc ;==>__CUI_ConsoleInit ; Unicode-aware ConsoleWrite Func _ConsoleWrite(ByRef $s) ConsoleWrite(BinaryToString(StringToBinary($s & @LF, 4), 1)) EndFunc ;==>_ConsoleWrite
Works for CUI or GUI, compiled or not.
comment:4 Changed 13 months ago by anonymous
Ok, let there be built-in function IsConsole(), why no?
As for examples above I've got my own functions which are almost th same :)
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Automatic ticket cleanup.