notepad get/set path (get/set text file path)

Post your working scripts, libraries and tools for AHK v1.1 and older
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

Re: notepad get/set path (get/set text file path)

18 Jul 2018, 17:25

Hi jeeswg,

Thank you for the great functions. I found a way to simplify the GetPath function and make it run significantly faster (~100 times). Here it is:

Code: Select all

F3::MsgBox % GetNotepadWinPath(WinExist("A"))

GetNotepadWinPath(hwnd) {
   static MAX_PATH := 260
   WinGetClass, Class, ahk_id %hwnd%
   WinGet, PID, PID, ahk_id %hwnd%
   hProc := DllCall("OpenProcess", "UInt", 0x410, "Int", 0, "UInt", PID, "Ptr")  ; PROCESS_QUERY_INFORMATION (0x400) | PROCESS_VM_READ (0x010)
   if !(Class = "Notepad" && hProc)
      Return
   DllCall("IsWow64Process", "Ptr", hProc, "IntP", IsWow64Process)
   BaseAddress := DllCall(A_PtrSize = 4  ? "GetWindowLong" : "GetWindowLongPtr", "Ptr", hwnd, "Int", -6, "Ptr")  ; GWLP_HINSTANCE = -6
   Address := !A_Is64bitOS || IsWow64Process ? BaseAddress + 0xCAE0 : BaseAddress + 0x10B40
   VarSetCapacity(Path, MAX_PATH*2, 0)
   DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", Address, "Str", Path, "UPtr", MAX_PATH*2, "UPtr", 0)
   DllCall("CloseHandle", "Ptr", hProc)
   Return Path
}
Cheers!

- iPhilip

EDIT: Changed the function so that it now works with both Notepad x32 and x64 on Windows 7.
Last edited by iPhilip on 18 Jul 2018, 20:59, edited 1 time in total.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: notepad get/set path (get/set text file path)

18 Jul 2018, 18:05

- This is great, thanks very much for sharing. So GWLP_HINSTANCE points to the application in the address space I suppose. Any background details about what led you to this discovery? And also, which OSes have you tested it on?
- This worked for me on Notepad x64 on Windows 7. Although it didn't work for me on Notepad x32 on Windows 7, or on a copy of Notepad x32 Windows XP version on Windows 7. I suppose though that GWLP_HINSTANCE might be able to speed up my current script anyhow, if it points you to the first address space regions to try. Thanks again.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

Re: notepad get/set path (get/set text file path)

18 Jul 2018, 18:46

jeeswg wrote:- This is great, thanks very much for sharing. So GWLP_HINSTANCE points to the application in the address space I suppose. Any background details about what led you to this discovery? And also, which OSes have you tested it on?
I was inspired by looking at the getProcessBaseAddress() method from RHCP's classMemory class. You can find it here.
jeeswg wrote:- This worked for me on Notepad x64 on Windows 7. Although it didn't work for me on Notepad x32 on Windows 7, or on a copy of Notepad x32 Windows XP version on Windows 7. I suppose though that GWLP_HINSTANCE might be able to speed up my current script anyhow, if it points you to the first address space regions to try. Thanks again.
I only tested it on Windows 7 with Notepad x64. If you can make it work with Notepad x32, it would be great. I am less interested in Windows XP as it's disappearing.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

Re: notepad get/set path (get/set text file path)

18 Jul 2018, 21:02

Hi jeeswg,

I updated the above post with a slightly modified function that now works with both Notepad x32 and x64 on Windows 7.

- iPhilip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: notepad get/set path (get/set text file path)

18 Jul 2018, 21:45

- Thanks for the insight.
- Your update now works on Notepad Windows 7 x64/x32 for me also. Although not on Notepad Windows XP x32, I will investigate.
- I see that you've made one change:
Before: PROCESS_VM_READ
After: PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
- It seems that on both AHK x64/x32, PROCESS_VM_READ was enough to work on Notepad x64, but PROCESS_QUERY_INFORMATION was also needed to work on Notepad x32.
- And yes, I did some benchmark tests, and the new function is around 75 to 100 times faster. (Although using the old function still seemed almost instant to me, I hope it didn't seem noticeably slow to anyone.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

Re: notepad get/set path (get/set text file path)

18 Jul 2018, 22:10

Hi jeeswg,

All your observations are correct. The old function didn't seem slow to me. I just did the speed tests to see if there was an advantage from that perspective.

Thank you for the work you did on these functions. I learned a lot from studying them as well as messing around with Process Hacker. :P

- iPhilip
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
omareg94
Posts: 94
Joined: 27 Jun 2016, 22:46

Re: notepad get/set path (get/set text file path)

21 Jan 2020, 19:17

I have tested it on Windows 10 x64, unfortunately it's not working.
It doesn't get the file path, just an empty string.
omareg94
Posts: 94
Joined: 27 Jun 2016, 22:46

Re: notepad get/set path (get/set text file path)

22 Jan 2020, 14:28

iPhilip wrote:
18 Jul 2018, 17:25
I found a way to simplify the GetPath function and make it run significantly faster (~100 times).
EDIT: Changed the function so that it now works with both Notepad x32 and x64 on Windows 7.
Hello @iPhilip and @jeeswg

Does this function work consistently when multiple windows of notepad are open?
I'm trying to understand the code to make it work for Windows 10.
I have played with the code a little to make it give me the file path of the notepad active window (This doesn't work yet as expected).
Also two lines are added to display some variables most important the BaseAddress and Address.

Code: Select all

q::
hWnd := WinActive("ahk_class Notepad") ; get active window's id and store within hWnd
MsgBox, % GetNotepadWinPath(hWnd)
return

GetNotepadWinPath(hwnd) {
   static MAX_PATH := 260
   WinGetClass, Class, ahk_id %hwnd%
   WinGet, PID, PID, ahk_id %hwnd%   
   hProc := DllCall("OpenProcess", "UInt", 0x410, "Int", 0, "UInt", PID, "Ptr")  ; PROCESS_QUERY_INFORMATION (0x400) | PROCESS_VM_READ (0x010)

   MsgBox, % "Process ID: " PID "`nProcess Start Path: " vPPath "`nWindow id: " hWnd "`nhProc: " hProc  ; display (PID, vPPath, hWnd, hProc) for debugging purposes

   if !(Class = "Notepad" && hProc)
      Return
   DllCall("IsWow64Process", "Ptr", hProc, "IntP", IsWow64Process)
   BaseAddress := DllCall(A_PtrSize = 4     ; If DLL call fails, returned value will = 0
            ? "GetWindowLong"
            : "GetWindowLongPtr"
            , "Ptr", hWnd, "Int", -6, A_Is64bitOS ? "Int64" : "UInt") ; GWLP_HINSTANCE = -6
   Address := !A_Is64bitOS || IsWow64Process ? BaseAddress + 0xCAE0 : BaseAddress + 0x10B40
   
   MsgBox, % "BaseAddress: " Format("{1:#x}",BaseAddress) "`nAddress: " Format("{1:#x}",Address) ; display (BaseAddress, Address) for debugging purposes
   
   VarSetCapacity(Path, MAX_PATH*2, 0)
   DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", Address, "Str", Path, "UPtr", MAX_PATH*2, "UPtr", 0)
   DllCall("CloseHandle", "Ptr", hProc)
   Return Path
}
I always get the same BaseAddress and Address whatever was the active window.
So I think that this approach will not work well to get file paths of different notepad windows.
I'm still a little confused if I will be able to get some BaseAddress that's related to the active window itself and see some constant offset where the file path is stored in.

All the best
Omar

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: gwarble and 255 guests