Handle Tool & split CMD Output Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Handle Tool & split CMD Output

08 Aug 2016, 15:17

Hi,
Actually I have few questions, answering any one will help me with my next step.

I'm trying to monitor a specific folder for any changes, and i'm thinking about the action if the folder has modified.
one of the action is detect the process who causes the change in that folder and kill it, found the tool from MS Handle.exe. Trying to use it in CMD

Code: Select all

handle.exe "d:\Monitored Folder"
The output like:

Code: Select all

explorer.exe       pid: 4044   type: File           F78: D:\Monitored Folder
explorer.exe       pid: 4044   type: File          10F0: D:\Monitored Folder
AM Hotkeys.exe     pid: 964    type: File             C: D:\Monitored Folder
- How can I take only the process name or the PID from each line? so I can use it later to kill the process.
- Is there anything in AHK like this tool that I can use to know which process made the changes?
Or maybe some one knows something like that out of AHK i can try to use it in my AHK script?

I have the tool in path that has spaces, I couldn't figure out why it doesn't work even if I use quotes "Program Files" in AHK (in batch it works)
It is in C:\Program Files\Tools\Handle.exe
I'm doing like:

Code: Select all

Run %comspec% /k "%A_ProgramFiles%\Tools\Handle.exe" "D:\Monitored Folder" > D:\log.log
- It is not possible to use long line of CMD after %comspec% ? Or what am i doing wrong?

Any help or suggestion will be appreciated.

Thank you
Rami
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output  Topic is solved

08 Aug 2016, 15:56

Untested, since I don't have Handle.exe

Code: Select all

#Include <StdOutToVar>

MsgBox, % """" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""

StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder""", "Handle")

#s::ExitApp

Handle(output, index){
	RegExMatch(output, "(?<=pid: )\d+", pID)
	Process, Close, %pID%
}
You will need StdOutToVar by Sean (Slightly modified by me, works on both 32 and 64 bit).

Code: Select all

StdOutStream(sCmd, Callback = "") {   	; Modified  :  SKAN 31-Aug-2013 http://goo.gl/j8XJXY                             
	Static StrGet := "StrGet"           ; Thanks to :  HotKeyIt         http://goo.gl/IsH1zs                                   
									    ; Original  :  Sean 20-Feb-2007 http://goo.gl/mxCdn
									  
	DllCall("CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0)
	DllCall("SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1)

	VarSetCapacity(STARTUPINFO, A_Is64bitOS ? 104 : 68,  0)     ; STARTUPINFO          ;  http://goo.gl/fZf24
	NumPut(68,         STARTUPINFO,  0)      					; cbSize
	NumPut(0x100,      STARTUPINFO, A_Is64bitOS ? 60 : 44)      ; dwFlags    =>  STARTF_USESTDHANDLES = 0x100 
	NumPut(hPipeWrite, STARTUPINFO, A_Is64bitOS ? 88 : 60)      ; hStdOutput
	NumPut(hPipeWrite, STARTUPINFO, A_Is64bitOS ? 96 : 64)      ; hStdError

	VarSetCapacity(PROCESS_INFORMATION, A_Is64bitOS ? 32 : 16)  ; PROCESS_INFORMATION  ;  http://goo.gl/b9BaI      

	If(!DllCall("CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ;  http://goo.gl/USC5a
			  , UInt,1, UInt,0x08000000, UInt,0, UInt,0
			  , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION)){
		Return ""
		, DllCall("CloseHandle", UInt,hPipeWrite)
		, DllCall("CloseHandle", UInt,hPipeRead)
		, DllCall("SetLastError", Int,-1)
	}

	hProcess := NumGet(PROCESS_INFORMATION, 0)
	hThread  := NumGet(PROCESS_INFORMATION, A_Is64bitOS ? 8 : 4)

	DllCall("CloseHandle", UInt,hPipeWrite)

	AIC := (SubStr(A_AhkVersion, 1, 3) = "1.0") ;  A_IsClassic
	VarSetCapacity(Buffer, 4096, 0), nSz := 0 
	
	While DllCall("ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, Int,0) {
		tOutput := (AIC && NumPut(0, Buffer, nSz, "Char") && VarSetCapacity(Buffer, -1)) ? Buffer : %StrGet%(&Buffer, nSz, "CP850")

		Isfunc(Callback) ? %Callback%(tOutput, A_Index) : sOutput .= tOutput
	}
	DllCall("GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode)
	DllCall("CloseHandle",  UInt,hProcess)
	DllCall("CloseHandle",  UInt,hThread)
	DllCall("CloseHandle",  UInt,hPipeRead)
	DllCall("SetLastError", UInt,ExitCode)
	
	Return Isfunc(Callback) ? %Callback%("", 0) : sOutput      
}
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 07:39

Thank you for your response , I will test that in few ...
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 08:47

I'm still very new to AHK, so I apologize if there will be any crazy questions :) very new to the level that i just figured out (and still not 100% sure) that to use function i have to write it at the beginning of my script :crazy:
Seems it's working for me using your code with my code, noted that i deleted the line: #Include <StdOutToVar> because it was giving me an error on this line, Is that OK ?

Whole my script is silent, so how can I get rid of MsgBox? but keeping the detection and ending process functions.
One more question for later, how can i use
Run %comspec% /k instead of MsgBox in the following example that you provided:

Code: Select all

MsgBox, % """" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""
I tried:

Code: Select all

Run %comspec% /k % """" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""
The AHK error is: This Parameter contains a variable name missing its ending percent sign.
I tried:

Code: Select all

Run %comspec% /k """" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""
The error in CMD window says: The system cannot find the path specified. (the same error i had before)

Thank you again ,
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 09:17

You can just delete the MsgBox line, it is only to verify that the path and command is formatted correctly.

You can write the line in these two ways.

Code: Select all

Run % comspec " /k" """" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder""" ; using Expression syntax, after having forced it to use Expression syntax by starting the parameter with %
or

Code: Select all

Run %comspec% /k "%A_ProgramFiles%\Tools\Handle.exe" "D:\Monitored Folder" ; using Command syntax
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 09:24

unfortunately, both are giving one of the CMD error that i was getting,
seems it reads it without ""
Capture.JPG
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 09:29

Rami wrote: Seems it's working for me using your code with my code, noted that i deleted the line: #Include <StdOutToVar> because it was giving me an error on this line, Is that OK ?
I think I was editing my post while you were answering, is it OK to delete the above line?

One more questions please, should i keep this: #s::ExitApp? why it is before the closing process? is there any concept of that?
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 09:36

as long as you have included the function StdOutStream manually it is fine.
Please excuse my spelling I am dyslexic.
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 09:38

As long as you have included the function StdOutStream manually it is fine.

Code: Select all

MsgBox, % comspec " /k """ A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""
MsgBox, %comspec% /k "%A_ProgramFiles%\Tools\Handle.exe" "D:\Monitored Folder"
there was an error in the expression it was missing a space, but it will probably not solve your problem.
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 10:08

Capn Odin wrote:

Code: Select all

MsgBox, % comspec " /k """ A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""
MsgBox, %comspec% /k "%A_ProgramFiles%\Tools\Handle.exe" "D:\Monitored Folder"
there was an error in the expression it was missing a space, but it will probably not solve your problem.
No, it didn't. the same error that 'C:\Program' is not recognized as an internal or external command.
I will change the actual path to one without spaces then change it in my script :)

I marked your answer as a correct answer for my question. Because i tried it alone and it worked for me, but i'm not having any luck now including it in my script ...
I was wondering if you could please show me how it should look like after including everything. I mentioned where did i included your codes, after including them the process was not killed, plus was repeatedly getting the msgbox that the folder has been modified every 5 seconds.
My script (monitor every 5 second MonitoredFolder for any modify) and notify me once before changing the modify time to the new one.
Spoiler
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 11:01

FYI I just tried adding msgboxES to check where is the problem:

Code: Select all

Handle(output, index){
	RegExMatch(output, "(?<=pid: )\d+", pID)
	msgbox, %pID%
	Process, Close, %pID%
I'm getting blank msg ... I think this is why it doesn't work in my script.
Any idea why it is blank msg?
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 13:25

Can you describe a run of Handle.exe, for instance does it print the processes as they tamper with the folder ? or just return the last process that tampered and then terminate it self ?
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 13:46

Handle is a utility that displays information about open handles for any process in the system. You can use it to see the programs that have a file open, or to see the object types and names of all the handles of a program
https://technet.microsoft.com/en-us/sys ... andle.aspx

As Example, if I use custom Windows wallpaper from folder on my D drive \Wallpaper , then I run:

Code: Select all

handle.exe "D:\wallpaper" 
It will return result:
1.JPG
2 Explorer because one for Windows background , another because I'm open the folder Wallpaper in my explorer.

Example2: If I run this command on D:\PST folder that is not in use It will return:

Code: Select all

D:\>handle64.exe d:\pst

Nthandle v4.1 - Handle viewer
Copyright (C) 1997-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

No matching handles found.
But the result could be any antivirus process if that antivirus is scanning the PST folder right now.

So, my concept of using this tool is to detect who is modifying my specific folder\sub-folders and kill its process.
I could create monitor through AHK with many helps from this forum to monitor my folder, but unfortunately I don't have AHK knowledge (if it is possible) to do what this tool does.
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 14:03

Code: Select all

#Persistent
#SingleInstance, force
#NoEnv

#Include StdOutToVar.ahk

; *** Force to run as Administrator ***

if(!A_IsAdmin){
	Run *RunAs "%A_ScriptFullPath%"
	ExitApp
}

intro:="
(
Version : MonitoredFolder

Author : Me

Function: Monitors [$.MonitoredFolder] directory for changes. When any change happens,
the program tries to find the process who caused that and kills it.
)"

;menu,tray,NoStandard
menu,tray,add,About...,about
;menu,tray,add,Exit,exit

; *** MONITORING ***
Loop, C:\Users\%A_UserName%\$.MonitoredFolder\*.*, , 1
	FolderTimeModified += %A_LoopFileTimeModified%

DoThis:
	Folder2TimeModified = 0
	Loop, C:\Users\%A_UserName%\$.MonitoredFolder\*.*, , 1
		Folder2TimeModified += %A_LoopFileTimeModified%
	if(Folder2TimeModified != FolderTimeModified){
		Process, priority, , RealTime
		SoundPlay, %A_WinDir%\Media\ding.wav
		SoundPlay *16
		MsgBox,16, WARNING!, WARNING!`n "$.MonitoredFolder" Folder has been modified.,3
		
		processes := StrSplit(StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""), "`n")
		for index, process in processes {
			RegExMatch(process, "(?<=pid: )\d+", pID)
			if(pID){
				Process, Close, %pID%
			}
		}
		
		FolderTimeModified = 0
		Loop, C:\Users\%A_UserName%\$.MonitoredFolder\*.*, , 1
		FolderTimeModified += %A_LoopFileTimeModified%
	}

	SetTimer , DoThis, 5000
return

exit:
	exitapp

about:
	gui,2:Destroy
	gui,2:add,link,,%intro%
	gui,2:show,,About
return 
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 14:30

I really appreciate your time with me. It didn't work as we're expecting.

I changed the line:
processes := StrSplit(StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""), "`n")
into:
processes := StrSplit(StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""C:\Users\A_UserName\$.MonitoredFolder"""), "`n")

Then I added MsgBox after the RegExMatch function. But I get the msgbox like 5 times empty :(
that why it doesn't continue into Process Close.

Spoiler
Then i added sleep 5 second before the End of IF to read the script after making changes in my monitored folder.
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 14:41

Try changing this line

Code: Select all

processes := StrSplit(StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder"""), "`n")
to

Code: Select all

MsgBox, % StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""D:\Monitored Folder""")
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 14:50

Capn Odin wrote:Try changing this line

Code: Select all

processes := StrSplit(StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""C:\Users\A_UserName\$.MonitoredFolder"""), "`n")
to

Code: Select all

MsgBox, % StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" ""C:\Users\A_UserName\$.MonitoredFolder""")
Edit: *The changes that i made is open the folder through explorer and delete couple files in it.
I got the following message:
Untitled.png
Untitled.png (16.93 KiB) Viewed 2988 times
noted that in CMD at the same time i got this result:
2.JPG
2.JPG (18.07 KiB) Viewed 2988 times
*
And here is the script: (Temp.ahk)
Spoiler
User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: Handle Tool & split CMD Output

09 Aug 2016, 15:29

This works for me.

Code: Select all

#Include StdOutToVar.ahk ; <StdOutToVar>

#s::
	processes := StrSplit(StdOutStream("""" A_ProgramFiles "\Tools\Handle.exe"" """ A_Desktop """"), "`n"), Pros := ""
	; processes := StrSplit(StdOutStream("""" A_ScriptDir "\handle.exe"" """ A_Desktop """"), "`n"), Pros := ""
	for index, process in processes {
		RegExMatch(process, "(?<=pid: )\d+", pID)
		if(pID){
			Pros .= pID " - " process
		}
	}
	MsgBox, % Pros
return
Please excuse my spelling I am dyslexic.
Rami
Posts: 55
Joined: 19 May 2016, 07:44

Re: Handle Tool & split CMD Output

09 Aug 2016, 15:47

On the Desktop it worked for me too :)
I really appreciate your time with me today. I will test everything again tomorrow (with killing the processes) based on last one since this one worked.
Thank you again Capn Odin!!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: boydfields and 152 guests