<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Эмулирование drag and drop в стороннее приложение через инжект]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=17667</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17667&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Эмулирование drag and drop в стороннее приложение через инжект».]]></description>
		<lastBuildDate>Sun, 12 Mar 2023 03:11:38 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[AHK: Эмулирование drag and drop в стороннее приложение через инжект]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=157104#p157104</link>
			<description><![CDATA[<p>Не во все приложения можно передать файлы с помощью сообщения WM_DROPFILES.<br />Такие приложения испльзуют IDropTarget interface.<br /><a href="https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nn-oleidl-idroptarget">https://docs.microsoft.com/en-us/window … droptarget</a><br />Чтобы узнать его адрес и использовать его методы нужен инжект.</p><p>Файлы должны быть разделены с &quot;|&quot;.<br />Позиция для перетаскивания определяется тут:<br /></p><div class="codebox"><pre><code>WinGetPos, x, y, width, height, ahk_id %Hwnd%
x += Round((Width*96/A_ScreenDPI)*2/3)
y += Round((Height*96/A_ScreenDPI)/2)</code></pre></div><p>Для каждого приложения должна определяться по разному алгоритму.<br />Битность автохотки и приложения должны совпадать.<br />AutoHotkeyMiniDll скачать тут<br /><a href="https://raw.githubusercontent.com/HotKeyIt/ahkdll-v1-release/master/Win32w/AutoHotkeyMini.dll">https://raw.githubusercontent.com/HotKe … eyMini.dll</a><br /><a href="https://raw.githubusercontent.com/HotKeyIt/ahkdll-v1-release/master/x64w/AutoHotkeyMini.dll">https://raw.githubusercontent.com/HotKe … eyMini.dll</a><br />Переименовать в AutoHotkeyMini_32.dll и в AutoHotkeyMini_64.dll соответственно, сделать им unlock и положить в папку со скриптом.<br /></p><div class="codebox"><pre><code>AutoHotkeyMiniDll := A_ScriptDir &quot;\AutoHotkeyMini_&quot; A_PtrSize*8 &quot;.dll&quot;
WindowTitle := &quot;ahk_exe Adobe Premiere Pro.exe&quot;
Filenames := &quot;D:\test1.mp4|D:\test2.mp4&quot;


f1::
WinActivate, %WindowTitle%
WinWaitActive, %WindowTitle%,, 2
if ErrorLevel
{
   MsgBox, 274336,, WinWaitActive timed out.
   return
}
WinGet, Hwnd, ID, %WindowTitle%
WinGet, PID, PID, ahk_id %Hwnd%
if (pid != pidPrev)
{
   if !pidPrev
   {
      if !DllCall(&quot;user32\GetProp&quot;, &quot;ptr&quot;, Hwnd, &quot;str&quot;, &quot;OleDropTargetInterface&quot;, &quot;ptr&quot;)
      {
         msgbox no OleDropTargetInterface
         return
      }
      Proc := DllCall(&quot;kernel32\OpenProcess&quot;, &quot;uint&quot;, PROCESS_QUERY_INFORMATION := 0x400, &quot;int&quot;, 0, &quot;uint&quot;, PID, &quot;ptr&quot;)
      DllCall(&quot;kernel32\IsWow64Process&quot;, &quot;ptr&quot;, Proc, &quot;int*&quot;, IsWow64Process)
      DllCall(&quot;kernel32\CloseHandle&quot;, &quot;ptr&quot;, Proc)
      if ((IsWow64Process = 0) and (A_PtrSize = 4)) or ((IsWow64Process = 1) and (A_PtrSize = 8))
      {
         msgbox process bitness mismatch
         ExitApp
      }
   }
   rThread := &quot;&quot;
   rThread := InjectAhkDll(PID, AutoHotkeyMiniDll)
   pidPrev := pid
}
WinGetPos, x, y, width, height, ahk_id %Hwnd%
x += Round((Width*96/A_ScreenDPI)*2/3)
y += Round((Height*96/A_ScreenDPI)/2)

DragAndDropScript1 := &quot;Hwnd := &quot; Hwnd &quot;, filenames := &quot;&quot;&quot; Filenames &quot;&quot;&quot;, x := &quot; x &quot;, y := &quot; y &quot;`r`n&quot;
if !DragAndDropScript2
{
   DragAndDropScript2 =
   (% ` Join`r`n
      SetBatchLines -1
      filenames := StrSplit(filenames, &quot;|&quot;)
      path := filenames.1
      SplitPath, path,, dir
      for key, path in filenames
      {
         SplitPath, path, name
         filenames[key] := name
      }
      if (!IsObject(filenames) || !filenames.MaxIndex() || !filenames[1])
         return
      if (!(pUnk := DllCall(&quot;GetProp&quot;, &quot;Ptr&quot;, hWnd, &quot;Str&quot;, &quot;OleDropTargetInterface&quot;, &quot;Ptr&quot;)))
         return
      if (!VarSetCapacity(IID_IDataObject))
      {
         VarSetCapacity(IID_IDataObject, 16)
         DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{0000010e-0000-0000-C000-000000000046}&quot;, &quot;Ptr&quot;, &amp;IID_IDataObject)
      }
      if (!VarSetCapacity(IID_IShellFolder))
      {
         VarSetCapacity(IID_IShellFolder, 16)
         DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{000214E6-0000-0000-C000-000000000046}&quot;, &quot;Ptr&quot;, &amp;IID_IShellFolder)
      }
      DllCall(&quot;shell32\SHGetDesktopFolder&quot;, &quot;Ptr*&quot;, pDesktop)
      if (dir = A_Desktop)
         pISF := pDesktop
      else
      {
         DllCall(&quot;shell32\SHParseDisplayName&quot;, &quot;WStr&quot;, dir, &quot;Ptr&quot;, 0, &quot;Ptr*&quot;, pidl_dir, UInt, 0, Ptr, 0)
         DllCall(NumGet(NumGet(pDesktop+0)+5*A_PtrSize), &quot;Ptr&quot;, pDesktop, &quot;Ptr&quot;, pidl_dir, &quot;UInt&quot;, 0, &quot;Ptr&quot;, &amp;IID_IShellFolder, &quot;Ptr*&quot;, pISF) ; BindToObject
      }
      if (pISF)
      {
         pDropTarget := ComObjQuery(pUnk, &quot;{00000122-0000-0000-C000-000000000046}&quot;)
         VarSetCapacity(pidl_list, filenames.MaxIndex() * A_PtrSize)
         filenameCount := 0, ParseDisplayName := NumGet(NumGet(pISF+0)+3*A_PtrSize)
         for _, filename in filenames
         {
            DllCall(ParseDisplayName, &quot;Ptr&quot;, pISF, &quot;Ptr&quot;, 0, Ptr, 0, &quot;WStr&quot;, filename, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, &amp;pidl_list+(filenameCount * A_PtrSize), &quot;Ptr&quot;, 0)
            filenameCount++
         }
         if (filenameCount)
         {
            DllCall(NumGet(NumGet(pISF+0)+10*A_PtrSize), &quot;Ptr&quot;, pISF, &quot;Ptr&quot;, 0, &quot;UInt&quot;, filenameCount, &quot;Ptr&quot;, &amp;pidl_list, &quot;Ptr&quot;, &amp;IID_IDataObject, &quot;Ptr&quot;, 0, &quot;Ptr*&quot;, pDataObject) ; GetUIObjectOf
            if (pDataObject)
            {
               DllCall(NumGet(NumGet(pDropTarget+0)+3*A_PtrSize), &quot;Ptr&quot;, pDropTarget, &quot;Ptr&quot;, pDataObject, &quot;UInt&quot;, 0, &quot;Int64&quot;, x | y &lt;&lt; 32, &quot;UInt*&quot;, DragEnter := 1)   ; DragEnter
               if (DragEnter = 0)
                  msgbox Coordinates Error: %x%-%y% 
               DllCall(NumGet(NumGet(pDropTarget+0)+6*A_PtrSize), &quot;Ptr&quot;, pDropTarget, &quot;Ptr&quot;, pDataObject, &quot;UInt&quot;, 0, &quot;Int64&quot;, x | y &lt;&lt; 32, &quot;UInt*&quot;, 1)   ; Drop
               ObjRelease(pDataObject)
            }
            Loop, % filenameCount
            {
               if ((pidl := NumGet(pidl_list, (A_Index - 1) * A_PtrSize, &quot;Ptr&quot;)))
                  DllCall(&quot;ole32\CoTaskMemFree&quot;, &quot;Ptr&quot;, pidl)
            }
         }
         DllCall(&quot;ole32\CoTaskMemFree&quot;, &quot;Ptr&quot;, pidl_dir)
         for _, obj in [pDropTarget, pISF]
            ObjRelease(obj)
         if !(dir = A_Desktop)
            ObjRelease(pDesktop)
      }
   )
}
rThread.Exec(DragAndDropScript1 DragAndDropScript2)
return



InjectAhkDll(PID,dll:=&quot;AutoHotkey64.dll&quot;,script:=0, deleteThread := false)
{
   static PROCESS_ALL_ACCESS:=0x1F0FFF,MEM_COMMIT := 0x1000,MEM_RELEASE:=0x8000,PAGE_EXECUTE_READWRITE:=64
   ,hKernel32:=DllCall(&quot;LoadLibrary&quot;,&quot;Str&quot;,&quot;kernel32.dll&quot;,&quot;PTR&quot;),LoadLibraryA:=DllCall(&quot;GetProcAddress&quot;,&quot;PTR&quot;,hKernel32,&quot;AStr&quot;,&quot;LoadLibraryA&quot;,&quot;PTR&quot;)
   ,FreeLibrary:=DllCall(&quot;GetProcAddress&quot;,&quot;PTR&quot;,hKernel32,&quot;AStr&quot;,&quot;FreeLibrary&quot;,&quot;PTR&quot;)
   ,TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1
   ,MAX_PATH:=260,MAX_MODULE_NAME32:=255,ModuleName:=&quot;&quot;,init:=VarSetCapacity(ModuleName,MAX_PATH*(A_IsUnicode?2:1))
   base:= deleteThread ? {__Call:&quot;InjectAhkDll&quot;,__Delete:&quot;InjectAhkDll&quot;} : {__Call:&quot;InjectAhkDll&quot;}

   if IsObject(PID)
   {
      if (dll!=&quot;Exec&quot; &amp;&amp; script)
         return &quot;Only Exec method can be used here!&quot;

      hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, PROCESS_ALL_ACCESS, &quot;Int&quot;,0, &quot;UInt&quot;, PID.PID,&quot;PTR&quot;)
      if !hProc
         return &quot;Could not open process for PID: &quot; PID.PID

      if (!script) ; Free Library in remote process (object is being deleted)
      {
         ; Terminate the thread in ahkdll
         hThread := DllCall(&quot;CreateRemoteThread&quot;, &quot;PTR&quot;, hProc, &quot;PTR&quot;, 0, &quot;PTR&quot;, 0, &quot;PTR&quot;, PID.ahkTerminate, &quot;PTR&quot;, 0, &quot;UInt&quot;, 0, &quot;PTR&quot;, 0,&quot;PTR&quot;)
         DllCall(&quot;WaitForSingleObject&quot;, &quot;PTR&quot;, hThread, &quot;UInt&quot;, 0xFFFFFFFF)
         ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hThread)

         ; Free library in remote process
         hThread := DllCall(&quot;CreateRemoteThread&quot;, &quot;PTR&quot;, hProc, &quot;UInt&quot;, 0, &quot;UInt&quot;, 0, &quot;PTR&quot;, FreeLibrary, &quot;PTR&quot;, PID.hModule, &quot;UInt&quot;, 0, &quot;UInt&quot;, 0,&quot;PTR&quot;)
         DllCall(&quot;WaitForSingleObject&quot;, &quot;PTR&quot;, hThread, &quot;UInt&quot;, 0xFFFFFFFF)
         ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hThread),DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)
         return
      }

      nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
      ,StrPut(script,&amp;nScript)

      ; Reserve memory in remote process where our script will be saved
      if !pBufferRemote := DllCall(&quot;VirtualAllocEx&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, 0, &quot;PTR&quot;, nScriptLength, &quot;UInt&quot;, MEM_COMMIT, &quot;UInt&quot;, PAGE_EXECUTE_READWRITE, &quot;Ptr&quot;)
         return &quot;Could not reseve memory for process&quot;
      ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)

      ; Write script to remote process memory
      DllCall(&quot;WriteProcessMemory&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, pBufferRemote, &quot;Ptr&quot;, &amp;nScript, &quot;PTR&quot;, nScriptLength, &quot;Ptr&quot;, 0)

      ; Start execution of code
      hThread := DllCall(&quot;CreateRemoteThread&quot;, &quot;PTR&quot;, hProc, &quot;PTR&quot;, 0, &quot;PTR&quot;, 0, &quot;PTR&quot;, PID.ahkExec, &quot;PTR&quot;, pBufferRemote, &quot;UInt&quot;, 0, &quot;PTR&quot;, 0,&quot;PTR&quot;)
      if !hThread
      {
         DllCall(&quot;VirtualFreeEx&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,pBufferRemote,&quot;PTR&quot;,nScriptLength,MEM_RELEASE)
         ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)
         return &quot;Could not execute script in remote process&quot;
      }

      ; Wait for thread to finish
      DllCall(&quot;WaitForSingleObject&quot;, &quot;PTR&quot;, hThread, &quot;UInt&quot;, 0xFFFFFFFF)

      ; Get Exit code returned by ahkExec (1 = script could be executed / 0 = script could not be executed)
      DllCall(&quot;GetExitCodeThread&quot;, &quot;PTR&quot;, hThread, &quot;UIntP&quot;, lpExitCode)
      if !lpExitCode
         return &quot;Could not execute script in remote process&quot;

      DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hThread)
      ,DllCall(&quot;VirtualFreeEx&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,pBufferRemote,&quot;PTR&quot;,nScriptLength,MEM_RELEASE)
      ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)
      return
   }
   else if !hDll:=DllCall(&quot;LoadLibrary&quot;,&quot;Str&quot;,dll,&quot;PTR&quot;)
      return &quot;Could not find &quot; dll &quot; library&quot;, DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)
   else
   {
      hProc := DllCall(&quot;OpenProcess&quot;,&quot;UInt&quot;, PROCESS_ALL_ACCESS, &quot;Int&quot;,0,&quot;UInt&quot;, DllCall(&quot;GetCurrentProcessId&quot;),&quot;PTR&quot;)
      DllCall(&quot;GetModuleFileName&quot;,&quot;PTR&quot;,hDll,&quot;PTR&quot;,&amp;ModuleName,&quot;UInt&quot;,MAX_PATH)
      DllCall(&quot;CloseHandle&quot;,&quot;PTR&quot;,hProc)
   }
   ; Open Process to PID
   hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, PROCESS_ALL_ACCESS, &quot;Int&quot;,0, &quot;UInt&quot;, PID,&quot;PTR&quot;)
   if !hProc
      return &quot;Could not open process for PID: &quot; PID
   
   Loop, Files, %dll%, F
      dll := A_LoopFileLongPath
   ; Reserve some memory and write dll path (ANSI)
   nDirLength := VarSetCapacity(nDir, StrLen(dll)+1, 0)
   ,StrPut(dll,&amp;nDir,&quot;CP0&quot;)

   ; Reserve memory in remote process
   if !pBufferRemote := DllCall(&quot;VirtualAllocEx&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, 0, &quot;PTR&quot;, nDirLength, &quot;UInt&quot;, MEM_COMMIT, &quot;UInt&quot;, PAGE_EXECUTE_READWRITE, &quot;Ptr&quot;)
      return &quot;Could not reseve memory for process&quot;, DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)

   ; Write dll path to remote process memory
   DllCall(&quot;WriteProcessMemory&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, pBufferRemote, &quot;Ptr&quot;, &amp;nDir, &quot;PTR&quot;, nDirLength, &quot;Ptr&quot;, 0)

   ; Start new thread loading our dll

   hThread:=DllCall(&quot;CreateRemoteThread&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,0,&quot;PTR&quot;,0,&quot;PTR&quot;,LoadLibraryA,&quot;PTR&quot;,pBufferRemote,&quot;UInt&quot;,0,&quot;PTR&quot;,0,&quot;PTR&quot;)
   if !hThread
   {
      DllCall(&quot;VirtualFreeEx&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,pBufferRemote,&quot;PTR&quot;,nDirLength,&quot;Uint&quot;,MEM_RELEASE)
      ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)
      return &quot;Could not load &quot; dll &quot; in remote process&quot;
   }
   ; Wait for thread to finish
   DllCall(&quot;WaitForSingleObject&quot;, &quot;PTR&quot;, hThread, &quot;UInt&quot;, 0xFFFFFFFF)

   ; Get Exit code returned by thread (HMODULE for our dll)
   DllCall(&quot;GetExitCodeThread&quot;, &quot;PTR&quot;, hThread, &quot;UInt*&quot;, hModule)

   ; Close Thread
   DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hThread)

   if (A_PtrSize=8)
   { ; use different method to retrieve base address because GetExitCodeThread returns DWORD only
      hModule:=0,VarSetCapacity(me32, (A_PtrSize=8?48:32)+(A_IsUnicode?1032:516), 0) ;W:1080:1064, A:564:548
      ;  Take a snapshot of all modules in the specified process.
      hModuleSnap := DllCall(&quot;CreateToolhelp32Snapshot&quot;,&quot;UInt&quot;, TH32CS_SNAPMODULE,&quot;UInt&quot;, PID, &quot;PTR&quot; )
      if ( hModuleSnap != INVALID_HANDLE_VALUE )
      {
         ; reset hModule and set the size of the structure before using it.
         NumPut((A_PtrSize=8?48:32)+(A_IsUnicode?1032:516), &amp;me32, 0, &quot;UInt&quot;) ;dwSize  ;W:1080:1064, A:564:548
         ;  Retrieve information about the first module,
         ;  and exit if unsuccessful
         if ( !DllCall(&quot;Module32First&quot; (A_IsUnicode?&quot;W&quot;:&quot;&quot;),&quot;PTR&quot;, hModuleSnap,&quot;PTR&quot;, &amp;me32 ) )
         {
            ; Free memory used for passing dll path to remote thread
            DllCall(&quot;VirtualFreeEx&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,pBufferRemote,&quot;PTR&quot;,nDirLength,MEM_RELEASE)
            ,DllCall(&quot;CloseHandle&quot;,&quot;PTR&quot;, hModuleSnap ) ; Must clean up the snapshot object!
            return false
         }
         ;  Now walk the module list of the process,and display information about each module
         while(A_Index=1 || DllCall(&quot;Module32Next&quot; (A_IsUnicode?&quot;W&quot;:&quot;&quot;),&quot;PTR&quot;,hModuleSnap,&quot;PTR&quot;, &amp;me32 ) )
            if (StrGet(&amp;me32+(A_PtrSize=8?48:32)+(A_IsUnicode?512:256))=dll) ;szExePath ;W:560:544, A:304:288
            {
               hModule := NumGet(me32, A_PtrSize=8?40:28, &quot;Ptr&quot;) ;hModule
               break
            }
         DllCall(&quot;CloseHandle&quot;,&quot;PTR&quot;,hModuleSnap) ; clean up
      }
   }

   hDll:=DllCall(&quot;LoadLibrary&quot;,&quot;Str&quot;,dll,&quot;PTR&quot;)

   ; Calculate pointer to ahkdll and ahkExec functions
   ahktextdll:=hModule+DllCall(&quot;GetProcAddress&quot;,&quot;PTR&quot;,hDll,&quot;AStr&quot;,&quot;ahktextdll&quot;,&quot;PTR&quot;)-hDll
   ahkExec:=hModule+DllCall(&quot;GetProcAddress&quot;,&quot;PTR&quot;,hDll,&quot;AStr&quot;,&quot;ahkExec&quot;,&quot;PTR&quot;)-hDll
   ahkTerminate:=hModule+DllCall(&quot;GetProcAddress&quot;,&quot;PTR&quot;,hDll,&quot;AStr&quot;,&quot;ahkTerminate&quot;,&quot;PTR&quot;)-hDll

   if script
   {
      nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
      ,StrPut(script,&amp;nScript)
      ; Reserve memory in remote process where our script will be saved
      if !pBufferScript := DllCall(&quot;VirtualAllocEx&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, 0, &quot;PTR&quot;, nScriptLength, &quot;UInt&quot;, MEM_COMMIT, &quot;UInt&quot;, PAGE_EXECUTE_READWRITE, &quot;Ptr&quot;)
         return &quot;Could not reseve memory for process&quot;
      ,DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)

      ; Write script to remote process memory
      DllCall(&quot;WriteProcessMemory&quot;, &quot;Ptr&quot;, hProc, &quot;Ptr&quot;, pBufferScript, &quot;Ptr&quot;, &amp;nScript, &quot;PTR&quot;, nScriptLength, &quot;Ptr&quot;, 0)
   }
   else
      pBufferScript:=0

   ; Run ahkdll function in remote thread
   hThread := DllCall(&quot;CreateRemoteThread&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,0,&quot;PTR&quot;,0,&quot;PTR&quot;,ahktextdll,&quot;PTR&quot;,pBufferScript,&quot;PTR&quot;,0,&quot;UInt&quot;,0,&quot;PTR&quot;)
   if !hThread
   { ; could not start ahkdll in remote process
      ; Free memory used for passing dll path to remote thread
      DllCall(&quot;VirtualFreeEx&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,pBufferRemote,&quot;PTR&quot;,nDirLength,MEM_RELEASE)
      DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)
      return &quot;Could not start ahkdll in remote process&quot;
   }
   DllCall(&quot;WaitForSingleObject&quot;, &quot;PTR&quot;, hThread, &quot;UInt&quot;, 0xFFFFFFFF)
   DllCall(&quot;GetExitCodeThread&quot;, &quot;PTR&quot;, hThread, &quot;UIntP&quot;, lpExitCode)

   ; Release memory and handles
   DllCall(&quot;VirtualFreeEx&quot;,&quot;PTR&quot;,hProc,&quot;PTR&quot;,pBufferRemote,&quot;PTR&quot;,nDirLength,MEM_RELEASE)
   DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hThread)
   DllCall(&quot;CloseHandle&quot;, &quot;PTR&quot;, hProc)

   if !lpExitCode ; thread could not be created.
      return &quot;Could not create a thread in remote process&quot;

   return {PID:PID,hModule:hModule,ahkExec:ahkExec,ahkTerminate:ahkTerminate,base:base}
}</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=16018">Тема для обсуждения</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Sun, 12 Mar 2023 03:11:38 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=157104#p157104</guid>
		</item>
	</channel>
</rss>
