Page 1 of 1

Handle Tool & split CMD Output

Posted: 08 Aug 2016, 15:17
by Rami
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

Re: Handle Tool & split CMD Output  Topic is solved

Posted: 08 Aug 2016, 15:56
by Capn Odin
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      
}

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 07:39
by Rami
Thank you for your response , I will test that in few ...

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 08:47
by Rami
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 ,

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 09:17
by Capn Odin
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

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 09:24
by Rami
unfortunately, both are giving one of the CMD error that i was getting,
seems it reads it without ""
Capture.JPG

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 09:29
by Rami
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?

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 09:36
by Capn Odin
as long as you have included the function StdOutStream manually it is fine.

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 09:38
by Capn Odin
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.

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 10:08
by Rami
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

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 11:01
by Rami
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?

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 13:25
by Capn Odin
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 ?

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 13:46
by Rami
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.

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 14:03
by Capn Odin

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 

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 14:30
by Rami
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.

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 14:41
by Capn Odin
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""")

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 14:50
by Rami
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 3011 times
noted that in CMD at the same time i got this result:
2.JPG
2.JPG (18.07 KiB) Viewed 3011 times
*
And here is the script: (Temp.ahk)
Spoiler

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 15:29
by Capn Odin
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

Re: Handle Tool & split CMD Output

Posted: 09 Aug 2016, 15:47
by Rami
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!!