From f39051ff5fd27550ef00d62d1bfaffcf2cf4a51b Mon Sep 17 00:00:00 2001 From: yuriy Date: Tue, 28 Feb 2023 00:31:11 -0500 Subject: [PATCH] Added Libs that are used by both projects --- Json.ahk | 374 ++++++++++++++++++++++++++++++++++++++++++++++++ RunCMD.ahk | 50 +++++++ SChrome.ahk | 54 +++++++ StdOutToVar.ahk | 56 ++++++++ 4 files changed, 534 insertions(+) create mode 100644 Json.ahk create mode 100644 RunCMD.ahk create mode 100644 SChrome.ahk create mode 100644 StdOutToVar.ahk diff --git a/Json.ahk b/Json.ahk new file mode 100644 index 0000000..e5b3d19 --- /dev/null +++ b/Json.ahk @@ -0,0 +1,374 @@ +/** + * Lib: JSON.ahk + * JSON lib for AutoHotkey. + * Version: + * v2.1.3 [updated 04/18/2016 (MM/DD/YYYY)] + * License: + * WTFPL [http://wtfpl.net/] + * Requirements: + * Latest version of AutoHotkey (v1.1+ or v2.0-a+) + * Installation: + * Use #Include JSON.ahk or copy into a function library folder and then + * use #Include + * Links: + * GitHub: - https://github.com/cocobelgica/AutoHotkey-JSON + * Forum Topic - http://goo.gl/r0zI8t + * Email: - cocobelgica gmail com + */ + + +/** + * Class: JSON + * The JSON object contains methods for parsing JSON and converting values + * to JSON. Callable - NO; Instantiable - YES; Subclassable - YES; + * Nestable(via #Include) - NO. + * Methods: + * Load() - see relevant documentation before method definition header + * Dump() - see relevant documentation before method definition header + */ +class JSON +{ + /** + * Method: Load + * Parses a JSON string into an AHK value + * Syntax: + * value := JSON.Load( text [, reviver ] ) + * Parameter(s): + * value [retval] - parsed value + * text [in, ByRef] - JSON formatted string + * reviver [in, opt] - function object, similar to JavaScript's + * JSON.parse() 'reviver' parameter + */ + class Load extends JSON.Functor + { + Call(self, ByRef text, reviver:="") + { + this.rev := IsObject(reviver) ? reviver : false + ; Object keys(and array indices) are temporarily stored in arrays so that + ; we can enumerate them in the order they appear in the document/text instead + ; of alphabetically. Skip if no reviver function is specified. + this.keys := this.rev ? {} : false + + static quot := Chr(34), bashq := "\" . quot + , json_value := quot . "{[01234567890-tfn" + , json_value_or_array_closing := quot . "{[]01234567890-tfn" + , object_key_or_object_closing := quot . "}" + + key := "" + is_key := false + root := {} + stack := [root] + next := json_value + pos := 0 + + while ((ch := SubStr(text, ++pos, 1)) != "") { + if InStr(" `t`r`n", ch) + continue + if !InStr(next, ch, 1) + this.ParseError(next, text, pos) + + holder := stack[1] + is_array := holder.IsArray + + if InStr(",:", ch) { + next := (is_key := !is_array && ch == ",") ? quot : json_value + + } else if InStr("}]", ch) { + ObjRemoveAt(stack, 1) + next := stack[1]==root ? "" : stack[1].IsArray ? ",]" : ",}" + + } else { + if InStr("{[", ch) { + ; Check if Array() is overridden and if its return value has + ; the 'IsArray' property. If so, Array() will be called normally, + ; otherwise, use a custom base object for arrays + static json_array := Func("Array").IsBuiltIn || ![].IsArray ? {IsArray: true} : 0 + + ; sacrifice readability for minor(actually negligible) performance gain + (ch == "{") + ? ( is_key := true + , value := {} + , next := object_key_or_object_closing ) + ; ch == "[" + : ( value := json_array ? new json_array : [] + , next := json_value_or_array_closing ) + + ObjInsertAt(stack, 1, value) + + if (this.keys) + this.keys[value] := [] + + } else { + if (ch == quot) { + i := pos + while (i := InStr(text, quot,, i+1)) { + value := StrReplace(SubStr(text, pos+1, i-pos-1), "\\", "\u005c") + + static tail := A_AhkVersion<"2" ? 0 : -1 + if (SubStr(value, tail) != "\") + break + } + + if (!i) + this.ParseError("'", text, pos) + + value := StrReplace(value, "\/", "/") + , value := StrReplace(value, bashq, quot) + , value := StrReplace(value, "\b", "`b") + , value := StrReplace(value, "\f", "`f") + , value := StrReplace(value, "\n", "`n") + , value := StrReplace(value, "\r", "`r") + , value := StrReplace(value, "\t", "`t") + + pos := i ; update pos + + i := 0 + while (i := InStr(value, "\",, i+1)) { + if !(SubStr(value, i+1, 1) == "u") + this.ParseError("\", text, pos - StrLen(SubStr(value, i+1))) + + uffff := Abs("0x" . SubStr(value, i+2, 4)) + if (A_IsUnicode || uffff < 0x100) + value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6) + } + + if (is_key) { + key := value, next := ":" + continue + } + + } else { + value := SubStr(text, pos, i := RegExMatch(text, "[\]\},\s]|$",, pos)-pos) + + static number := "number", integer :="integer" + if value is %number% + { + if value is %integer% + value += 0 + } + else if (value == "true" || value == "false") + value := %value% + 0 + else if (value == "null") + value := "" + else + ; we can do more here to pinpoint the actual culprit + ; but that's just too much extra work. + this.ParseError(next, text, pos, i) + + pos += i-1 + } + + next := holder==root ? "" : is_array ? ",]" : ",}" + } ; If InStr("{[", ch) { ... } else + + is_array? key := ObjPush(holder, value) : holder[key] := value + + if (this.keys && this.keys.HasKey(holder)) + this.keys[holder].Push(key) + } + + } ; while ( ... ) + + return this.rev ? this.Walk(root, "") : root[""] + } + + ParseError(expect, ByRef text, pos, len:=1) + { + static quot := Chr(34), qurly := quot . "}" + + line := StrSplit(SubStr(text, 1, pos), "`n", "`r").Length() + col := pos - InStr(text, "`n",, -(StrLen(text)-pos+1)) + msg := Format("{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}" + , (expect == "") ? "Extra data" + : (expect == "'") ? "Unterminated string starting at" + : (expect == "\") ? "Invalid \escape" + : (expect == ":") ? "Expecting ':' delimiter" + : (expect == quot) ? "Expecting object key enclosed in double quotes" + : (expect == qurly) ? "Expecting object key enclosed in double quotes or object closing '}'" + : (expect == ",}") ? "Expecting ',' delimiter or object closing '}'" + : (expect == ",]") ? "Expecting ',' delimiter or array closing ']'" + : InStr(expect, "]") ? "Expecting JSON value or array closing ']'" + : "Expecting JSON value(string, number, true, false, null, object or array)" + , line, col, pos) + + static offset := A_AhkVersion<"2" ? -3 : -4 + throw Exception(msg, offset, SubStr(text, pos, len)) + } + + Walk(holder, key) + { + value := holder[key] + if IsObject(value) { + for i, k in this.keys[value] { + ; check if ObjHasKey(value, k) ?? + v := this.Walk(value, k) + if (v != JSON.Undefined) + value[k] := v + else + ObjDelete(value, k) + } + } + + return this.rev.Call(holder, key, value) + } + } + + /** + * Method: Dump + * Converts an AHK value into a JSON string + * Syntax: + * str := JSON.Dump( value [, replacer, space ] ) + * Parameter(s): + * str [retval] - JSON representation of an AHK value + * value [in] - any value(object, string, number) + * replacer [in, opt] - function object, similar to JavaScript's + * JSON.stringify() 'replacer' parameter + * space [in, opt] - similar to JavaScript's JSON.stringify() + * 'space' parameter + */ + class Dump extends JSON.Functor + { + Call(self, value, replacer:="", space:="") + { + this.rep := IsObject(replacer) ? replacer : "" + + this.gap := "" + if (space) { + static integer := "integer" + if space is %integer% + Loop, % ((n := Abs(space))>10 ? 10 : n) + this.gap .= " " + else + this.gap := SubStr(space, 1, 10) + + this.indent := "`n" + } + + return this.Str({"": value}, "") + } + + Str(holder, key) + { + value := holder[key] + + if (this.rep) + value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined) + + if IsObject(value) { + ; Check object type, skip serialization for other object types such as + ; ComObject, Func, BoundFunc, FileObject, RegExMatchObject, Property, etc. + static type := A_AhkVersion<"2" ? "" : Func("Type") + if (type ? type.Call(value) == "Object" : ObjGetCapacity(value) != "") { + if (this.gap) { + stepback := this.indent + this.indent .= this.gap + } + + is_array := value.IsArray + ; Array() is not overridden, rollback to old method of + ; identifying array-like objects. Due to the use of a for-loop + ; sparse arrays such as '[1,,3]' are detected as objects({}). + if (!is_array) { + for i in value + is_array := i == A_Index + until !is_array + } + + str := "" + if (is_array) { + Loop, % value.Length() { + if (this.gap) + str .= this.indent + + v := this.Str(value, A_Index) + str .= (v != "") ? v . "," : "null," + } + } else { + colon := this.gap ? ": " : ":" + for k in value { + v := this.Str(value, k) + if (v != "") { + if (this.gap) + str .= this.indent + + str .= this.Quote(k) . colon . v . "," + } + } + } + + if (str != "") { + str := RTrim(str, ",") + if (this.gap) + str .= stepback + } + + if (this.gap) + this.indent := stepback + + return is_array ? "[" . str . "]" : "{" . str . "}" + } + + } else ; is_number ? value : "value" + return ObjGetCapacity([value], 1)=="" ? value : this.Quote(value) + } + + Quote(string) + { + static quot := Chr(34), bashq := "\" . quot + + if (string != "") { + string := StrReplace(string, "\", "\\") + ; , string := StrReplace(string, "/", "\/") ; optional in ECMAScript + , string := StrReplace(string, quot, bashq) + , string := StrReplace(string, "`b", "\b") + , string := StrReplace(string, "`f", "\f") + , string := StrReplace(string, "`n", "\n") + , string := StrReplace(string, "`r", "\r") + , string := StrReplace(string, "`t", "\t") + + static rx_escapable := A_AhkVersion<"2" ? "O)[^\x20-\x7e]" : "[^\x20-\x7e]" + while RegExMatch(string, rx_escapable, m) + string := StrReplace(string, m.Value, Format("\u{1:04x}", Ord(m.Value))) + } + + return quot . string . quot + } + } + + /** + * Property: Undefined + * Proxy for 'undefined' type + * Syntax: + * undefined := JSON.Undefined + * Remarks: + * For use with reviver and replacer functions since AutoHotkey does not + * have an 'undefined' type. Returning blank("") or 0 won't work since these + * can't be distnguished from actual JSON values. This leaves us with objects. + * Replacer() - the caller may return a non-serializable AHK objects such as + * ComObject, Func, BoundFunc, FileObject, RegExMatchObject, and Property to + * mimic the behavior of returning 'undefined' in JavaScript but for the sake + * of code readability and convenience, it's better to do 'return JSON.Undefined'. + * Internally, the property returns a ComObject with the variant type of VT_EMPTY. + */ + Undefined[] + { + get { + static empty := {}, vt_empty := ComObject(0, &empty, 1) + return vt_empty + } + } + + class Functor + { + __Call(method, ByRef arg, args*) + { + ; When casting to Call(), use a new instance of the "function object" + ; so as to avoid directly storing the properties(used across sub-methods) + ; into the "function object" itself. + if IsObject(method) + return (new this).Call(method, arg, args*) + else if (method == "") + return (new this).Call(arg, args*) + } + } +} diff --git a/RunCMD.ahk b/RunCMD.ahk new file mode 100644 index 0000000..d4f5d7d --- /dev/null +++ b/RunCMD.ahk @@ -0,0 +1,50 @@ + ; PowerShell +; https://www.autohotkey.com/boards/viewtopic.php?p=341237#p341237 + + +RunCMD(CmdLine, WorkingDir:="", Codepage:="CP0", Fn:="RunCMD_Output") { ; RunCMD v0.94 +Local ; RunCMD v0.94 by SKAN on D34E/D37C @ autohotkey.com/boards/viewtopic.php?t=74647 +Global A_Args ; Based on StdOutToVar.ahk by Sean @ autohotkey.com/board/topic/15455-stdouttovar + + Fn := IsFunc(Fn) ? Func(Fn) : 0 +, DllCall("CreatePipe", "PtrP",hPipeR:=0, "PtrP",hPipeW:=0, "Ptr",0, "Int",0) +, DllCall("SetHandleInformation", "Ptr",hPipeW, "Int",1, "Int",1) +, DllCall("SetNamedPipeHandleState","Ptr",hPipeR, "UIntP",PIPE_NOWAIT:=1, "Ptr",0, "Ptr",0) + +, P8 := (A_PtrSize=8) +, VarSetCapacity(SI, P8 ? 104 : 68, 0) ; STARTUPINFO structure +, NumPut(P8 ? 104 : 68, SI) ; size of STARTUPINFO +, NumPut(STARTF_USESTDHANDLES:=0x100, SI, P8 ? 60 : 44,"UInt") ; dwFlags +, NumPut(hPipeW, SI, P8 ? 88 : 60) ; hStdOutput +, NumPut(hPipeW, SI, P8 ? 96 : 64) ; hStdError +, VarSetCapacity(PI, P8 ? 24 : 16) ; PROCESS_INFORMATION structure + + If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "Int",0, "Int",True + ,"Int",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1, "UInt"), "Int",0 + ,"Ptr",WorkingDir ? &WorkingDir : 0, "Ptr",&SI, "Ptr",&PI) + Return Format("{1:}", "", ErrorLevel := -1 + ,DllCall("CloseHandle", "Ptr",hPipeW), DllCall("CloseHandle", "Ptr",hPipeR)) + + DllCall("CloseHandle", "Ptr",hPipeW) +, A_Args.RunCMD := { "PID": NumGet(PI, P8? 16 : 8, "UInt") } +, File := FileOpen(hPipeR, "h", Codepage) + +, LineNum := 1, sOutput := "" + While (A_Args.RunCMD.PID + DllCall("Sleep", "Int",0)) + and DllCall("PeekNamedPipe", "Ptr",hPipeR, "Ptr",0, "Int",0, "Ptr",0, "Ptr",0, "Ptr",0) + While A_Args.RunCMD.PID and (Line := File.ReadLine()) + sOutput .= Fn ? Fn.Call(Line, LineNum++) : Line + + A_Args.RunCMD.PID := 0 +, hProcess := NumGet(PI, 0) +, hThread := NumGet(PI, A_PtrSize) + +, DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode:=0) +, DllCall("CloseHandle", "Ptr",hProcess) +, DllCall("CloseHandle", "Ptr",hThread) +, DllCall("CloseHandle", "Ptr",hPipeR) + +, ErrorLevel := ExitCode + +Return sOutput +} diff --git a/SChrome.ahk b/SChrome.ahk new file mode 100644 index 0000000..535dcc8 --- /dev/null +++ b/SChrome.ahk @@ -0,0 +1,54 @@ +; Written by AHK_User 2019-10-11 +; Special thanks to tmplinshi, CH HAN and Joe Glines +; https://www.autohotkey.com/boards/viewtopic.php?f=7&t=32323&p=296136&hilit=schrome_get#p296136 +;Driver := SChrome_Get("https://stackoverflow.com/questions/37088589/selenium-wont-open-a-new-url-in-a-new-tab-python-chrome/39353910#39353910",,"Tab") + +; Written by AHK_User 2019-10-11 +; Special thanks to tmplinshi, CH HAN and Joe Glines + +SChrome_Get(URL := "", Profile := "Profile 1", IP_Port := "127.0.0.1:9222"){ + IP_Port_Nr := RegExReplace(IP_Port, ".*:(\d*)", "$1") + if WinExist("ahk_exe Chrome.exe"){ + WinGet, pid, PID, ahk_exe chrome.exe + for item in ComObjGet("winmgmts:").ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId='" pid "'"){ + if RegExMatch(item.CommandLine, "i)--remote-debugging-port=\K\d+", port){ + break + } + } + if (Port=""){ + MsgBox, 36, ,Chrome Needs to be started in debugging mode in order for Autohotkey to connect to it.`nIs it ok to restart Chrome in debugmode to enable a connection? + IfMsgBox, Yes + { + While(WinExist("ahk_exe chrome.exe")) { + WinClose, ahk_exe chrome.exe + } + Process, WaitClose, chrome.exe + } + Else{ + Exit + } + } + } + + if(URL!="" or !winExist("ahk_class Chrome_WidgetWin_1")){ + ; run % "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --remote-debugging-port=" IP_Port_Nr ( winExist("ahk_class Chrome_WidgetWin_1") ? " --new-window " : " " ) URL + if(A_ComputerName = "WLatitude") + { + run, C:\Software\Chromium\chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" ; %URL% + ; sleep, 1000 + ; run, C:\Software\Chromium\chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" --new-window %URL% + } + else, + { + run, chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" %URL% + ; sleep, 1000 + ; run, chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" --new-window %URL% + + } + } + + Driver := ComObjCreate("Selenium.ChromeDriver") + Driver.SetCapability("debuggerAddress", IP_Port) + Driver.Start() + return Driver +} \ No newline at end of file diff --git a/StdOutToVar.ahk b/StdOutToVar.ahk new file mode 100644 index 0000000..5525d35 --- /dev/null +++ b/StdOutToVar.ahk @@ -0,0 +1,56 @@ +; Edited by Masonjar13 to be compatible with 32 and 64-bit (2015) + +;msgbox % StdOutToVar("ipconfig") + +StdOutToVar( sCmd ) { ; GAHK32 ; Modified Version : SKAN 05-Jul-2013 http://goo.gl/j8XJXY + ; msgbox, getting stdout + Static StrGet := "StrGet" ; Original Author : Sean 20-Feb-2007 http://goo.gl/mxCdn + + DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 ) + DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 ) + + if(a_ptrSize=8){ + VarSetCapacity( STARTUPINFO, 104, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 + NumPut( 104, STARTUPINFO, 0 ) ; cbSize + NumPut( 0x100, STARTUPINFO, 60 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 + NumPut( hPipeWrite, STARTUPINFO, 88 ) ; hStdOutput + NumPut( hPipeWrite, STARTUPINFO, 96 ) ; hStdError + VarSetCapacity( PROCESS_INFORMATION, 32 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI + }else{ + VarSetCapacity( STARTUPINFO, 68, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 + NumPut( 68, STARTUPINFO, 0 ) ; cbSize + NumPut( 0x100, STARTUPINFO, 44 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 + NumPut( hPipeWrite, STARTUPINFO, 60 ) ; hStdOutput + NumPut( hPipeWrite, STARTUPINFO, 64 ) ; hStdError + VarSetCapacity( PROCESS_INFORMATION, 16 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI + } + If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ; http://goo.gl/USC5a + , UInt,1, UInt,0x08000000, UInt,0, UInt,0 + , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) + Return "" + , DllCall( "CloseHandle", UInt,hPipeWrite ) + , DllCall( "CloseHandle", UInt,hPipeRead ) + , DllCall( "SetLastError", Int,-1 ) + + hProcess := NumGet( PROCESS_INFORMATION, 0 ) + if(a_is64bitOS) + hThread := NumGet( PROCESS_INFORMATION, 8 ) + else + hThread := NumGet( PROCESS_INFORMATION, 4 ) + + DllCall( "CloseHandle", UInt,hPipeWrite ) + + AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" ) ; A_IsClassic + VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 + + While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, UInt,0 ) + sOutput .= ( AIC && NumPut( 0, Buffer, nSz, "UChar" ) && VarSetCapacity( Buffer,-1 ) ) + ? Buffer : %StrGet%( &Buffer, nSz, "CP850" ) + + DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode ) + DllCall( "CloseHandle", UInt,hProcess ) + DllCall( "CloseHandle", UInt,hThread ) + DllCall( "CloseHandle", UInt,hPipeRead ) + +Return sOutput, DllCall( "SetLastError", UInt,ExitCode ) +}