Old 7th June 2014, 15:19   #1
r2du-soft
Senior Member
 
r2du-soft's Avatar
 
Join Date: Nov 2013
Location: Iran
Posts: 342
Question send y key to a process

hi
how can send "y" key to a process?
thanks
r2du-soft is offline   Reply With Quote
Old 7th June 2014, 16:18   #2
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,270
You cannot send keyboard events to a process, you can send them to the top level window by calling SendInput or keybd_event with the system plugin.

You can try to fake the messages if you need to send to a specific window by sending WM_KEYDOWN/UP messages.

I hope you are not trying to click Yes in some security dialog because that is evil. And what if the language is not English?

If you are doing a lot of automation you can try AutoIt or something like that.

What is the actual goal? Which application are you controlling and can it be done in a different way that does not involve sending fake input?

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 7th June 2014, 21:01   #3
r2du-soft
Senior Member
 
r2du-soft's Avatar
 
Join Date: Nov 2013
Location: Iran
Posts: 342
Question

Quote:
Originally Posted by Anders View Post
You cannot send keyboard events to a process, you can send them to the top level window by calling SendInput or keybd_event with the system plugin.

You can try to fake the messages if you need to send to a specific window by sending WM_KEYDOWN/UP messages.

I hope you are not trying to click Yes in some security dialog because that is evil. And what if the language is not English?

If you are doing a lot of automation you can try AutoIt or something like that.

What is the actual goal? Which application are you controlling and can it be done in a different way that does not involve sending fake input?
thanks
The real target is this question This is:
i after close a process need to (send y key) OR (send left arrow and after that send enter key) for confirmation stages exit.

i use this code with cmd:

HTML Code:
@if (@CodeSection == @Batch) @then

@echo off &setlocal

set "process=Project1.exe"

for /f "tokens=2" %%i in ('tasklist /nh /fi "imagename eq %process%" 2^>nul') do set PID1=%%i
taskkill /pid %PID1% /t
timeout /T 2
cscript //nologo //E:JScript "%~F0"
goto :EOF
@end

var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.AppActivate("Student Register");
WshShell.SendKeys("Y");

but i need now write this code and use in nsis
There was no way for a send key to process or active a windows and send key to that?
r2du-soft is offline   Reply With Quote
Old 7th June 2014, 23:10   #4
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,270
Quote:
!include LogicLib.nsh
!include Win\COM.nsh
!include Win\PropKey.nsh
/*
72c24dd5-d70a-438b-8a42-98424b88afb8 CLSID_WshShell
F935DC21-1CF0-11d0-ADB9-00C04FD58A0B IWshShell
24BE5A30-EDFE-11d2-B933-00104B365C9F IWshShell2
41904400-BE18-11d3-A28B-00104BD35090 IWshShell3
*/
${NSISCOMIFACEDECL}IWshShell2 AppActivate 17 (i,i,*i)i
${NSISCOMIFACEDECL}IWshShell2 SendKeys 18 (i,i)i
System::Call 'OLE32::CLSIDFromProgID(w "WScript.Shell",g.r1)i.r0'
!insertmacro ComHlpr_CreateInProcInstance $1 "{24BE5A30-EDFE-11d2-B933-00104B365C9F}" r0 ""
${If} $0 <> 0
System::Call 'OLEAUT32::SysAllocString(w "Calculator")i.r9'
System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BSTR},,ir9)i.r1'
System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BOOL},,${VARIANT_TRUE})i.r2'
StrCpy $5 0
startedapp:
${IWshShell2::AppActivate} $0 '(r1,r2,${VARIANT_FALSE}r3)i.r4'
${If} $3 <> ${VARIANT_FALSE}
${AndIf} $4 = 0
System::Call 'OLEAUT32::SysFreeString(ir9)'
System::Call 'OLEAUT32::SysAllocString(w "1 + 2 =")i.r9' ; Do some calculation
${IWshShell2::SendKeys} $0 '(r9,r2)i.r4'
${Else}
Exec calc.exe
Sleep 1111
IntOp $5 $5 + 1
IntCmpU $5 1 "" "" +2
goto startedapp
${EndIf}
System::Call 'OLEAUT32::SysFreeString(ir9)'
System::Free $2
System::Free $1
${IUnknown::Release} $0 ""
${EndIf}
but NSIS is not the best UI automation tool, you should try AutoIt or some other tool...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 8th June 2014, 09:00   #5
r2du-soft
Senior Member
 
r2du-soft's Avatar
 
Join Date: Nov 2013
Location: Iran
Posts: 342
Question

Quote:
Originally Posted by Anders View Post
but NSIS is not the best UI automation tool, you should try AutoIt or some other tool...
thanks Anders
i know NSIS is not the best UI automation tool,but i forced use that

when compile,nsis compiler Getting error for this line:

code:

System::Call 'OLE32::CLSIDFromProgID(w "WScript.Shell",g.r1)i.r0'



what Getting error?
And this code that you contract for me send to "y" a process? Or other work doing?
thanks
r2du-soft is offline   Reply With Quote
Old 8th June 2014, 12:06   #6
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,270
Quote:
Originally Posted by r2du-soft View Post
when compile,nsis compiler Getting error for this line:
what Getting error?
How am I supposed to know when you don't say what the compiler error is?


Change
Quote:
System::Call 'OLE32::CLSIDFromProgID(w "WScript.Shell",g.r1)i.r0'
!insertmacro ComHlpr_CreateInProcInstance $1 "{24BE5A30-EDFE-11d2-B933-00104B365C9F}" r0 ""
to
Quote:
!insertmacro ComHlpr_CreateInProcInstance "{72c24dd5-d70a-438b-8a42-98424b88afb8}" "{24BE5A30-EDFE-11d2-B933-00104B365C9F}" r0 ""
Quote:
Originally Posted by r2du-soft View Post
And this code that you contract for me send to "y" a process?
I don't know how many times I need to say this, you cannot send keys to a process! Simulated input will go to a thread and a thread can have multiple windows but it will most likely be handled by the foreground window.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 8th June 2014, 13:31   #7
r2du-soft
Senior Member
 
r2du-soft's Avatar
 
Join Date: Nov 2013
Location: Iran
Posts: 342
Question

Quote:
Originally Posted by Anders View Post
How am I supposed to know when you don't say what the compiler error is?


Change

to


I don't know how many times I need to say this, you cannot send keys to a process! Simulated input will go to a thread and a thread can have multiple windows but it will most likely be handled by the foreground window.
thanks
problem fixed
but i have another question:
in this code for send nuber12 in calculator , what line send number 12 ?
how can this number 12 to another numbers (13,14,15) ?
thanks
r2du-soft is offline   Reply With Quote
Old 8th June 2014, 15:16   #8
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,270
It sends "1", "+", "2" and "=" and you should end up with 3. SysAllocString creates it and SendKeys sends it...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 20th April 2016, 07:54   #9
r2du-soft
Senior Member
 
r2du-soft's Avatar
 
Join Date: Nov 2013
Location: Iran
Posts: 342
Thanks for helping
Often i have a problem with this codes:


HTML Code:
;--------------------------------
!include "Win\COM.nsh"
!include "Win\PropKey.nsh"
!include "LogicLib.nsh"
;--------------------------------

;----------
Var Handle1
Var Handle2
Var GetForegroundWindow_hwnd
#--------------


Section

MessageBox MB_YESNO|MB_TOPMOST|MB_SETFOREGROUND|MB_ICONEXCLAMATION "Return?" IDYES true IDNO false

true:

	CheckAgainWindow:
	Sleep 1000
	;------------
	;Sleep 500
	FindWindow $Handle1 "CalcFrame" ""
	SendMessage $Handle1 0x0010 0 0
	;------------
	Sleep 1000
	;------------
	Exec "Calc.exe"
	;------------
	Sleep 1000
	;------------
	FindWindow $Handle2 "CalcFrame" ""
	Sleep 500
	System::Call 'user32::SetForegroundWindow(i $Handle2)'
	;------------
	Sleep 1000
	;------------
	System::Call user32::GetForegroundWindow('')i.r0
	StrCpy $GetForegroundWindow_hwnd $0
	;------------
	Sleep 1000
	;------------
	StrCmp $Handle2 $GetForegroundWindow_hwnd ContinueWindow CheckAgainWindow 
	#--------------------------
	

	ContinueWindow:
	
	${NSISCOMIFACEDECL}IWshShell2 AppActivate 17 (i,i,*i)i
	${NSISCOMIFACEDECL}IWshShell2 SendKeys 18 (i,i)i
	;System::Call 'OLE32::CLSIDFromProgID(w "WScript.Shell",g.r1)i.r0'
	;!insertmacro ComHlpr_CreateInProcInstance $1 "{24BE5A30-EDFE-11d2-B933-00104B365C9F}" r0 ""
	!insertmacro ComHlpr_CreateInProcInstance "{72c24dd5-d70a-438b-8a42-98424b88afb8}" "{24BE5A30-EDFE-11d2-B933-00104B365C9F}" r0 "" 
${If} $0 <> 0
		System::Call 'OLEAUT32::SysAllocString(w "Calculator")i.r9'
		System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BSTR},,ir9)i.r1'
		System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BOOL},,${VARIANT_TRUE})i.r2'
		StrCpy $5 0
		startedapp:
		${IWshShell2::AppActivate} $0 '(r1,r2,${VARIANT_FALSE}r3)i.r4'
	${If} $3 <> ${VARIANT_FALSE}
	${AndIf} $4 = 0
		;-------------------------------------------------------------------------
		System::Call 'OLEAUT32::SysFreeString(ir9)'
		System::Call 'OLEAUT32::SysAllocString(w "1 + 2 =")i.r9'
		${IWshShell2::SendKeys} $0 '(r9,r2)i.r4'
		;------------
		Sleep 2000
		;------------
		System::Call 'OLEAUT32::SysFreeString(ir9)'
		System::Call 'OLEAUT32::SysAllocString(w "{DEL}")i.r9'
		${IWshShell2::SendKeys} $0 '(r9,r2)i.r4'
		;------------
		Sleep 1000
		;------------
		System::Call 'OLEAUT32::SysFreeString(ir9)'
		System::Call 'OLEAUT32::SysAllocString(w "3 + 4 =")i.r9'
		${IWshShell2::SendKeys} $0 '(r9,r2)i.r4'
		;-------------------------------------------------------------------------
	${Else}
		Exec calc.exe
		Sleep 1111
		IntOp $5 $5 + 1
		IntCmpU $5 1 "" "" +2
		goto startedapp
	${EndIf}
System::Call 'OLEAUT32::SysFreeString(ir9)'
System::Free $2
System::Free $1
${IUnknown::Release} $0 ""
${EndIf}
	##----------------------------------

false:

SectionEnd


When i use from code MessageBox at the beginning of the program,some times calculator crashed and show me Close the program and some times no send any key to calculator!

and i have another problem:
i try to fix that but i did not succeed...
i want send

i send 1 + 2 = to calculator and after sleep 2 Sec delete that and send 3 + 4 = to calculator but after run app just see 34 in calculator and i didn't see 12 !!
how can fix that?

Except this method to send key i can send key with System::Call ???
before that you say can send key with keybd_event() and SendInput() , is possible give me a example from keybd_event() and SendInput() for send key?
Thanks
r2du-soft is offline   Reply With Quote
Old 20th April 2016, 17:06   #10
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,270
All of this just goes to show how hard it is to do UI automation. My old example might be a bit broken because some versions of Calculator seems to interpret space as some operation.

Here is a better version (NSIS v3):
PHP Code:
!include LogicLib.nsh
!include Win\COM.nsh
!include Win\PropKey.nsh
!define /IfNDef CLSID_WshShell {72c24dd5-d70a-438b-8a42-98424b88afb8}
!
define /IfNDef IID_IWshShell2 {24BE5A30-EDFE-11d2-B933-00104B365C9F}
${
NSISCOMIFACEDECL}IWshShell2 AppActivate 17 (p,p,*i); (VARIANT*titlebeginswith,VARIANT*wait,VARIANT_BOOL*success)
${
NSISCOMIFACEDECL}IWshShell2 SendKeys 18 (p,p); (BSTR,VARIANT*wait//technet.microsoft.com/en-us/library/ee156592.aspx#Sending Keystrokes to a Program

Function SendKeysToApp
System
::Store S
Pop $R1 
Keys
Pop $R2 
App
!insertmacro ComHlpr_CreateInProcInstance "${CLSID_WshShell}" "${IID_IWshShell2}r0 ""
${If} $0 P<> 0
    System
::Call 'OLEAUT32::SysAllocString(w R2)i.r9'
    
System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BSTR},,ir9)i.r1' 
    
System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BOOL},,${VARIANT_TRUE})i.r2'
    
${IWshShell2::AppActivate} $'(r1,r2,${VARIANT_FALSE}r3)i.r4'
    
System::Call 'OLEAUT32::SysFreeString(ir9)'
    
DetailPrint "DEBUG: AppActivate($R2): hr=$4 success=$3"
    
${If} $>= 0
    
${AndIf} $<> ${VARIANT_FALSE}
        
System::Call 'OLEAUT32::SysAllocString(w R1)i.r9'
        
${IWshShell2::SendKeys} $'(r9,r2)i.r4'
        
System::Call 'OLEAUT32::SysFreeString(ir9)'
        
DetailPrint "DEBUG: SendKeys($R1) hr=$4"
    
${EndIf}
    
System::Free $2
    System
::Free $1
    
${IUnknown::Release} $""
${EndIf}
System::Store L
FunctionEnd

Function ActivateOrStart
System
::Store S
Pop $R1 
Cmd
Pop $R2 
App
!insertmacro ComHlpr_CreateInProcInstance "${CLSID_WshShell}" "${IID_IWshShell2}r0 ""
${If} $0 P<> 0
retryFind
:
    
System::Call 'OLEAUT32::SysAllocString(w R2)i.r9'
    
System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BSTR},,ir9)i.r1' 
    
System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BOOL},,${VARIANT_FALSE})i.r2'
    
${IWshShell2::AppActivate} $'(r1,r2,${VARIANT_FALSE}r3)i.r4'
    
System::Call 'OLEAUT32::SysFreeString(ir9)'
    
System::Free $2
    System
::Free $1
    
${If} $>= 0
    
${AndIf} $= ${VARIANT_FALSE}
        ${If} 
$R1 != ""
            
Exec '$R1'
            
StrCpy $R1 ""
        
${EndIf}
        
Sleep 1000
        
Goto retryFind TODOIt might be a good idea to give up after 20 seconds or so?
    ${EndIf}
    ${
IUnknown::Release} $""
${EndIf}
System::Store L
FunctionEnd


Section
Push 
"Calculator"
Push '"Calc.exe"'
Call ActivateOrStart

Push 
"Calculator"
Push "1{+}2="
Call SendKeysToApp

Sleep 1555
Push 
"Calculator"
Push "{DEL}"
Call SendKeysToApp Send DEL to reset the Calculator is not really required but I'm doing it anyway here

Sleep 1555
Push "Calculator"
Push "4*4="
Call SendKeysToApp
SectionEnd 
Using keybd_event or SendInput is a bit more complicated and I'm not going to even try before you tell us what you are actually trying to do. Performing calculations in Calculator is OK as a example but it is clearly not your real goal!

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 21st April 2016, 09:21   #11
stass
Senior Member
 
Join Date: Nov 2012
Posts: 146
r2du-soft
If you just need to click on the keyboard :

Quote:
OutFile "CalcPress-test.exe"
!include "MUI2.nsh"
!insertmacro MUI_LANGUAGE English

!define VK_DELETE 0x2E ; Delete
!define VK_1 0x31 ; 1
!define VK_2 0x32 ; 2
!define VK_ADD 0x6B ; +
!define VK_RETURN 0x0D ; Enter
!define keybd_event "!insertmacro macro_keybd_event"

var HWND

!macro macro_keybd_event setkey intkey
!ifndef keybd
!define keybd
!define KEYEVENTF_EXTENDEDKEY 0x0001
!define KEYEVENTF_KEYUP 0x0002
!endif
System::Store S
${For} $0 1 ${intkey}
System::Call "user32::keybd_event(i${setkey}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|0, i0)"
System::Call "user32::keybd_event(i${setkey}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|${KEYEVENTF_KEYUP}, i0)"
${Next}
System::Store L
!macroend

Section
ExecShell "open" "Calc.exe"
Sleep 500
FindWindow $HWND "CalcFrame" "Calculator" ;Basic Window Info - [HWND] [Class] [Title]

Sleep 100
${keybd_event} ${VK_DELETE} 1 ; Reset Calc
Sleep 1000
${keybd_event} ${VK_1} 1
Sleep 1000
${keybd_event} ${VK_ADD} 1
Sleep 1000
${keybd_event} ${VK_2} 1
Sleep 1000
${keybd_event} ${VK_RETURN} 1
SectionEnd
stass is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump