Skip to content

Instantly share code, notes, and snippets.

@qwerty12
Last active November 16, 2024 20:30
Show Gist options
  • Save qwerty12/5537d1b2153259a8f48a6c8dd60d4c02 to your computer and use it in GitHub Desktop.
Save qwerty12/5537d1b2153259a8f48a6c8dd60d4c02 to your computer and use it in GitHub Desktop.
;@Ahk2Exe-ConsoleApp
#NoEnv
#NoTrayIcon
AutoTrim Off
SetBatchLines, -1
ListLines, Off
#SingleInstance ignore
SetWorkingDir %A_ScriptDir%
; https://docs.jellyseerr.dev/getting-started/buildfromsource#installation-1
; https://stackoverflow.com/a/46006249
/*
scoop install nodejs-lts pnpm byenow
npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"
quick version:
git clone -b main --single-branch --depth=1 https://github.com/Fallenbagel/jellyseerr.git
OR
git clone https://github.com/Fallenbagel/jellyseerr.git
git checkout main
git branch -D develop
git gc --aggressive
Do not run pnpm config --location project set node-linker hoisted - pnpm goes into a loop
*/
/*
RegisterSyncCallback (by Lexikos)
A replacement for RegisterCallback for use with APIs that will call
the callback on the wrong thread. Synchronizes with the script's main
thread via a window message.
This version tries to emulate RegisterCallback as much as possible
without using RegisterCallback, so shares most of its limitations,
and some enhancements that could be made are not.
Other differences from v1 RegisterCallback:
- Variadic mode can't be emulated exactly, so is not supported.
- A_EventInfo can't be set in v1, so is not supported.
- Fast mode is not supported (the option is ignored).
- ByRef parameters are allowed (but ByRef is ignored).
- Throws instead of returning "" on failure.
*/
RegisterSyncCallback(FunctionName, Options:="", ParamCount:="") {
if !(fn := Func(FunctionName)) || fn.IsBuiltIn
throw Exception("Bad function", -1, FunctionName)
if (ParamCount == "")
ParamCount := fn.MinParams
if (ParamCount > fn.MaxParams && !fn.IsVariadic || ParamCount+0 < fn.MinParams)
throw Exception("Bad param count", -1, ParamCount)
static sHwnd := 0, sMsg, sSendMessageW
if !sHwnd
{
Gui RegisterSyncCallback: +Parent%A_ScriptHwnd% +hwndsHwnd
OnMessage(sMsg := 0x8000, Func("RegisterSyncCallback_Msg"))
sSendMessageW := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "user32.dll", "ptr"), "astr", "SendMessageW", "ptr")
}
if !(pcb := DllCall("GlobalAlloc", "uint", 0, "ptr", 96, "ptr"))
throw
DllCall("VirtualProtect", "ptr", pcb, "ptr", 96, "uint", 0x40, "uint*", 0)
p := pcb
if (A_PtrSize = 8)
{
/*
48 89 4c 24 08 ; mov [rsp+8], rcx
48 89 54'24 10 ; mov [rsp+16], rdx
4c 89 44 24 18 ; mov [rsp+24], r8
4c'89 4c 24 20 ; mov [rsp+32], r9
48 83 ec 28' ; sub rsp, 40
4c 8d 44 24 30 ; lea r8, [rsp+48] (arg 3, &params)
49 b9 .. ; mov r9, .. (arg 4, operand to follow)
*/
p := NumPut(0x54894808244c8948, p+0)
p := NumPut(0x4c182444894c1024, p+0)
p := NumPut(0x28ec834820244c89, p+0)
p := NumPut( 0xb9493024448d4c, p+0) - 1
lParamPtr := p, p += 8
p := NumPut(0xba, p+0, "char") ; mov edx, nmsg
p := NumPut(sMsg, p+0, "int")
p := NumPut(0xb9, p+0, "char") ; mov ecx, hwnd
p := NumPut(sHwnd, p+0, "int")
p := NumPut(0xb848, p+0, "short") ; mov rax, SendMessageW
p := NumPut(sSendMessageW, p+0)
/*
ff d0 ; call rax
48 83 c4 28 ; add rsp, 40
c3 ; ret
*/
p := NumPut(0x00c328c48348d0ff, p+0)
}
else ;(A_PtrSize = 4)
{
p := NumPut(0x68, p+0, "char") ; push ... (lParam data)
lParamPtr := p, p += 4
p := NumPut(0x0824448d, p+0, "int") ; lea eax, [esp+8]
p := NumPut(0x50, p+0, "char") ; push eax
p := NumPut(0x68, p+0, "char") ; push nmsg
p := NumPut(sMsg, p+0, "int")
p := NumPut(0x68, p+0, "char") ; push hwnd
p := NumPut(sHwnd, p+0, "int")
p := NumPut(0xb8, p+0, "char") ; mov eax, &SendMessageW
p := NumPut(sSendMessageW, p+0, "int")
p := NumPut(0xd0ff, p+0, "short") ; call eax
p := NumPut(0xc2, p+0, "char") ; ret argsize
p := NumPut((InStr(Options, "C") ? 0 : ParamCount*4), p+0, "short")
}
NumPut(p, lParamPtr+0) ; To be passed as lParam.
p := NumPut(&fn, p+0)
p := NumPut(ParamCount, p+0, "int")
return pcb
}
RegisterSyncCallback_Msg(wParam, lParam) {
if (A_Gui != "RegisterSyncCallback")
return
fn := Object(NumGet(lParam + 0))
paramCount := NumGet(lParam + A_PtrSize, "int")
params := []
Loop % paramCount
params.Push(NumGet(wParam + A_PtrSize * (A_Index-1)))
return %fn%(params*)
}
; ----------------------------------------------------------------------------------------------------------------------
; Name .........: TermWait library
; Description ..: Implement the RegisterWaitForSingleObject Windows API.
; AHK Version ..: AHK_L 1.1.13.01 x32/64 Unicode
; Author .......: Cyruz (http://ciroprincipe.info) & SKAN (http://goo.gl/EpCq0Z)
; License ......: WTFPL - http://www.wtfpl.net/txt/copying/
; Changelog ....: Sep. 15, 2012 - v0.1 - First revision.
; ..............: Jan. 02, 2014 - v0.2 - AHK_L Unicode and x64 version.
; ----------------------------------------------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TermWait_WaitForProcTerm
; Description ..: This function initializes a global structure and start an asynchrounous thread to wait for program
; ..............: termination. The global structure is used to pass arbitrary data at offset 24/36. Offsets are:
; ..............: < +0 = hWnd | +4/+8 = nMsgId | +8/+12 = nPid | +12/+16 = hProc | +16/+24 = hWait | +20/+32 bGetExitCode | +24/+36 = sDataIn >
; Parameters ...: hWnd - Handle of the window that will receive the notification.
; ..............: nMsgId - Generic message ID (msg).
; ..............: nPid - PID of the process that needs to be waited for.
; ..............: sDataIn - Arbitrary data (use this to pass any data in string form).
; ..............: bGetExitCode - allow your notification function to get the exit code of the process (if nPidIsHandle is true, however, then the handle must have the required rights)
; ..............: nPidIsHandle - treats the nPid parameter as if it is a valid process handle instead (WARNING: TermWait_StopWaiting will always close the handle. You should duplicate it yourself beforehand if needed.)
; Return .......: On success, address of global allocated structure. 0 on failure. If you passed a handle, it will not be closed on failure.
; ----------------------------------------------------------------------------------------------------------------------
TermWait_WaitForProcTerm(hWnd, nMsgId, nPid, ByRef sDataIn:="", bGetExitCode := False, nPidIsHandle := False) {
static addrCallback := 0
if (!addrCallback)
{
fnRegisterSyncCallback := Func("RegisterSyncCallback")
if (fnRegisterSyncCallback)
addrCallback := fnRegisterSyncCallback.Call("__TermWait_TermNotifier")
else
addrCallback := RegisterCallback("__TermWait_TermNotifier")
}
if (nPid < 1)
return 0
if (!nPidIsHandle) {
procOpenFlags := 0x00100000 ; SYNCHRONIZE
if (bGetExitCode) {
if A_OSVersion in WIN_2003,WIN_XP,WIN_2000
procOpenFlags |= 0x0400 ; PROCESS_QUERY_INFORMATION
else
procOpenFlags |= 0x1000 ; PROCESS_QUERY_LIMITED_INFORMATION
}
hProc := DllCall("OpenProcess", "UInt", procOpenFlags, "Int", False, "UInt", nPid, "Ptr")
if (!hProc)
return 0
} else {
hProc := nPid
nPid := DllCall("GetProcessId", "Ptr", hProc, "UInt")
}
szDataIn := VarSetCapacity(sDataIn)
,pGlobal := DllCall("GlobalAlloc", "UInt", 0x0040, "UInt", (A_PtrSize == 8 ? 36 : 24) + szDataIn, "Ptr")
NumPut(hWnd, pGlobal+0,, "Ptr")
,NumPut(nMsgId, pGlobal+0, A_PtrSize, "UInt")
,NumPut(nPid, pGlobal+0, A_PtrSize == 8 ? 12 : 8, "UInt")
,NumPut(hProc, pGlobal+0, A_PtrSize == 8 ? 16 : 12, "Ptr")
,NumPut(bGetExitCode, pGlobal+0, A_PtrSize == 8 ? 32 : 20, "Int")
DllCall("RtlMoveMemory", "Ptr", pGlobal+(A_PtrSize == 8 ? 36 : 24), "Ptr", &sDataIn, "Ptr", szDataIn)
if (!DllCall("RegisterWaitForSingleObject", "Ptr", pGlobal+(A_PtrSize == 8 ? 24 : 16), "Ptr", hProc, "Ptr", addrCallback
, "Ptr", pGlobal, "UInt", 0xFFFFFFFF, "UInt", 0x00000004 | 0x00000008)) { ; INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE
TermWait_StopWaiting(pGlobal, True)
return 0
}
return pGlobal
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TermWait_StopWaiting
; Description ..: This function cleans all handles and frees global allocated memory.
; Parameters ...: pGlobal - Global structure address.
; ----------------------------------------------------------------------------------------------------------------------
TermWait_StopWaiting(pGlobal, justFreepGlobal := False) {
if (pGlobal) {
if (!justFreepGlobal) {
DllCall("UnregisterWait", "Ptr", NumGet(pGlobal+0, A_PtrSize == 8 ? 24 : 16, "Ptr"))
,DllCall("CloseHandle", "Ptr", NumGet(pGlobal+0, A_PtrSize == 8 ? 16 : 12))
}
DllCall("GlobalFree", "Ptr", pGlobal, "Ptr")
}
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: __TermWait_TermNotifier
; Description ..: This callback is called when a monitored process signal its closure. It gets executed on a different
; ..............: thread because of the RegisterWaitForSingleObject, so it could interferee with the normal AutoHotkey
; ..............: behaviour (eg. it's not bug free).
; Parameters ...: pGlobal - Global structure.
; ----------------------------------------------------------------------------------------------------------------------
__TermWait_TermNotifier(pGlobal) {
Critical 1000
dwExitCode := 0
if (NumGet(pGlobal+0, A_PtrSize == 8 ? 32 : 20, "Int"))
DllCall("GetExitCodeProcess", "Ptr", NumGet(pGlobal+0, A_PtrSize + 8, "Ptr"), "UInt*", dwExitCode)
DllCall("SendNotifyMessage",Ptr,NumGet(pGlobal+0,"Ptr"),UInt,NumGet((A_PtrSize==4)?pGlobal+4:pGlobal+8,"UInt"),UInt,dwExitCode,Ptr,pGlobal)
Critical Off
}
; By cocobelgica
Jxon_Load(ByRef src, args*) {
static q := Chr(34)
key := "", is_key := false
stack := [ tree := [] ]
is_arr := { (tree): 1 }
next := q . "{[01234567890-tfn"
pos := 0
while ( (ch := SubStr(src, ++pos, 1)) != "" )
{
if InStr(" `t`n`r", ch)
continue
if !InStr(next, ch, true)
{
ln := ObjLength(StrSplit(SubStr(src, 1, pos), "`n"))
col := pos - InStr(src, "`n",, -(StrLen(src)-pos+1))
msg := Format("{}: line {} col {} (char {})"
, (next == "") ? ["Extra data", ch := SubStr(src, pos)][1]
: (next == "'") ? "Unterminated string starting at"
: (next == "\") ? "Invalid \escape"
: (next == ":") ? "Expecting ':' delimiter"
: (next == q) ? "Expecting object key enclosed in double quotes"
: (next == q . "}") ? "Expecting object key enclosed in double quotes or object closing '}'"
: (next == ",}") ? "Expecting ',' delimiter or object closing '}'"
: (next == ",]") ? "Expecting ',' delimiter or array closing ']'"
: [ "Expecting JSON value(string, number, [true, false, null], object or array)"
, ch := SubStr(src, pos, (SubStr(src, pos)~="[\]\},\s]|$")-1) ][1]
, ln, col, pos)
throw Exception(msg, -1, ch)
}
is_array := is_arr[obj := stack[1]]
if i := InStr("{[", ch)
{
val := (proto := args[i]) ? new proto : {}
is_array? ObjPush(obj, val) : obj[key] := val
ObjInsertAt(stack, 1, val)
is_arr[val] := !(is_key := ch == "{")
next := q . (is_key ? "}" : "{[]0123456789-tfn")
}
else if InStr("}]", ch)
{
ObjRemoveAt(stack, 1)
next := stack[1]==tree ? "" : is_arr[stack[1]] ? ",]" : ",}"
}
else if InStr(",:", ch)
{
is_key := (!is_array && ch == ",")
next := is_key ? q : q . "{[0123456789-tfn"
}
else ; string | number | true | false | null
{
if (ch == q) ; string
{
i := pos
while i := InStr(src, q,, i+1)
{
val := StrReplace(SubStr(src, pos+1, i-pos-1), "\\", "\u005C")
static end := A_AhkVersion<"2" ? 0 : -1
if (SubStr(val, end) != "\")
break
}
if !i ? (pos--, next := "'") : 0
continue
pos := i ; update pos
val := StrReplace(val, "\/", "/")
, val := StrReplace(val, "\" . q, q)
, val := StrReplace(val, "\b", "`b")
, val := StrReplace(val, "\f", "`f")
, val := StrReplace(val, "\n", "`n")
, val := StrReplace(val, "\r", "`r")
, val := StrReplace(val, "\t", "`t")
i := 0
while i := InStr(val, "\",, i+1)
{
if (SubStr(val, i+1, 1) != "u") ? (pos -= StrLen(SubStr(val, i)), next := "\") : 0
continue 2
; \uXXXX - JSON unicode escape sequence
xxxx := Abs("0x" . SubStr(val, i+2, 4))
if (A_IsUnicode || xxxx < 0x100)
val := SubStr(val, 1, i-1) . Chr(xxxx) . SubStr(val, i+6)
}
if is_key
{
key := val, next := ":"
continue
}
}
else ; number | true | false | null
{
val := SubStr(src, pos, i := RegExMatch(src, "[\]\},\s]|$",, pos)-pos)
; For numerical values, numerify integers and keep floats as is.
; I'm not yet sure if I should numerify floats in v2.0-a ...
static number := "number", integer := "integer"
if val is %number%
{
if val is %integer%
val += 0
}
; in v1.1, true,false,A_PtrSize,A_IsUnicode,A_Index,A_EventInfo,
; SOMETIMES return strings due to certain optimizations. Since it
; is just 'SOMETIMES', numerify to be consistent w/ v2.0-a
else if (val == "true" || val == "false")
val := %val% + 0
; AHK_H has built-in null, can't do 'val := %value%' where value == "null"
; as it would raise an exception in AHK_H(overriding built-in var)
else if (val == "null")
val := ""
; any other values are invalid, continue to trigger error
else if (pos--, next := "#")
continue
pos += i-1
}
is_array? ObjPush(obj, val) : obj[key] := val
next := obj==tree ? "" : is_array ? ",]" : ",}"
}
}
return tree[1]
}
CtrlHandler(fdwCtrlType) {
if (fdwCtrlType == 0 || fdwCtrlType == 2) {
Critical 1000
ExitFunc()
DllCall("TerminateProcess", "Ptr", GetCurrentProcess(), "UInt", 0)
}
return 0
}
_PROCESS_INFORMATION(ByRef pi) {
static piCb := A_PtrSize == 8 ? 24 : 16
if (IsByRef(pi))
VarSetCapacity(pi, piCb, 0)
}
_PROCESS_INFORMATION_hProcess(ByRef pi) {
return NumGet(pi,, "Ptr")
}
_PROCESS_INFORMATION_hThread(ByRef pi) {
return NumGet(pi, A_PtrSize, "Ptr")
}
cbStartupInfoEx := A_PtrSize == 8 ? 112 : 72
_STARTUPINFOEX(ByRef si) {
global cbStartupInfoEx
if (IsByRef(si))
VarSetCapacity(si, cbStartupInfoEx, 0), NumPut(cbStartupInfoEx, si,, "UInt")
}
CloseHandle(hObject) {
static INVALID_HANDLE_VALUE := -1
return (hObject && hObject != INVALID_HANDLE_VALUE) ? DllCall("kernel32.dll\CloseHandle", "Ptr", hObject) : False
}
GetCurrentProcess() {
static hProc := DllCall("GetCurrentProcess", "Ptr") ; always -1
return hProc
}
GetParentProcessID() {
; Undocumented but far easier than CreateToolhelp32Snapshot
VarSetCapacity(PROCESS_BASIC_INFORMATION, pbiSz := A_PtrSize == 8 ? 48 : 24)
if (DllCall("ntdll.dll\NtQueryInformationProcess", "Ptr", GetCurrentProcess(), "UInt", 0, "Ptr", &PROCESS_BASIC_INFORMATION, "UInt", pbiSz, "Ptr", 0) >= 0)
return NumGet(PROCESS_BASIC_INFORMATION, pbiSz - A_PtrSize, "UInt")
return 0
}
GetOverseerVersion() {
FileRead, package, package.json
package := Jxon_Load(package)
return package["version"]
}
DeleteFolder(target) {
RunWait, byenow -y -n -x "%target%",, Hide UseErrorLevel
RunWait, byenow -y -x "%target%",, Hide UseErrorLevel
FileRemoveDir, % target, 1
}
; VersionCompare function by boiler at ahkscript.org
; Compares versions where simple string comparison can fail, such as 9.1.3.2 and 10.1.3.5
; Both version numbers are in format n1[.n2.n3.n4...] where each n can be any number of digits.
; Fills in zeros for missing sections for purposes of comparison (e.g., comparing 9 to 8.1).
; Not limited to 4 sections. Can handle 5.3.2.1.6.19.6 (and so on) if needed.
; Returns 1 if version1 is more recent, 2 if version 2 is more recent, 0 if they are the same.
VersionCompare(version1, version2) {
StringSplit, verA, version1, .
StringSplit, verB, version2, .
Loop, % (verA0> verB0 ? verA0 : verB0)
{
if (verA0 < A_Index)
verA%A_Index% := "0"
if (verB0 < A_Index)
verB%A_Index% := "0"
if (verA%A_Index% > verB%A_Index%)
return 1
if (verB%A_Index% > verA%A_Index%)
return 2
}
return 0
}
SearchPathW(FileName, Extension)
{
static buf
if (!VarSetCapacity(buf))
VarSetCapacity(buf, (260 + 1) * 2)
written := DllCall("kernel32.dll\SearchPathW", "Ptr", 0, "WStr", FileName, "WStr", Extension, "UInt", 260, "Ptr", &buf, "Ptr", 0)
if (written == 0 || written > 260)
return 0
return StrGet(&buf, written, "UTF-16")
}
Try Menu, Tray, Icon, %A_ScriptDir%\public\favicon.ico
hProcess := 0
ExitFunc()
{
global hProcess
OnExit("ExitFunc", 0)
if (hProcess) {
shouldKill := True
dwProcessId := DllCall("kernel32.dll\GetProcessId", "Ptr", hProcess)
DllCall("SetConsoleCtrlHandler", "Ptr", 0, "Int", True)
alreadyAttached := !!DllCall("GetConsoleWindow", "Ptr")
if (alreadyAttached || DllCall("AttachConsole", "UInt", dwProcessId)) {
generated := DllCall("GenerateConsoleCtrlEvent", "UInt", 0, "UInt", 0)
if (!alreadyAttached)
DllCall("FreeConsole")
if (generated)
shouldKill := DllCall("WaitForSingleObject", "Ptr", hProcess, "UInt", 3000, "UInt") != 0
}
DllCall("SetConsoleCtrlHandler", "Ptr", 0, "Int", False)
if (shouldKill)
DllCall("TerminateProcess", "Ptr", hProcess, "UInt", 0)
}
}
MSGID := 0x8500 ; msg
AHK_TERMNOTIFY(wParam, lParam) {
global hProcess
OnExit("ExitFunc", 0)
TermWait_StopWaiting(lParam)
;CloseHandle(hProcess)
hProcess := 0
ExitApp
}
EnvSet, CLINK_NOAUTORUN, 1
EnvSet, NEXT_TELEMETRY_DISABLED, 1
EnvSet, CYPRESS_INSTALL_BINARY, 0
EnvSet, FORCE_IPV4_FIRST, true
DllCall("GetProcessAffinityMask", "Ptr", GetCurrentProcess(), "UPtr*", ProcessAffinityMask, "UPtr*", SystemAffinityMask)
,VarSetCapacity(SYSTEM_INFO, 24 + A_PtrSize*3)
,DllCall("GetSystemInfo", "Ptr", &SYSTEM_INFO)
,coresNumber := NumGet(SYSTEM_INFO, 8 + A_PtrSize*3, "UInt")
,lastTwoCoresAffinity := (1 << (coresNumber - 2)) | (1 << (coresNumber - 1))
,DllCall("SetProcessAffinityMask", "Ptr", GetCurrentProcess(), "UPtr", lastTwoCoresAffinity)
,DllCall("SetPriorityClass", "Ptr", GetCurrentProcess(), "UInt", PROCESS_MODE_BACKGROUND_BEGIN := 0x00100000)
if (ComObjCreate("{DCB00C01-570F-4A9B-8D69-199FDBA5723B}").GetConnectivity() & 0x40) != 0 { ; NLM_CONNECTIVITY_IPV4_INTERNET
if (!FileExist("C:\Users\" . A_UserName . "\scoop\persist\nodejs-lts\bin\node_modules\win-node-env\")) {
npm := SearchPathW("npm", ".cmd")
RunWait, %npm% install -g win-node-env,, Hide
}
RunWait, git.exe stash drop,, Hide
RunWait, git.exe checkout origin/main .npmrc,, Hide
RunWait, git.exe checkout origin/main package.json,, Hide
RunWait, git.exe checkout origin/main pnpm-lock.yaml,, Hide
previousVersion := GetOverseerVersion()
RunWait, git.exe pull,, Hide
if (ErrorLevel == 0) {
newVersion := GetOverseerVersion()
if (previousVersion && newVersion && VersionCompare(previousVersion, newVersion) == 2) {
DeleteFolder(A_ScriptDir . "\dist")
,DeleteFolder(A_ScriptDir . "\node_modules")
,DeleteFolder(A_ScriptDir . "\.next")
}
if (!FileExist("dist")) {
inst_cmd := "C:\Users\" . A_UserName . "\scoop\apps\pnpm\current\pnpm.exe" ;SearchPathW("pnpm", ".exe")
RunWait, %inst_cmd% config --location project set engine-strict false,, Hide ; supported by both `pnpm` and `npm`
RunWait, %inst_cmd% install --frozen-lockfile --prefer-offline --fetch-timeout 1000000,, Hide
if (ErrorLevel != 0)
ExitApp 1
RunWait, %inst_cmd% build,, Hide
if (ErrorLevel != 0)
ExitApp 1
; commenting the following lines (and DeleteFolder calls above for node_modules and .next) might make for faster rebuilds; however, to save space instead run https://github.com/Freaky/Compactor here
RunWait, %inst_cmd% prune --prod --ignore-scripts,, Hide
RunWait, %inst_cmd% store prune --force,, Hide
RunWait, %inst_cmd% cache delete,, Hide
DeleteFolder(A_ScriptDir . "\.next\cache")
EnvGet, LocalAppData, LOCALAPPDATA
DeleteFolder(LocalAppData . "\pnpm-cache")
}
} else {
newVersion := GetOverseerVersion()
if (!newVersion || newVersion != previousVersion)
ExitApp, 1
}
}
DllCall("SetPriorityClass", "Ptr", GetCurrentProcess(), "UInt", PROCESS_MODE_BACKGROUND_END := 0x00200000)
,DllCall("SetProcessAffinityMask", "Ptr", GetCurrentProcess(), "UPtr", ProcessAffinityMask)
_PROCESS_INFORMATION(pi)
,_STARTUPINFOEX(si)
,dwCreationFlags := CREATE_NO_WINDOW := 0x08000000
/*
if ((parentPid := GetParentProcessID())) {
if ((hParentProcess := DllCall("OpenProcess", "UInt", PROCESS_CREATE_PROCESS := 0x0080, "Int", False, "UInt", parentPid, "Ptr"))) {
DllCall("InitializeProcThreadAttributeList", "Ptr", 0, "UInt", 1, "UInt", 0, "Ptr*", size)
if (size) {
VarSetCapacity(AttributeList, size + A_PtrSize)
if (DllCall("InitializeProcThreadAttributeList", "Ptr", &AttributeList, "UInt", 1, "UInt", 0, "Ptr*", size)) {
NumPut(hParentProcess, AttributeList, size, "Ptr")
if (DllCall("UpdateProcThreadAttribute", "Ptr", &AttributeList, "UInt", 0, "UPtr", PROC_THREAD_ATTRIBUTE_PARENT_PROCESS := 0x00020000, "Ptr", &AttributeList+size, "Ptr", A_PtrSize, "Ptr", 0, "Ptr", 0)) {
NumPut(&AttributeList, si, cbStartupInfoEx - A_PtrSize, "Ptr")
,dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT := 0x00080000
}
} else {
VarSetCapacity(AttributeList, 0)
}
}
}
}
*/
EnvSet, HOST, 0.0.0.0
EnvSet, PORT, 5055
; important to keep here, after yarn
EnvSet, NODE_ENV, production
if (!(exe := SearchPathW("node", ".exe")))
ExitApp 1
cmd := """" . exe . """" . " dist\index.js"
if (DllCall("CreateProcessW", "WStr", exe, "WStr", cmd, "Ptr", 0, "Ptr", 0, "Int", False, "UInt", dwCreationFlags, "Ptr", 0, "Ptr", 0, "Ptr", &si, "Ptr", &pi)) {
hProcess := _PROCESS_INFORMATION_hProcess(pi)
,DllCall("SetProcessAffinityMask", "Ptr", hProcess, "UPtr", lastTwoCoresAffinity)
,DllCall("SetPriorityClass", "Ptr", hProcess, "UInt", BELOW_NORMAL_PRIORITY_CLASS := 0x00004000)
,DllCall("ntdll.dll\NtSetInformationProcess", "Ptr", hProcess, "UInt", ProcessIoPriority := 33, "UInt*", 1, "UInt", 4)
CloseHandle(_PROCESS_INFORMATION_hThread(pi))
;,CloseHandle(hProcess)
OnExit("ExitFunc")
OnMessage(MSGID, "AHK_TERMNOTIFY")
TermWait_WaitForProcTerm(A_ScriptHwnd, MSGID, hProcess,,, True)
if (DllCall("GetConsoleWindow", "Ptr"))
DllCall("SetConsoleCtrlHandler", "Ptr", RegisterCallback("CtrlHandler", "Fast"), "Int", True)
if (VarSetCapacity(AttributeList))
DllCall("DeleteProcThreadAttributeList", "Ptr", &AttributeList)
CloseHandle(hParentProcess)
} else {
ExitApp, 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment