<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Хоткей с экрана блокировки Windows]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=14290</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=14290&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Хоткей с экрана блокировки Windows».]]></description>
		<lastBuildDate>Mon, 11 May 2020 17:08:56 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=139452#p139452</link>
			<description><![CDATA[<p><strong>EV</strong>, прекращайте нарушать правила:<br /></p><div class="quotebox"><blockquote><p>3.11. Руководствуйтесь правилом: один вопрос - одна тема, не загромождайте существующие ветки посторонними вопросами и информацией.</p></blockquote></div><p><a href="http://forum.script-coding.com/rules.html">http://forum.script-coding.com/rules.html</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 11 May 2020 17:08:56 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=139452#p139452</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=139451#p139451</link>
			<description><![CDATA[<p><strong>Malcev</strong><br />Решения нет. Прекращайте загадочно отвечать</p>]]></description>
			<author><![CDATA[null@example.com (EV)]]></author>
			<pubDate>Mon, 11 May 2020 17:02:38 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=139451#p139451</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=139449#p139449</link>
			<description><![CDATA[<p>А это уже другой вопрос, к данной теме отношения не имеющий.</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 11 May 2020 16:54:46 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=139449#p139449</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=139448#p139448</link>
			<description><![CDATA[<div class="codebox"><pre><code>Run, %comspec% /c psexec -i \\192.168.1.35 -u Home -p foresters cmd /c start &quot;&quot; &quot;C:\Users\Home\Documents\Script\SynchronizesTime.exe&quot;,, Hide</code></pre></div><p>Как можно на удаленном запустить .exe?</p>]]></description>
			<author><![CDATA[null@example.com (EV)]]></author>
			<pubDate>Mon, 11 May 2020 16:49:09 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=139448#p139448</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=139447#p139447</link>
			<description><![CDATA[<p>Благодаря стараниям <strong>qwerty12</strong> такое можно провернуть и без PsExec.exe.<br />При нажатии f11 выскочит msgbox:<br /></p><div class="codebox"><pre><code>#NoEnv	; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn	; Enable warnings to assist with detecting common errors.
SendMode Input	; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%	 ; Ensures a consistent starting directory.
#SingleInstance Force
#KeyHistory 0
ListLines, Off
SetBatchLines, -1
#NoTrayIcon
#UseHook Off
DetectHiddenWindows On
CoordMode, Mouse, Screen

winlogonSessionIDs := []

if (!A_IsUnicode)
	ExitApp 1

if (LogonDesktop_IsScriptProcessSYSTEM()) { 
	if (!LogonDesktop_WaitForTermSrvInit()) ; Probably redundant since Task Scheduler starts this script so late, and probably checks itself...
		ExitApp 1

	LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), TOKEN_QUERY := 0x0008, hToken)
	if (!LogonDesktop_GetTokenSessionId(hToken, scriptSessionId))
		ExitApp 1
	LogonDesktop_CloseHandle(hToken)
	if (!LogonDesktop_GetThreadDesktopName(desktopName))
		ExitApp 1

	if (scriptSessionId == 0) {
		if (!(wtsHandle := LogonDesktop_LoadWtsApi()))
		  ExitApp 1

		EnumerateSessionsAndLaunchWinlogonClient()

		if (DllCall(&quot;wtsapi32.dll\WTSRegisterSessionNotification&quot;, &quot;Ptr&quot;, A_ScriptHwnd, &quot;UInt&quot;, 1))
			OnMessage(WM_WTSSESSION_CHANGE := 0x2B1, &quot;WM_WTSSESSION_CHANGE&quot;)
		
		OnExit(&quot;AtExit&quot;)
	} else {
		if (desktopName == &quot;Winlogon&quot;) {
			Hotkey, f11, sendPassword, UseErrorLevel On
		}
	}
} else {
	if (A_IsAdmin) {
		LogonDesktop_AddTask(True, True)
	} else {
		Run *RunAs &quot;%A_AhkPath%&quot; &quot;%A_ScriptFullPath%&quot;,, UseErrorLevel
	}
	ExitApp
}

sendPassword() {  
   msgbox
}

EnumerateSessionsAndLaunchWinlogonClient()
{
	global winlogonSessionIDs

	if (DllCall(&quot;wtsapi32\WTSEnumerateSessionsExW&quot;, &quot;Ptr&quot;, 0, &quot;UInt*&quot;, 1, &quot;UInt&quot;, 0, &quot;Ptr*&quot;, pSessionInfo, &quot;UInt*&quot;, wtsSessionCount)) {
		cbWTS_SESSION_INFO_1 := A_PtrSize == 8 ? 56 : 32
		Loop % wtsSessionCount {
			currSessOffset := cbWTS_SESSION_INFO_1 * (A_Index - 1)
			;if (StrGet(NumGet(pSessionInfo+0, currSessOffset+(A_PtrSize == 8 ? 32 : 20), &quot;Ptr&quot;),, &quot;UTF-16&quot;)) ; Poor person&#039;s WTSActive check
			if ((sessionId := NumGet(pSessionInfo+0, currSessOffset+8, &quot;UInt&quot;))) {
				if (DllCall(&quot;wtsapi32\WTSQuerySessionInformationW&quot;, &quot;Ptr&quot;, 0, &quot;UInt&quot;, sessionId, &quot;UInt&quot;, WTSConnectState := 8, &quot;Ptr*&quot;, pBuffer, &quot;Ptr*&quot;, BytesReturned)) {
					if (BytesReturned == 4) {
						state := NumGet(pBuffer+0,, &quot;UInt&quot;)
						if (state == 0 || state == 1) {
							foundSessionId := False
							for _, s in winlogonSessionIDs {
							  if (s == sessionId) {
								foundSessionId := True
								break
							   }
							}
							if (!foundSessionId) {
								if (LogonDesktop_LaunchOnWinlogonDesktop(DllCall(&quot;GetCommandLineW&quot;, &quot;WStr&quot;) . &quot; /force&quot;, sessionId))
									winlogonSessionIDs.Push(sessionId)
							}
						}
					}
					DllCall(&quot;wtsapi32\WTSFreeMemory&quot;, &quot;Ptr&quot;, pBuffer)
				}
			}
		}
		DllCall(&quot;wtsapi32\WTSFreeMemoryExW&quot;, &quot;UInt&quot;, 2, &quot;Ptr&quot;, pSessionInfo, &quot;UInt&quot;, wtsSessionCount)
	}
}

WM_WTSSESSION_CHANGE(wParam, lParam)
{
	Critical
	global winlogonSessionIDs, scriptSessionId
	if (scriptSessionId == 0) {
		if (wParam == 6) {
			winlogonSessionIDs.Delete(lParam)
		}
		else if (wParam == 1) {
			SetTimer, EnumerateSessionsAndLaunchWinlogonClient, -1000
		}
	}
	Critical Off
}

AtExit()
{
	global WM_WTSSESSION_CHANGE, wtsHandle

	OnExit(A_ThisFunc, 0)
	if (wtsHandle)
		OnMessage(WM_WTSSESSION_CHANGE, &quot;&quot;), DllCall(&quot;wtsapi32.dll\WTSUnRegisterSessionNotification&quot;, &quot;Ptr&quot;, A_ScriptHwnd), LogonDesktop_UnloadWtsApi(wtsHandle), wtsHandle := 0
	return 0
}



; LogonDesktop - run scripts on the Winlogon desktop
; 26/02/17 - qwerty12

; Modified version of RunAsTask() by SKAN: https://autohotkey.com/boards/viewtopic.php?t=4334
LogonDesktop_AddTask(runNow, runOnStartup)
{
	local TaskName, XML, TaskSchd, TaskRoot, RunAsTask
	local TASK_CREATE := 0x2, TASK_LOGON_SERVICE_ACCOUNT := 5, scriptDir := A_ScriptDir

	try 
		TaskSchd := ComObjCreate(&quot;Schedule.Service&quot;), TaskSchd.Connect(), TaskRoot := TaskSchd.GetFolder(&quot;\&quot;)
	catch
		return &quot;&quot;

	TaskName := &quot;[AHKLogonDesktop]&quot; . A_ScriptName . &quot; - &quot; . DllCall(&quot;NTDLL\RtlComputeCrc32&quot;, &quot;Int&quot;, 0, &quot;Ptr&quot;, &amp;scriptDir, &quot;UInt&quot;, StrLen(scriptDir) * 2, &quot;UInt&quot;)

	try 
		RunAsTask := TaskRoot.GetTask(TaskName)
	catch
		RunAsTask := &quot;&quot;

	if (!RunAsTask) {
		trigger := runOnStartup ? &quot;&lt;Triggers&gt;&lt;BootTrigger&gt;&lt;Enabled&gt;true&lt;/Enabled&gt;&lt;/BootTrigger&gt;&lt;/Triggers&gt;&quot; : &quot;&lt;Triggers /&gt;&quot;

		XML := &quot;
			( LTrim Join
			&lt;?xml version=&quot;&quot;1.0&quot;&quot; ?&gt;&lt;Task xmlns=&quot;&quot;http://schemas.microsoft.com/windows/2004/02/mit/task&quot;&quot;&gt;
			&lt;RegistrationInfo /&gt;&quot; . trigger . &quot;&lt;Principals&gt;&lt;Principal id=&quot;&quot;Author&quot;&quot;&gt;&lt;UserId&gt;S-1-5-18&lt;/UserId&gt;&lt;RunLevel&gt;HighestAvailable&lt;/RunLevel&gt;
			&lt;/Principal&gt;&lt;/Principals&gt;&lt;Settings&gt;&lt;MultipleInstancesPolicy&gt;Parallel&lt;/MultipleInstancesPolicy&gt;
			&lt;DisallowStartIfOnBatteries&gt;false&lt;/DisallowStartIfOnBatteries&gt;&lt;StopIfGoingOnBatteries&gt;false&lt;/StopIfGoingOnBatteries&gt;
			&lt;AllowHardTerminate&gt;false&lt;/AllowHardTerminate&gt;&lt;StartWhenAvailable&gt;false&lt;/StartWhenAvailable&gt;&lt;RunOnlyIfNetworkAvailable&gt;false&lt;/RunOnlyIfNetworkAva
			ilable&gt;&lt;IdleSettings&gt;&lt;StopOnIdleEnd&gt;false&lt;/StopOnIdleEnd&gt;&lt;RestartOnIdle&gt;false&lt;/RestartOnIdle&gt;&lt;/IdleS
			ettings&gt;&lt;AllowStartOnDemand&gt;true&lt;/AllowStartOnDemand&gt;&lt;Enabled&gt;true&lt;/Enabled&gt;&lt;Hidden&gt;false&lt;/Hidden&gt;&lt;
			RunOnlyIfIdle&gt;false&lt;/RunOnlyIfIdle&gt;&lt;DisallowStartOnRemoteAppSession&gt;false&lt;/DisallowStartOnRemoteApp
			Session&gt;&lt;UseUnifiedSchedulingEngine&gt;false&lt;/UseUnifiedSchedulingEngine&gt;&lt;WakeToRun&gt;false&lt;/WakeToRun&gt;&lt;
			ExecutionTimeLimit&gt;PT0S&lt;/ExecutionTimeLimit&gt;&lt;Priority&gt;4&lt;/Priority&gt;&lt;/Settings&gt;&lt;Actions Context=&quot;&quot;Author&quot;&quot;&gt;&lt;Exec&gt;
			&lt;Command&gt;&quot; . &quot;&quot;&quot;&quot; . A_AhkPath . &quot;&quot;&quot;&quot; . &quot;&lt;/Command&gt;
			&lt;Arguments&gt;&quot; . (A_IsCompiled ? &quot;&quot; : &quot;&quot;&quot;&quot; . A_ScriptFullPath . &quot;&quot;&quot;&quot;) . &quot; /ErrorStdOut&quot; . &quot;&lt;/Arguments&gt;
			&lt;WorkingDirectory&gt;&quot; . scriptDir . &quot;&lt;/WorkingDirectory&gt;&lt;/Exec&gt;&lt;/Actions&gt;&lt;/Task&gt;
			)&quot;
		TaskRoot.RegisterTask(TaskName, XML, TASK_CREATE, &quot;&quot;, &quot;&quot;, TASK_LOGON_SERVICE_ACCOUNT)
	}

	if (!RunAsTask) {
		try 
			RunAsTask := TaskRoot.GetTask(TaskName)
		catch
			return &quot;&quot;
	}

	if (runNow)
		RunAsTask.Run(&quot;&quot;)

	return TaskName
}

LogonDesktop_LaunchOnWinlogonDesktop(cmdLine, sessionId, ignoreSentinel := False, InheritHandles := False)
{
	static tokenPerms := 0x0100 | 0x0008 | 0x0002 | 0x0001, neededPrivs := {&quot;SeTcbPrivilege&quot;: True, &quot;SeImpersonatePrivilege&quot;: True, &quot;SeAssignPrimaryTokenPrivilege&quot;: True, &quot;SeIncreaseQuotaPrivilege&quot;: True} ; TOKEN_ADJUST_SESSIONID | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY
	ret := False

	if (!ignoreSentinel) {
		EnvGet, _LOGON_DESKTOP_SENTINEL, _LOGON_DESKTOP_SENTINEL
		if (_LOGON_DESKTOP_SENTINEL == &quot;1&quot;)
			return ret
	}

	if (LogonDesktop_AdjustThisProcessPrivileges(neededPrivs, PreviousState)) {
		if (LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), tokenPerms, hToken)) {
			if (LogonDesktop_DuplicateTokenEx(hToken, 0x02000000, 0, 1, 1, hNewToken)) { ; MAXIMUM_ALLOWED, SecurityIdentification, TokenPrimary
				if (_SetTokenInformation(hNewToken, 12, sessionId, 4, &quot;UInt*&quot;)) { ; TokenSessionId
					EnvSet, _LOGON_DESKTOP_SENTINEL, 1
					ret := LogonDesktop_EasyCreateProcessUsingToken(hNewToken, cmdLine, &quot;WinSta0\Winlogon&quot;, False, InheritHandles)
					EnvSet, _LOGON_DESKTOP_SENTINEL, 0
				}
				LogonDesktop_CloseHandle(hNewToken)
			}
			LogonDesktop_CloseHandle(hToken)
		}
		LogonDesktop_AdjustThisProcessPrivileges(0, PreviousState)
	}

	return ret
}

_IsSystemSid(pSid) {
	return DllCall(&quot;advapi32\IsWellKnownSid&quot;, &quot;Ptr&quot;, pSid, &quot;UInt&quot;, 22) ; WinLocalSystemSid
}

LogonDesktop_IsScriptProcessSYSTEM()
{
	ret := hToken := 0

	if (LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), 0x0008, hToken)) { ; TOKEN_QUERY
		if (LogonDesktop_GetTokenUser(hToken, TOKEN_USER))
			ret := _IsSystemSid(NumGet(TOKEN_USER,, &quot;Ptr&quot;))
		LogonDesktop_CloseHandle(hToken)
	}

	return ret
}

LogonDesktop_AdjustTokenPrivileges(hToken, privNames, ByRef PreviousState := 0, ByRef notAllAssigned := 0) {
	static cbTOKEN_PRIVILEGES := 16, skipPrivCount := cbTOKEN_PRIVILEGES - 4
	static LookupPrivilegeValueW := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;LookupPrivilegeValueW&quot;, &quot;Ptr&quot;), AdjustTokenPrivileges := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;AdjustTokenPrivileges&quot;, &quot;Ptr&quot;)
	ret := False

	DllCall(&quot;SetLastError&quot;, &quot;UInt&quot;, 0)

	if (IsObject(privNames)) {
		if (!(privNamesOrPrevStateLen := privNames.SetCapacity(0)))
			return ret

		VarSetCapacity(TOKEN_PRIVILEGES, (sizeTp := 4 + (skipPrivCount * privNamesOrPrevStateLen)), 0)
		NumPut(privNamesOrPrevStateLen, TOKEN_PRIVILEGES,, &quot;UInt&quot;)
		for priv, enabled in privNames {
			luidOffset := 4 + (skipPrivCount * (A_Index - 1))
			if (DllCall(LookupPrivilegeValueW, &quot;Ptr&quot;, 0, &quot;WStr&quot;, priv, &quot;Ptr&quot;, &amp;TOKEN_PRIVILEGES+luidOffset))
				if (enabled)
					NumPut(0x00000002, TOKEN_PRIVILEGES, luidOffset+8, &quot;UInt&quot;)
		}
	} else {
		if (!privNames &amp;&amp; !IsByRef(PreviousState))
			return ret
	}

	if (hToken) {
		psBr := IsByRef(PreviousState)
		if (privNames) {
			if (psBr)
				VarSetCapacity(PreviousState, sizeTp, 0)
			ret := DllCall(AdjustTokenPrivileges, &quot;Ptr&quot;, hToken, &quot;Int&quot;, False, &quot;Ptr&quot;, &amp;TOKEN_PRIVILEGES, &quot;UInt&quot;, psBr ? 0 : sizeTp, &quot;Ptr&quot;, psBr ? &amp;PreviousState : 0, &quot;UInt*&quot;, ReturnLength)
			if (!ret &amp;&amp; psBr &amp;&amp; ReturnLength &amp;&amp; A_LastError == 122) { ; ERROR_INSUFFICIENT_BUFFER
				VarSetCapacity(PreviousState, ReturnLength)
				ret := DllCall(AdjustTokenPrivileges, &quot;Ptr&quot;, hToken, &quot;Int&quot;, False, &quot;Ptr&quot;, &amp;TOKEN_PRIVILEGES, &quot;UInt&quot;, ReturnLength, &quot;Ptr&quot;, &amp;PreviousState, &quot;UInt*&quot;, ReturnLength)
			}
		} else {
			if (psBr &amp;&amp; PreviousState)
				ret := DllCall(AdjustTokenPrivileges, &quot;Ptr&quot;, hToken, &quot;Int&quot;, False, &quot;Ptr&quot;, &amp;PreviousState, &quot;UInt&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0)
		}
	}

	if (ret)
		notAllAssigned := A_LastError == 1300 ; ERROR_NOT_ALL_ASSIGNED

	return ret
}

LogonDesktop_AdjustThisProcessPrivileges(privNames, ByRef PreviousState := 0, ByRef notAllAssigned := 0) {
	ret := False

	if (LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), 0x0028, hToken)) { ; TOKEN_ADJUST_PRIVILEGES := 0x0020 | TOKEN_QUERY := 0x0008
		ret := LogonDesktop_AdjustTokenPrivileges(hToken, privNames, PreviousState, notAllAssigned)
		LogonDesktop_CloseHandle(hToken)
	}

	return ret
}

LogonDesktop_EasyCreateProcessUsingToken(hToken, cmdLine, desktop, useTokenEnvBlock, InheritHandles := False, ShowWindow := -1) {
	ret := envModule := pEnv := 0

	if (!cmdLine)
		return ret

	if (useTokenEnvBlock) {
		if (!(envModule := _PrepareEnvironmentBlockCall()))
			return ret

		; http://stackoverflow.com/a/13733317
		if (!_CreateEnvironmentBlock(pEnv, hToken, False)) {
			_EndEnvironmentBlockCall(envModule)
			return ret
		}
	}

	_PROCESS_INFORMATION(pi)
	_STARTUPINFO(si, desktop ? &amp;desktop : 0, ShowWindow)
	dwCreationFlags := 0x01000000 | (pEnv ? 0x00000400 : 0) ; CREATE_BREAKAWAY_FROM_JOB | CREATE_UNICODE_ENVIRONMENT

	if (!(ret := _CreateProcessAsUserW(hToken, 0, &amp;cmdLine, 0, 0, InheritHandles, dwCreationFlags, pEnv, 0, &amp;si, &amp;pi)))
		ret := _CreateProcessWithTokenW(hToken, 0x00000001, 0, &amp;cmdLine, dwCreationFlags, pEnv, 0, &amp;si, &amp;pi) ; LOGON_WITH_PROFILE

	if (ret) {
		LogonDesktop_CloseHandle(_PROCESS_INFORMATION_hProcess(pi))
		LogonDesktop_CloseHandle(_PROCESS_INFORMATION_hThread(pi))
	}

	if (useTokenEnvBlock) {
		if (pEnv)
			_DestroyEnvironmentBlock(pEnv)

		if (envModule)
			_EndEnvironmentBlockCall(envModule)
	}

	return ret
}

LogonDesktop_WaitForTermSrvInit()
{
	ret := False
	if ((TermSrvReadyEvent := DllCall(&quot;OpenEventW&quot;, &quot;UInt&quot;, 0x00100000, &quot;Int&quot;, False, &quot;WStr&quot;, &quot;Global\TermSrvReadyEvent&quot;, &quot;Ptr&quot;))) { ; SYNCHRONIZE
		ret := DllCall(&quot;WaitForSingleObject&quot;, &quot;Ptr&quot;, TermSrvReadyEvent, &quot;UInt&quot;, -1) == 0
		LogonDesktop_CloseHandle(TermSrvReadyEvent)
	}
	return ret
}

/*
; NOTE: I don&#039;t recommend using LogonDesktop_WaitForDesktopSwitchSync(). With AutoHotkey, it&#039;s nicer to use the accessibility framework to be be notified asynchronously:
OnDesktopSwitch(hWinEventHook, event, hWnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
	MsgBox Desktop switched
}
DllCall(&quot;SetWinEventHook&quot;, &quot;UInt&quot;, (EVENT_SYSTEM_DESKTOPSWITCH := 0x0020), &quot;UInt&quot;, EVENT_SYSTEM_DESKTOPSWITCH, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, (lpfnWinEventProc := RegisterCallback(&quot;OnDesktopSwitch&quot;, &quot;&quot;)), &quot;UInt&quot;, 0, &quot;UInt&quot;, 0, &quot;UInt&quot;, WINEVENT_OUTOFCONTEXT := 0x0000 | WINEVENT_SKIPOWNPROCESS := 0x0002)
(You should include a corresponding call to UnhookWinEvent, and GlobalFree for the callback function pointer at exit.)
; If you really don&#039;t want to use the accessibility framework, you might be able to use RegisterWaitForSingleObject in lieu of MsgWaitForMultipleObjectsEx,
; in combination with Lexikos&#039; RegisterSyncCallback library to be notified asynchronously, in the style of SetWinEventHook.
*/
; The following blocks the current thread unless a message is recieved, waiting fails or WinSta0_DesktopSwitch is signalled
LogonDesktop_WaitForDesktopSwitchSync()
{
	static SYNCHRONIZE := 0x00100000, evt := DllCall(&quot;OpenEventW&quot;, &quot;UInt&quot;, SYNCHRONIZE, &quot;Int&quot;, False, &quot;WStr&quot;, &quot;WinSta0_DesktopSwitch&quot;, &quot;Ptr&quot;), MsgWaitForMultipleObjectsEx := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;user32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;MsgWaitForMultipleObjectsEx&quot;, &quot;Ptr&quot;)

	desktopSwitched := False
	Loop {
		r := DllCall(MsgWaitForMultipleObjectsEx, &quot;UInt&quot;, 1, &quot;Ptr*&quot;, evt, &quot;UInt&quot;, -1, &quot;UInt&quot;, 0x4FF, &quot;UInt&quot;, 0x0002) ; INFINITE, QS_ALLINPUT, MWMO_ALERTABLE - stolen from Lexikos
		Sleep -1 ; let AutoHotkey process messages
		if (r == 0) { ; WAIT_OBJECT_0
			desktopSwitched := True
			break
		} else if (r == -1) { ; WAIT_FAILED
			break
		}
	}

	;LogonDesktop_CloseHandle(evt)
	return desktopSwitched
}

LogonDesktop_GetTokenUser(hToken, ByRef TOKEN_USER)
{
	ret := dwLengthNeeded := 0

	if (!_GetTokenInformation(hToken, TokenUser := 1, 0, 0, dwLengthNeeded))
		if (A_LastError == 122 &amp;&amp; VarSetCapacity(TOKEN_USER, dwLengthNeeded)) ; ERROR_INSUFFICIENT_BUFFER
			ret := _GetTokenInformation(hToken, TokenUser, &amp;TOKEN_USER, dwLengthNeeded, dwLengthNeeded)

	return ret
}

_LookupAccountSidW(lpSid, ByRef username, ByRef domain := 0, ByRef use := 0) ; thanks to jNizM: https://autohotkey.com/boards/viewtopic.php?t=4365
{
	cchName := cchReferencedDomainName := 0
	if (!DllCall(&quot;advapi32.dll\LookupAccountSidW&quot;, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, lpSid, &quot;Ptr&quot;, 0, &quot;UInt*&quot;, cchName, &quot;Ptr&quot;, 0, &quot;UInt*&quot;, cchReferencedDomainName, &quot;UInt*&quot;, peUse) &amp;&amp; A_LastError == 122) {
		VarSetCapacity(n, cchName * 2), VarSetCapacity(d, cchReferencedDomainName * 2)
		ret := DllCall(&quot;advapi32.dll\LookupAccountSidW&quot;, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, lpSid, &quot;Ptr&quot;, &amp;n, &quot;UInt*&quot;, cchName, &quot;Ptr&quot;, &amp;d, &quot;UInt*&quot;, cchReferencedDomainName, &quot;UInt*&quot;, peUse)
		if (ret) {
			if (IsByRef(username))
				username := StrGet(&amp;n,, &quot;UTF-16&quot;)
			if (IsByRef(domain))
				domain := StrGet(&amp;d,, &quot;UTF-16&quot;)
			if (IsByRef(use))
				use := _use
		}
		return ret
	}
	return False
}

LogonDesktop_GetTokenUsername(hToken, ByRef username, ByRef domain := 0, ByRef use := 0)
{
	if (LogonDesktop_GetTokenUser(hToken, TOKEN_USER))
		return _LookupAccountSidW(NumGet(TOKEN_USER,, &quot;Ptr&quot;), username, domain, use)

	return False
}

LogonDesktop_GetProcessWindowStationName(ByRef out)
{
	ret := False

	if ((hWinSta := DllCall(&quot;GetProcessWindowStation&quot;, &quot;Ptr&quot;))) 
		ret := LogonDesktop_GetUserObjectName(hWinSta, out)
	
	return ret
}

LogonDesktop_GetThreadDesktopName(ByRef out, tId := -1)
{
	ret := False
	
	if ((hDesk := DllCall(&quot;GetThreadDesktop&quot;, &quot;UInt&quot;, tId == -1 ? DllCall(&quot;GetCurrentThreadId&quot;, &quot;UInt&quot;) : tId, &quot;Ptr&quot;))) 
		ret := LogonDesktop_GetUserObjectName(hDesk, out)
	
	return ret
}

LogonDesktop_ProcessIdToSessionId(dwProcessId, ByRef dwSessionId)
{
	static ProcessIdToSessionId := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;kernel32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;ProcessIdToSessionId&quot;, &quot;Ptr&quot;)
	return DllCall(ProcessIdToSessionId, &quot;UInt&quot;, dwProcessId, &quot;UInt*&quot;, dwSessionId)
}

/*
	LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), 0x0008, hToken) ; TOKEN_QUERY
	if (!LogonDesktop_GetTokenSessionId(hToken, scriptSessionId))
		return
	LogonDesktop_CloseHandle(hToken)
*/
LogonDesktop_GetTokenSessionId(hToken, ByRef out)
{
	ret := dwLengthNeeded := 0
		
	if (hToken)
		ret := _GetTokenInformation(hToken, 12, out, 4, dwLengthNeeded, &quot;UInt*&quot;) ; TokenSessionId

	return ret
}

LogonDesktop_PossiblyDetermineIfUnelevatedUserCanWriteToScript()
{
	AccessStatus := grantedAccess := hPrimaryToken := TokenIsElevated := hToken := dwLengthNeeded := ret := 0
	
	if ((desktopHwnd := DllCall(&quot;GetShellWindow&quot;, &quot;Ptr&quot;))) {
		WinGet, explorerPid, PID, ahk_id %desktopHwnd%
		if (explorerPid) {
			if ((hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, PROCESS_QUERY_LIMITED_INFORMATION := 0x1000, &quot;Int&quot;, False, &quot;UInt&quot;, explorerPid, &quot;Ptr&quot;))) {
				if (LogonDesktop_OpenProcessToken(hProc, TOKEN_QUERY := 0x0008 | TOKEN_DUPLICATE := 0x0002, hToken)) {
					if (_GetTokenInformation(hToken, TokenElevation := 20, TokenIsElevated, 4, dwLengthNeeded, &quot;UInt*&quot;)) {
						if (!TokenIsElevated) {
							; From Aaron Ballman @ http://blog.aaronballman.com/2011/08/how-to-check-access-rights/
							dwLengthNeeded := 0
							if (!DllCall(&quot;advapi32.dll\GetFileSecurity&quot;, &quot;WStr&quot;, A_ScriptFullPath, &quot;UInt&quot;, DACL_SECURITY_INFORMATION := 0x00000004 | OWNER_SECURITY_INFORMATION := 0x00000001 | GROUP_SECURITY_INFORMATION := 0x00000002, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;UInt*&quot;, dwLengthNeeded)) {
								if (A_LastError == (ERROR_INSUFFICIENT_BUFFER := 122) &amp;&amp; VarSetCapacity(sd, dwLengthNeeded) &amp;&amp; DllCall(&quot;advapi32.dll\GetFileSecurity&quot;, &quot;WStr&quot;, A_ScriptFullPath, &quot;UInt&quot;, DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, &quot;Ptr&quot;, &amp;sd, &quot;Ptr&quot;, dwLengthNeeded, &quot;UInt*&quot;, dwLengthNeeded)) {
									VarSetCapacity(GENERIC_MAPPING, 16)
									NumPut(0x00020000 | 0x0001 | 0x0080 | 0x0008 | 0x00100000, GENERIC_MAPPING, 0, &quot;UInt&quot;)	
									NumPut(0x00020000 | 0x0002 | 0x0100 | 0x0010 | 0x0004 | 0x00100000, GENERIC_MAPPING, 4, &quot;UInt&quot;)
									NumPut(0x00020000 | 0x0080 | 0x0020 | 0x00100000, GENERIC_MAPPING, 8, &quot;UInt&quot;)
									NumPut(0x000F0000 | 0x00100000 | 0x1FF, GENERIC_MAPPING, 12, &quot;UInt&quot;)
									GENERIC_WRITE := 0x40000000

									VarSetCapacity(PRIVILEGE_SET, cbPS := 20, 0)
									DllCall(&quot;advapi32.dll\MapGenericMask&quot;, &quot;UInt*&quot;, GENERIC_WRITE, &quot;Ptr&quot;, &amp;GENERIC_MAPPING)
									if (DllCall(&quot;advapi32.dll\DuplicateToken&quot;, &quot;Ptr&quot;, hToken, &quot;UInt&quot;, SecurityIdentification := 1, &quot;Ptr*&quot;, hPrimaryToken)) {
										if (DllCall(&quot;advapi32.dll\AccessCheck&quot;, &quot;Ptr&quot;, &amp;sd, &quot;Ptr&quot;, hPrimaryToken, &quot;UInt&quot;, GENERIC_WRITE, &quot;Ptr&quot;, &amp;GENERIC_MAPPING, &quot;Ptr&quot;, &amp;PRIVILEGE_SET, &quot;UInt*&quot;, cbPS, &quot;UInt*&quot;, grantedAccess, &quot;Int*&quot;, AccessStatus))
											ret := AccessStatus
										LogonDesktop_CloseHandle(hPrimaryToken)
									}
								}
							}
						}
					}
					LogonDesktop_CloseHandle(hToken)
				}
				LogonDesktop_CloseHandle(hProc)
			}
		}
	}
	
	return ret
}

; Pretty much from the GetEffectiveRightsFromAcl MSDN sample
LogonDesktop_AllUsersCanWriteToThisScript()
{
	; This doesn&#039;t check the allowed ACEs for users that are only part of the Users group. Bear that in mind...
	hAuthzResourceManager := hAuthzClientContext := psd := pacl := ret := 0

	SECURITY_MAX_SID_SIZE := 68
	SIDs := {&quot;WinBuiltinUsersSid&quot;: &quot;27&quot;, &quot;WinWorldSid&quot;: &quot;1&quot;}
	for k, v in SIDs {
		cbSize := SECURITY_MAX_SID_SIZE
		SIDs.SetCapacity(k, cbSize)
		if (!_CreateWellKnownSid(v+0, 0, SIDs.GetAddress(k), cbSize))
			return ret
	}

	if (!authzMod := _LoadLibrary(&quot;Authz.dll&quot;))
		return ret

	if (!DllCall(&quot;advapi32.dll\GetNamedSecurityInfoW&quot;, &quot;WStr&quot;, A_ScriptFullPath, &quot;UInt&quot;, SE_FILE_OBJECT := 1, &quot;UInt&quot;, DACL_SECURITY_INFORMATION := 0x00000004 | OWNER_SECURITY_INFORMATION := 0x00000001 | GROUP_SECURITY_INFORMATION := 0x00000002, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr*&quot;, pacl, &quot;Ptr&quot;, 0, &quot;Ptr*&quot;, psd, &quot;UInt&quot;)) {
		if (DllCall(&quot;Authz\AuthzInitializeResourceManager&quot;, &quot;UInt&quot;, AUTHZ_RM_FLAG_NO_AUDIT := 0x1, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr*&quot;, hAuthzResourceManager)) {
			for k, v in SIDs {
				if (DllCall(&quot;Authz\AuthzInitializeContextFromSid&quot;, &quot;UInt&quot;, 0, &quot;Ptr&quot;, SIDs.GetAddress(k), &quot;Ptr&quot;, hAuthzResourceManager, &quot;Ptr&quot;, 0, &quot;Int64&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr*&quot;, hAuthzClientContext)) {				
					VarSetCapacity(AUTHZ_ACCESS_REQUEST, 20 * (A_PtrSize == 8 ? 2 : 1), 0)
					VarSetCapacity(AUTHZ_ACCESS_REPLY, 16 * (A_PtrSize == 8 ? 2 : 1), 0)
					VarSetCapacity(buf, 1024, 0)
					
					NumPut(MAXIMUM_ALLOWED := 0x02000000, AUTHZ_ACCESS_REQUEST,, &quot;UInt&quot;)
					NumPut(1, AUTHZ_ACCESS_REPLY,, &quot;UInt&quot;)
					NumPut(&amp;buf, AUTHZ_ACCESS_REPLY, A_PtrSize, &quot;Ptr&quot;)
					NumPut(&amp;buf+4, AUTHZ_ACCESS_REPLY, 12 * (A_PtrSize == 8 ? 2 : 1), &quot;Ptr&quot;)

					if (DllCall(&quot;Authz\AuthzAccessCheck&quot;, &quot;UInt&quot;, 0, &quot;Ptr&quot;, hAuthzClientContext, &quot;Ptr&quot;, &amp;AUTHZ_ACCESS_REQUEST, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, psd, &quot;Ptr&quot;, 0, &quot;UInt&quot;, 0, &quot;Ptr&quot;, &amp;AUTHZ_ACCESS_REPLY, &quot;Ptr&quot;, 0)) {
						GrantedAccessMask := NumGet(buf,, &quot;UInt&quot;)
						GENERIC_WRITE := 0x40000000
						FILE_GENERIC_WRITE := 0x00020000 | 0x0002 | 0x0100 | 0x0010 | 0x0004 | 0x00100000
						if (((GrantedAccessMask &amp; GENERIC_WRITE) == GENERIC_WRITE) || ((GrantedAccessMask &amp; FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE))
							ret := True
					}
					DllCall(&quot;Authz\AuthzFreeContext&quot;, &quot;Ptr&quot;, hAuthzClientContext)
					VarSetCapacity(buf, 0)

					if (ret)
						break
				}
			}
			DllCall(&quot;Authz\AuthzFreeResourceManager&quot;, &quot;Ptr&quot;, hAuthzResourceManager)
		}
	}
	
	_FreeLibrary(authzMod)
	return ret
}

LogonDesktop_SetUiAccessToken(hToken, reallyHigh) {
	; Unsure if there is more to it
	static tilSize := 8 * (A_PtrSize == 8 ? 2 : 1), SECURITY_LABEL_MEDIUM_MORE_SID := 0, SECURITY_LABEL_HIGH_SID

	if (hToken) {
		if (reallyHigh) {
			; 0x3000
			if (!VarSetCapacity(SECURITY_LABEL_HIGH_SID)) {
				VarSetCapacity(SECURITY_LABEL_HIGH_SID, cbSize := 256) ; MAX_SID_SIZE
				if (!_CreateWellKnownSid(68, 0, &amp;SECURITY_LABEL_HIGH_SID, cbSize)) ; WinHighLabelSid
					return
			}
		} else {
			; SECURITY_MANDATORY_MEDIUM_RID (0x2000) + 0x10 - not the same thing as SECURITY_MANDATORY_MEDIUM_PLUS_RID (0x100)!
			if (!SECURITY_LABEL_MEDIUM_MORE_SID) {
				if (!DllCall(&quot;advapi32.dll\ConvertStringSidToSidW&quot;, &quot;WStr&quot;, &quot;S-1-16-8208&quot;, &quot;Ptr*&quot;, SECURITY_LABEL_MEDIUM_MORE_SID)) ; &quot;higherIntegrityLevelSidForLimitedAccounts&quot;
					return
			}
		}

		lpSecLabel := reallyHigh ? &amp;SECURITY_LABEL_HIGH_SID : SECURITY_LABEL_MEDIUM_MORE_SID
		if (_SetTokenInformation(hToken, 26, True, 4, &quot;UInt*&quot;)) { ; TokenUIAccess
			; https://msdn.microsoft.com/en-us/library/bb625960.aspx
			VarSetCapacity(TOKEN_MANDATORY_LABEL, tilSize, 0), NumPut(lpSecLabel, TOKEN_MANDATORY_LABEL,, &quot;Ptr&quot;), NumPut(0x00000020, TOKEN_MANDATORY_LABEL, A_PtrSize, &quot;UInt&quot;) ; SE_GROUP_INTEGRITY
			_SetTokenInformation(hToken, 25, &amp;TOKEN_MANDATORY_LABEL, tilSize + _GetLengthSid(lpSecLabel)) ; TokenIntegrityLevel
		}
		
;		if (SECURITY_LABEL_MEDIUM_MORE_SID)
;			DllCall(&quot;LocalFree&quot;, &quot;Ptr&quot;, SECURITY_LABEL_MEDIUM_MORE_SID, &quot;Ptr&quot;)
	}
}

; https://code.msdn.microsoft.com/windowsapps/CppUACSelfElevation-5bfc52dd
LogonDesktop_DoesTokenContainAdminGroupDirectlyOrNot(hToken, fallBackToLegacyMethod := False)
{
	static adminSID, CheckTokenMembership := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;CheckTokenMembership&quot;, &quot;Ptr&quot;), DuplicateToken := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;DuplicateToken&quot;, &quot;Ptr&quot;)
	hTokenToCheck := fInAdminGroup := 0

	if (!hToken)
		return fInAdminGroup

	; Create the SID corresponding to the Administrators group.
	if (!VarSetCapacity(adminSID)) {
		VarSetCapacity(adminSID, cbSize := 68) ; SECURITY_MAX_SID_SIZE
		if (!_CreateWellKnownSid(26, 0, &amp;adminSID, cbSize)) { ; WinBuiltinAdministratorsSid 
			VarSetCapacity(adminSID, 0)
			return fInAdminGroup
		}
	}

	; Determine token type: limited, elevated, or default
	if (!_GetTokenInformation(hToken, 18, elevType, 4, cbSize, &quot;UInt*&quot;)) ; TokenElevationType
		return fInAdminGroup

	; If limited, get the linked elevated token for further check.
	if (3 == elevType) ; TokenElevationTypeLimited
	{
		if (!_GetTokenInformation(hToken, 19, hTokenToCheck, A_PtrSize, cbSize, &quot;Ptr*&quot;)) ; TokenLinkedToken
			return fInAdminGroup
	}

	/* CheckTokenMembership requires an impersonation token. If we just got a 
	 linked token, it already is an impersonation token.  If we did not get 
	 a linked token, duplicate the original into an impersonation token for 
	 CheckTokenMembership.
	*/
	if (!hTokenToCheck)
	{
		if (!DllCall(DuplicateToken, &quot;Ptr&quot;, hToken, &quot;UInt&quot;, 1, &quot;Ptr*&quot;, hTokenToCheck)) ; SecurityIdentification
			return fInAdminGroup
	}

	/* Check if the token to be checked contains admin SID.
	 http://msdn.microsoft.com/en-us/library/aa379596(VS.85).aspx:
	 To determine whether a SID is enabled in a token, that is, whether it 
	 has the SE_GROUP_ENABLED attribute, call CheckTokenMembership.
	*/
	if (!DllCall(CheckTokenMembership, &quot;Ptr&quot;, hTokenToCheck, &quot;Ptr&quot;, &amp;adminSID, &quot;Int*&quot;, fInAdminGroup) &amp;&amp; fallBackToLegacyMethod &amp;&amp; A_LastError == 1309) ; ERROR_NO_IMPERSONATION_TOKEN
		fInAdminGroup := _DetermineIfTheTokenHasAGroupTheNT4Way(hTokenToCheck, &amp;adminSID)

	if (hTokenToCheck)
		LogonDesktop_CloseHandle(hTokenToCheck)

	return fInAdminGroup
}

_isTokenUiAccess(hToken)
{
	ret := False
	if (hToken)
		_GetTokenInformation(hToken, TokenUIAccess := 26, ret, 4, dwLengthNeeded, &quot;UInt*&quot;)
	return ret
}

LogonDesktop_isThisProcessUiAccess()
{
	ret := False
	if (LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), TOKEN_QUERY := 0x0008, hToken)) {
		ret := _isTokenUiAccess(hToken)
		LogonDesktop_CloseHandle(hToken)
	}
	return ret
}

LogonDesktop_isThisProcessHighIntegrity()
{
	ret := false
	if (LogonDesktop_OpenProcessToken(LogonDesktop_GetCurrentProcess(), TOKEN_QUERY := 0x0008, hToken)) {
		if (!_GetTokenInformation(hToken, TokenIntegrityLevel := 25, 0, 0, dwLengthNeeded))
			if (A_LastError == (ERROR_INSUFFICIENT_BUFFER := 122))
				if (VarSetCapacity(pTIL, dwLengthNeeded) &amp;&amp; _GetTokenInformation(hToken, TokenIntegrityLevel, &amp;pTIL, dwLengthNeeded, dwLengthNeeded))
					ret := (DllCall(&quot;advapi32.dll\GetSidSubAuthority&quot;, &quot;Ptr&quot;, (pSid := NumGet(pTil,, &quot;Ptr&quot;)), &quot;UInt&quot;, DllCall(&quot;advapi32.dll\GetSidSubAuthorityCount&quot;, &quot;Ptr&quot;, pSid, &quot;UChar*&quot;)-1, &quot;UInt*&quot;)) &gt;= 0x00002010
		LogonDesktop_CloseHandle(hToken)
	}

	return ret
}

LogonDesktop_SessionIsLocked(sessionId)
{
	static WTS_CURRENT_SERVER_HANDLE := 0, WTSSessionInfoEx := 25, WTS_SESSIONSTATE_LOCK := 0x00000000, WTS_SESSIONSTATE_UNLOCK := 0x00000001 ;, WTS_SESSIONSTATE_UNKNOWN := 0xFFFFFFFF
	ret := False
	
	if (DllCall(&quot;wtsapi32\WTSQuerySessionInformation&quot;, &quot;Ptr&quot;, WTS_CURRENT_SERVER_HANDLE, &quot;UInt&quot;, sessionId, &quot;UInt&quot;, WTSSessionInfoEx, &quot;Ptr*&quot;, sesInfo, &quot;Ptr*&quot;, BytesReturned)) {
		SessionFlags := NumGet(sesInfo+0, 16, &quot;Int&quot;)
		; &quot;Windows Server 2008 R2 and Windows 7: Due to a code defect, the usage of the WTS_SESSIONSTATE_LOCK and WTS_SESSIONSTATE_UNLOCK flags is reversed.&quot;
		ret := A_OSVersion != &quot;WIN_7&quot; ? SessionFlags == WTS_SESSIONSTATE_LOCK : SessionFlags == WTS_SESSIONSTATE_UNLOCK
		DllCall(&quot;wtsapi32\WTSFreeMemory&quot;, &quot;Ptr&quot;, sesInfo)
	}

	return ret
}

LogonDesktop_WTSEnumerateProcessesEx(ByRef WTS, hServer := 0, SessionID := 0xFFFFFFFE) ; WTS_CURRENT_SERVER_HANDLE, WTS_ANY_SESSION
{ ; Todo: 32-Bit support. https://msdn.microsoft.com/en-us/library/ee621013(v=vs.85).aspx. Based on jNizM&#039;s code: https://github.com/jNizM/AHK_ProcessExplorer/blob/HEAD/src/ProcessExplorer.ahk#L112
	local PI := PI_EX := TTL := 0
	if (!DllCall(&quot;wtsapi32\WTSEnumerateProcessesEx&quot;, &quot;ptr&quot;, hServer, &quot;UInt*&quot;, 1, &quot;UInt&quot;, SessionID, &quot;Ptr*&quot;, PI_EX, &quot;UInt*&quot;, TTL))
		return False
	PI := PI_EX, WTS := []
	loop % TTL
	{
		entry := {&quot;SessionID&quot;: NumGet(PI+0, &quot;UInt&quot;)
				 ,&quot;ProcessID&quot;: NumGet(PI+4, &quot;UInt&quot;)
				 ,&quot;ProcessName&quot;: StrGet(NumGet(PI+8, &quot;ptr&quot;))
				 ,&quot;NumberOfThreads&quot;: NumGet(PI+24, &quot;UInt&quot;)
				 ,&quot;HandleCount&quot;: NumGet(PI+28, &quot;UInt&quot;)
				 ,&quot;PagefileUsage&quot;: NumGet(PI+32, &quot;UInt&quot;)
				 ,&quot;PeakPagefileUsage&quot;: NumGet(PI+36, &quot;UInt&quot;)
				 ,&quot;WorkingSetSize&quot;: NumGet(PI+40, &quot;UInt&quot;)
				 ,&quot;PeakWorkingSetSize&quot;: NumGet(PI+44, &quot;UInt&quot;)
				 ,&quot;UserTime&quot;: NumGet(PI+48, &quot;Int64&quot;)
				 ,&quot;KernelTime&quot;: NumGet(PI+56, &quot;Int64&quot;)}

		SID := NumGet(PI+16, &quot;ptr&quot;)
		if (_IsValidSid(SID)) {
			if (_LookupAccountSidW(SID, Name, Domain)) {
				entry[&quot;UserName&quot;] := Name
				entry[&quot;UserDomain&quot;] := Domain
			}

			SIDLength := _GetLengthSid(SID)
			if (entry.SetCapacity(&quot;UserSID&quot;, SIDLength) &gt;= SIDLength)
				DllCall(&quot;ntdll\RtlMoveMemory&quot;, &quot;Ptr&quot;, entry.GetAddress(&quot;UserSID&quot;), &quot;Ptr&quot;, SID, &quot;Ptr&quot;, SIDLength)
		}
		WTS.Push(entry)

		PI += 64
	}
	DllCall(&quot;wtsapi32\WTSFreeMemoryEx&quot;, &quot;UInt&quot;, 1, &quot;ptr&quot;, PI_EX, &quot;UInt&quot;, TTL)
	return True
}

_DetermineIfTheTokenHasAGroupTheNT4Way(hToken, pSid) { ; Seriously, don&#039;t use this.
	static SE_GROUP_ENABLED := 0x00000004, SE_GROUP_USE_FOR_DENY_ONLY := 0x00000010, cbSID_AND_ATTRIBUTES := 8 * (A_PtrSize == 8 ? 2 : 1)
	retval := False

	if (!hToken || !pSid)
		return retval

	if (!_GetTokenInformation(hToken, TokenGroups := 2, 0, 0, dwSize))
		if (A_LastError != 122) ; ERROR_INSUFFICIENT_BUFFER
			return retval

	VarSetCapacity(groupInfo, dwSize, 0)
	if (!_GetTokenInformation(hToken, TokenGroups, &amp;groupInfo, dwSize, dwSize))
		return retval

	GroupCount := NumGet(groupInfo,, &quot;UInt&quot;)
	Loop % GroupCount {
		currGroupOffset := A_PtrSize + (cbSID_AND_ATTRIBUTES * (A_Index - 1)) 
		Attributes := NumGet(groupInfo, currGroupOffset + A_PtrSize, &quot;UInt&quot;)
		if (Attributes &amp; SE_GROUP_USE_FOR_DENY_ONLY)
			continue
		if ((Attributes &amp; SE_GROUP_ENABLED) &amp;&amp; _EqualSid(pSID, NumGet(groupInfo, currGroupOffset, &quot;Ptr&quot;))) {
			retval := true
			break
		}
	}

	return retval
}

_EqualSid(pSid1, pSid2)
{
	static EqualSid := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;EqualSid&quot;, &quot;Ptr&quot;)
	return DllCall(EqualSid, &quot;Ptr&quot;, pSid1, &quot;Ptr&quot;, pSid2)
}

LogonDesktop_GetUserObjectName(hObj, ByRef out) {
	static GetUserObjectInformationW := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;user32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;GetUserObjectInformationW&quot;, &quot;Ptr&quot;)
	nLengthNeeded := VarSetCapacity(out)

	if (!(ret := DllCall(GetUserObjectInformationW, &quot;Ptr&quot;, hObj, &quot;Int&quot;, 2, &quot;WStr&quot;, out, &quot;UInt&quot;, nLengthNeeded, &quot;UInt*&quot;, nLengthNeeded))) ; UOI_NAME
		if (A_LastError == 122 &amp;&amp; VarSetCapacity(out, nLengthNeeded)) ; ERROR_INSUFFICIENT_BUFFER
			ret := DllCall(GetUserObjectInformationW, &quot;Ptr&quot;, hObj, &quot;Int&quot;, 2, &quot;WStr&quot;, out, &quot;UInt&quot;, nLengthNeeded, &quot;Ptr&quot;, 0)

	return ret
}

_OnWinLogonDesktop()
{
	static OpenInputDesktop := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;user32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;OpenInputDesktop&quot;, &quot;Ptr&quot;), desktopName

	if !VarSetCapacity(desktopName)
		VarSetCapacity(desktopName, 65534)

	if hDesk := DllCall(OpenInputDesktop, &quot;UInt&quot;, 0, &quot;Int&quot;, False, &quot;UInt&quot;, 0, &quot;Ptr&quot;)
		return !LogonDesktop_GetUserObjectName(hDesk, desktopName) || desktopName == &quot;Winlogon&quot;, LogonDesktop_CloseDesktop(hDesk)

	return True
}

LogonDesktop_LoadWtsApi() {
	static lib := &quot;wtsapi32.dll&quot;
	return _LoadLibrary(lib)
}

LogonDesktop_UnloadWtsApi(wtsapiModule) {
	return _FreeLibrary(wtsapiModule)
}

LogonDesktop_WTSQueryUserToken(SessionId, ByRef phToken) {
	return DllCall(&quot;wtsapi32\WTSQueryUserToken&quot;, &quot;UInt&quot;, SessionId, &quot;Ptr*&quot;, phToken)
}

LogonDesktop_DuplicateTokenEx(hExistingToken, dwDesiredAccess, lpTokenAttributes, ImpersonationLevel, TokenType, ByRef phNewToken) {
	static DuplicateTokenEx := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;DuplicateTokenEx&quot;, &quot;Ptr&quot;)
	return DllCall(DuplicateTokenEx, &quot;Ptr&quot;, hExistingToken, &quot;UInt&quot;, dwDesiredAccess, &quot;Ptr&quot;, lpTokenAttributes, &quot;UInt&quot;, ImpersonationLevel, &quot;UInt&quot;, TokenType, &quot;Ptr*&quot;, phNewToken)
}

_CreateProcessAsUserW(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) {
	static CreateProcessAsUserW := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;CreateProcessAsUserW&quot;, &quot;Ptr&quot;)
	return DllCall(CreateProcessAsUserW, &quot;Ptr&quot;, hToken, &quot;Ptr&quot;, lpApplicationName, &quot;Ptr&quot;, lpCommandLine, &quot;Ptr&quot;, lpProcessAttributes, &quot;Ptr&quot;, lpThreadAttributes, &quot;Int&quot;, bInheritHandles, &quot;UInt&quot;, dwCreationFlags, &quot;Ptr&quot;, lpEnvironment, &quot;Ptr&quot;, lpCurrentDirectory, &quot;Ptr&quot;, lpStartupInfo, &quot;Ptr&quot;, lpProcessInformation)
}

_CreateProcessWithTokenW(hToken, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInfo) {
	static CreateProcessWithTokenW := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;CreateProcessWithTokenW&quot;, &quot;Ptr&quot;)
	return DllCall(CreateProcessWithTokenW, &quot;Ptr&quot;, hToken, &quot;UInt&quot;, dwLogonFlags, &quot;Ptr&quot;, lpApplicationName, &quot;Ptr&quot;, lpCommandLine, &quot;UInt&quot;, dwCreationFlags, &quot;Ptr&quot;, lpEnvironment, &quot;Ptr&quot;, lpCurrentDirectory, &quot;Ptr&quot;, lpStartupInfo, &quot;Ptr&quot;, lpProcessInformation)
}

LogonDesktop_OpenProcessToken(ProcessHandle, DesiredAccess, ByRef TokenHandle) {
	static OpenProcessToken := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;OpenProcessToken&quot;, &quot;Ptr&quot;)
	return DllCall(OpenProcessToken, &quot;Ptr&quot;, ProcessHandle, &quot;UInt&quot;, DesiredAccess, &quot;Ptr*&quot;, TokenHandle)
}

LogonDesktop_CloseHandle(hObject) {
	static CloseHandle := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;kernel32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;CloseHandle&quot;, &quot;Ptr&quot;), INVALID_HANDLE_VALUE := -1
	return (hObject &amp;&amp; hObject != INVALID_HANDLE_VALUE) ? DllCall(CloseHandle, &quot;Ptr&quot;, hObject) : False
}

LogonDesktop_CloseDesktop(hDesktop) {
	static CloseDesktop := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;user32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;CloseDesktop&quot;, &quot;Ptr&quot;)
	return DllCall(CloseDesktop, &quot;Ptr&quot;, hDesktop)
}

_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,, &quot;Ptr&quot;)
}

_PROCESS_INFORMATION_hThread(ByRef pi) {
	return NumGet(pi, A_PtrSize, &quot;Ptr&quot;)
}

_STARTUPINFO(ByRef si, lpDesktop := 0, ShowWindow := -1, restOneDay*) {
	static siCb := A_PtrSize == 8 ? 104 : 68
	if (IsByRef(si)) {
		dwFlags := 0
		VarSetCapacity(si, siCb, 0), NumPut(siCb, si,, &quot;UInt&quot;)
		if (lpDesktop)
			NumPut(lpDesktop, si, A_PtrSize * 2, &quot;Ptr&quot;)
		if (ShowWindow &gt; -1) {
			dwFlags |= 0x00000001 ; STARTF_USESHOWWINDOW
			NumPut(ShowWindow, si, A_PtrSize == 8 ? 64 : 48, &quot;UShort&quot;)
		}
		NumPut(dwFlags, si, A_PtrSize == 8 ? 60 : 44, &quot;UInt&quot;)
	}
}

_PrepareEnvironmentBlockCall() {
	static lib := &quot;userenv.dll&quot;
	return _LoadLibrary(lib)
}

_CreateEnvironmentBlock(ByRef lpEnvironment, hToken, bInherit) {
	return DllCall(&quot;userenv.dll\CreateEnvironmentBlock&quot;, &quot;Ptr*&quot;, lpEnvironment, &quot;Ptr&quot;, hToken, &quot;Int&quot;, bInherit)
}

_DestroyEnvironmentBlock(lpEnvironment) {
	return DllCall(&quot;userenv.dll\DestroyEnvironmentBlock&quot;, &quot;Ptr&quot;, lpEnvironment)
}

_EndEnvironmentBlockCall(userenvModule) {
	return _FreeLibrary(userenvModule)
}

_GetTokenInformation(TokenHandle, TokenInformationClass, ByRef TokenInformation, TokenInformationLength, ByRef ReturnLength := 0, _tokenInfoType := &quot;Ptr&quot;) {
	static GetTokenInformation := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;GetTokenInformation&quot;, &quot;Ptr&quot;)
	return DllCall(GetTokenInformation, &quot;Ptr&quot;, TokenHandle, &quot;UInt&quot;, TokenInformationClass, _tokenInfoType, TokenInformation, &quot;UInt&quot;, TokenInformationLength, &quot;UInt*&quot;, ReturnLength)
}

_SetTokenInformation(TokenHandle, TokenInformationClass, ByRef TokenInformation, TokenInformationLength, _tokenInfoType := &quot;Ptr&quot;) {
	static SetTokenInformation := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;SetTokenInformation&quot;, &quot;Ptr&quot;)
	return DllCall(SetTokenInformation, &quot;Ptr&quot;, TokenHandle, &quot;UInt&quot;, TokenInformationClass, _tokenInfoType, TokenInformation, &quot;UInt&quot;, TokenInformationLength)
}

_CreateWellKnownSid(WellKnownSidType, DomainSid, pSid, ByRef cbSid) {
	static CreateWellKnownSid := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;CreateWellKnownSid&quot;, &quot;Ptr&quot;)
	return DllCall(CreateWellKnownSid, &quot;UInt&quot;, WellKnownSidType, &quot;Ptr&quot;, DomainSid, &quot;Ptr&quot;, pSid, &quot;UInt*&quot;, cbSid)
}

_IsValidSid(pSid) {
	static IsValidSid := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;IsValidSid&quot;, &quot;Ptr&quot;)
	return DllCall(IsValidSid, &quot;Ptr&quot;, pSid)
}

_GetLengthSid(pSid) {
	static GetLengthSid := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;advapi32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;GetLengthSid&quot;, &quot;Ptr&quot;)
	return DllCall(GetLengthSid, &quot;Ptr&quot;, pSid, &quot;UInt&quot;)
}

_FindASystemProcessToken(TokenWantedPerms := 0xF, FilterFunc := 0, FilterFuncExtraData := 0, lookInSession := 0) { ; TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_IMPERSONATE - the token returned isn&#039;t a duplicated one
	static PROCESS_QUERY_INFORMATION := 0x0400
	ret := 0

	if (LogonDesktop_AdjustThisProcessPrivileges({&quot;SeDebugPrivilege&quot;: True}, PreviousState)) {
		if (LogonDesktop_WTSEnumerateProcessesEx(WTS,, lookInSession)) {
			FilterFuncValid := IsObject(FilterFunc) &amp;&amp; IsFunc(FilterFunc)
			for _, proc in WTS {
				if (_IsSystemSid(proc.GetAddress(&quot;UserSID&quot;))) {
					if ((hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, PROCESS_QUERY_INFORMATION, &quot;Int&quot;, False, &quot;UInt&quot;, proc.ProcessID, &quot;Ptr&quot;))) {
						if (LogonDesktop_OpenProcessToken(hProc, TokenWantedPerms, ret), LogonDesktop_CloseHandle(hProc)) {
							if (!FilterFuncValid || FilterFunc.Call(proc, ret, FilterFuncExtraData))
								break
						}
					}
				}
			}
		}
		LogonDesktop_AdjustThisProcessPrivileges(0, PreviousState)
	}
	
	return ret
}

LogonDesktop_GetCurrentProcessId() {
	static dwProcessId := DllCall(&quot;GetCurrentProcessId&quot;, &quot;UInt&quot;) ; well, it&#039;s not like this one is going to change each time we call it
	return dwProcessId
}

LogonDesktop_GetCurrentProcess() {
	static hProc := DllCall(&quot;GetCurrentProcess&quot;, &quot;Ptr&quot;) ; always -1
	return hProc
}

_LoadLibrary(lpFileName) {
	static LoadLibraryW := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;kernel32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;LoadLibraryW&quot;, &quot;Ptr&quot;)
	return DllCall(LoadLibraryW, &quot;WStr&quot;, lpFileName, &quot;Ptr&quot;)
}

_FreeLibrary(hModule) {
	static FreeLibrary := DllCall(&quot;GetProcAddress&quot;, &quot;Ptr&quot;, DllCall(&quot;GetModuleHandleW&quot;, &quot;WStr&quot;, &quot;kernel32.dll&quot;, &quot;Ptr&quot;), &quot;AStr&quot;, &quot;FreeLibrary&quot;, &quot;Ptr&quot;)
	return DllCall(FreeLibrary, &quot;Ptr&quot;, hModule)
}

_TOKEN_ALL_ACCESS()
{
	return (STANDARD_RIGHTS_REQUIRED := 0x000F0000 | TOKEN_ASSIGN_PRIMARY := 0x0001 | TOKEN_DUPLICATE := 0x0002 | TOKEN_IMPERSONATE := 0x0004 | TOKEN_QUERY := 0x0008 | TOKEN_QUERY_SOURCE := 0x0010 | TOKEN_ADJUST_PRIVILEGES := 0x0020 | TOKEN_ADJUST_GROUPS := 0x0040 | TOKEN_ADJUST_DEFAULT := 0x0080 | TOKEN_ADJUST_SESSIONID := 0x0100)
}

GetParentProcessID()
{
	; Undocumented, and could break at any time, but far easier than the CreateToolhelp32Snapshot way...
	VarSetCapacity(PROCESS_BASIC_INFORMATION, pbiSz := A_PtrSize == 8 ? 48 : 24)
	if (DllCall(&quot;ntdll\NtQueryInformationProcess&quot;, &quot;Ptr&quot;, LogonDesktop_GetCurrentProcess(), &quot;UInt&quot;, 0, &quot;Ptr&quot;, &amp;PROCESS_BASIC_INFORMATION, &quot;UInt&quot;, pbiSz, &quot;Ptr&quot;, 0) &gt;= 0)
		return NumGet(PROCESS_BASIC_INFORMATION, pbiSz - A_PtrSize, &quot;UInt&quot;)
	return 0
}

GetParentProcessName()
{
	if (parentPID := GetParentProcessID()) {
		if (hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, 0x1000 | 0x0010, &quot;Int&quot;, False, &quot;UInt&quot;, parentPID, &quot;Ptr&quot;)) { ; PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ
			VarSetCapacity(procName, (260 + 1) * 2)
			bnOK := !!DllCall(&quot;K32GetModuleBaseNameW&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, 0, &quot;WStr&quot;, procName, &quot;UInt&quot;, 260, &quot;UInt&quot;)
			LogonDesktop_CloseHandle(hProc)
			if (bnOK)
				return procName
		}
	}
	return &quot;&quot;
}</code></pre></div><p><a href="https://www.autohotkey.com/boards/viewtopic.php?p=129830">https://www.autohotkey.com/boards/viewt … p?p=129830</a><br /><a href="https://www.autohotkey.com/boards/viewtopic.php?f=6&amp;t=27709">https://www.autohotkey.com/boards/viewt … mp;t=27709</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 11 May 2020 16:25:03 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=139447#p139447</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129602#p129602</link>
			<description><![CDATA[<p>Уточнение: компилировать скрипт не обязательно, можно запустить с помощью интерпретатора.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Fri, 02 Nov 2018 07:29:20 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129602#p129602</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129601#p129601</link>
			<description><![CDATA[<p>Спасибо, все работает!</p>]]></description>
			<author><![CDATA[null@example.com (DrDron)]]></author>
			<pubDate>Fri, 02 Nov 2018 05:05:05 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129601#p129601</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129599#p129599</link>
			<description><![CDATA[<p>Да, наверное, потому что запущено от SYSTEM.</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Fri, 02 Nov 2018 01:37:23 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129599#p129599</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129597#p129597</link>
			<description><![CDATA[<p>Действительно, работает на экране блокировки. Но не работает в обычном режиме.<br /></p><div class="codebox"><pre><code>counter := 0
$!1:: SetTimer, Timer, 300

Timer:
   ToolTip % ++counter
   Return</code></pre></div><p>Запускал так:<br /></p><div class="codebox"><pre><code>Run D:\DISTRIBUTs\PSTools\PsExec.exe /h /x /d /s &quot;D:\OneDrive\Scripts\_Разработка\New8.exe&quot;</code></pre></div><p>от админа.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Thu, 01 Nov 2018 23:39:24 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129597#p129597</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129592#p129592</link>
			<description><![CDATA[<p>Есть.<br /><a href="http://forum.script-coding.com/viewtopic.php?pid=105903#p105903">http://forum.script-coding.com/viewtopi … 03#p105903</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Thu, 01 Nov 2018 21:26:35 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129592#p129592</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129590#p129590</link>
			<description><![CDATA[<p>Нету.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Thu, 01 Nov 2018 20:17:42 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129590#p129590</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Хоткей с экрана блокировки Windows]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=129581#p129581</link>
			<description><![CDATA[<p>Подскажите, есть ли возможность обратится к скрипту AHK с помощью хоткея с экрана блокировки Windows?</p>]]></description>
			<author><![CDATA[null@example.com (DrDron)]]></author>
			<pubDate>Thu, 01 Nov 2018 17:57:52 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=129581#p129581</guid>
		</item>
	</channel>
</rss>
