Hi,
I'am trying to prevent user to run installer more then once at a time. (it works) 🙂
In such a case I want to display message about it and set focus to already working installer winodw.
my code:
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
FindWindow $1 "" "${PRODUCT_NAME}" 0 0
SendMessage $1 0x00007 0 0 'send WM_SETFOCUS
Abort
ok:
...
FunctionEnd
why it didn't work ? Any idea ?
with WM_CLOSE (0x00010) it works perfectly ...
thanks in advance
kobus
Set focus to installer window
23 posts
You're calling it in .onInit, at this time the installer GUI wasn't loaded so it will never find a window and set focus to it. Use .onGUIInit instead.
Originally posted by deguixThe scenario is different.
You're calling it in .onInit, at this time the installer GUI wasn't loaded so it will never find a window and set focus to it. Use .onGUIInit instead.
User run installer (instance no 1). Then run installer agian (instance no 2).
And now instance no 2. should inform user that installer is already working, set focus to window with instance no 1 and close itself (instance no 2).
anyway ... with .onGuiInit didn't work too. 🙁
kobus
Interesting. The code seems to be good. Can you upload your script?
[edit]
OK, this works:
[/edit]
[edit]
OK, this works:
When you issue the FindWindow instruction, make sure to specify the installer name followed by " Setup". In my case the installer name was "${PRODUCT_NAME} ${PRODUCT_VERSION}"
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup" 0 0
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Abort
ok:
...
FunctionEnd
[/edit]
When you issue the FindWindow instruction, make sure to specify the installer name followed by " Setup". In my case the installer name was "${PRODUCT_NAME} ${PRODUCT_VERSION}"I set title with caption for "${PRODUCT NAME}" so when I am trying to find window I use "${PRODUCT NAME}" as a title without "setup" word and it works ! - WM_CLOSE message close desired window. Only WM_SETFOCUS didn't work ...
I attach the code (sorry the UI is in Polish ...)
The problematic code is in onInit funcion
thanks for spending time with my problems
kobus
Your attachment is missing.
Anyway, did you try SetWindowPos as in my example:
Anyway, did you try SetWindowPos as in my example:
This seems to work.
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Yes, it's really works !!! 👍
That's was my typo error 🙁
thanks a lot
kobus
That's was my typo error 🙁
thanks a lot
kobus
Hello,
I just saw this post and test the code above. But it won't work for me.
I rewrite it here.
Thanks 🙂
I just saw this post and test the code above. But it won't work for me.
I rewrite it here.
Can someone see why that doesn't work ?
!define PRODUCT_NAME "My application"
!define PRODUCT_VERSION "1.0"
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
outfile "test.exe"
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup"
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Abort
ok:
FunctionEnd
section "Install"
sectionend
Thanks 🙂
I found that it won't work for that example because once the installation has completed, the window title will become:
${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Completed
If you change it to that (in FindWindow) then it works fine. This will be a problem though because the title is never going to be the same.
-Stu
${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Completed
If you change it to that (in FindWindow) then it works fine. This will be a problem though because the title is never going to be the same.
-Stu
why didn't you try the usual way?
should work for every title ...FindWindow $1 "#32770"
Doesn't work 😛
-Stu
-Stu
Originally posted by externeTested on Win98, NSIS 2.01 - works fine.
Can someone see why that doesn't work ?
BTW in one of my apps customer asked do not show second "already running" message box, but close 3-rd instance silently 🙁
#32770 window class - few and not installer dialog windows may present on the desktop 🙂
Hey thanks, I never seen that the titlebar name changed...
Now it work ( code below )
But the focus are not really doing. (The window is gray)
Is it normal ?
Thanks
🙂
Now it work ( code below )
But the focus are not really doing. (The window is gray)
Is it normal ?
Thanks
🙂
!define PRODUCT_NAME "My application"
!define PRODUCT_VERSION "1.0"
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
outfile "test.exe"
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup"
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Abort
ok:
FunctionEnd
section "Install"
MessageBox MB_OK|MB_ICONSTOP "I'm running... Launch another instance for testing... "
sectionend
It won't be working because the title will be "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Installing Files" and so on.
I'm going to have to modify that script...
-Stu
I'm going to have to modify that script...
-Stu
This should work (might want to try it).
!define PRODUCT_NAME "My application"
!define PRODUCT_VERSION "1.0"
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
outfile "test.exe"
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup"
StrCmp $1 0 0 setFocus
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: License Agreement"
StrCmp $1 0 0 setFocus
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Installation Options"
StrCmp $1 0 0 setFocus
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Directory"
StrCmp $1 0 0 setFocus
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Installing Files"
StrCmp $1 0 0 setFocus
FindWindow $1 "" "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup: Completed"
setFocus:
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Abort
ok:
FunctionEnd
Section "Install"
...
SectionEnd
-Stu
Nice, Thanks Afrow UK. 🙂
I understand the way well now 😛
Is it possible to list the windows ? I mean create a macro who's loop in the list of all window and search the words "${PRODUCT_NAME}" and "Setup".
Nice idea no ?
Bye.
I understand the way well now 😛
Is it possible to list the windows ? I mean create a macro who's loop in the list of all window and search the words "${PRODUCT_NAME}" and "Setup".
Nice idea no ?
Bye.
Program can check all top level dialog windows - this should work with custom installer pages too.
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
StrLen $5 "${PRODUCT_NAME} ${PRODUCT_VERSION}"
loop:
FindWindow $0 '#32770' '' 0 $0
IntCmp $0 0 ok
StrCpy $3 ${NSIS_MAX_STRLEN}
System::Call "user32.dll::GetWindowText(i r0, t r1, i r3) i.r4"
StrCpy $6 $1 $5
StrCmp $6 "${PRODUCT_NAME} ${PRODUCT_VERSION}" 0 loop
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Abort
ok:
FunctionEnd
Function .onInit
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutexS") i .r1 ?e'
Pop $R0
StrCmp $R0 0 ok
MessageBox MB_OK|MB_ICONSTOP "Installer already working"
StrLen $5 "${PRODUCT_NAME} ${PRODUCT_VERSION}"
loop:
FindWindow $0 '#32770' '' 0 $0
IntCmp $0 0 ok
StrCpy $3 ${NSIS_MAX_STRLEN}
System::Call "user32.dll::GetWindowText(i r0, t r1, i r3) i.r4"
StrCpy $6 $1 $5
StrCmp $6 "${PRODUCT_NAME} ${PRODUCT_VERSION}" 0 loop
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i.r1"
Pop $1
Abort
ok:
FunctionEnd
Well, sorry if i'm a few OT, but I want to understand what return exactly :
FindWindow $0 '#32770' '' 0 $0
So I write this little test : A 10 loop wich open a messagebox with the return of FindWindow.
Can someone tell me what mean those numbers ?
Thanks 🙂
FindWindow $0 '#32770' '' 0 $0
So I write this little test : A 10 loop wich open a messagebox with the return of FindWindow.
And that give me numbers : 918078, 66148, 66188, 1180982, 0, ...
outfile "test.exe"
Section "Install"
StrCpy $9 0
loop:
FindWindow $0 '#32770' '' 0 $0
MessageBox MB_OK|MB_ICONSTOP $0
IntOp $9 $9 + 1
StrCmp $9 10 0 loop
SectionEnd
Can someone tell me what mean those numbers ?
Thanks 🙂
This means that you have 4 dialog type windows (class #32770) on the desktop, and numbers are system window handles. Using handle program can read window caption (this case).
Ok,
#32770 mean USER dialog boxes thanks!
I found info also here : MSDN
You say : "Using handle program can read window caption".
This is what the line System::Call "user32.dll::GetWindowText(i r0, t r1, i r3) i.r4" does ? Right ?
Well I try this ( from reading your previous code )
But that return nohing ( I try to have the caption in the messagebox )
#32770 mean USER dialog boxes thanks!
I found info also here : MSDN
You say : "Using handle program can read window caption".
This is what the line System::Call "user32.dll::GetWindowText(i r0, t r1, i r3) i.r4" does ? Right ?
Well I try this ( from reading your previous code )
But that return nohing ( I try to have the caption in the messagebox )
Can you help me once again please ? 🙂
outfile "test.exe"
Section "Install"
StrCpy $9 0
loop:
FindWindow $0 '#32770' '' 0 $0
System::Call "user32.dll::GetWindowText(i r0, t r1, i r3) i.r4"
StrCpy $6 $1
MessageBox MB_OK|MB_ICONSTOP $6
IntOp $9 $9 + 1
StrCmp $9 3 0 loop
SectionEnd
Caption text is second parameter, use $1 in the MessageBox.
StrCpy copies from $1 to $6 first part of caption only ($5 is length).
You have nothing because not defines buffer length (last parameter, MSDN please 🙂
StrCpy copies from $1 to $6 first part of caption only ($5 is length).
You have nothing because not defines buffer length (last parameter, MSDN please 🙂
#32770 window class - few and not installer dialog windows may present on the desktopdamn 🙂
improved and shortened the code a bit:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "$(^Name)") i .r0 ?e'
Pop $0
StrCmp $0 0 ok
MessageBox MB_OK|MB_ICONEXCLAMATION "Installer already running."
StrLen $0 "$(^Name)"
loop:
FindWindow $1 '#32770' '' 0 $1
IntCmp $1 0 ok
System::Call "user32.dll::GetWindowText(i r1, t .r2, i ${NSIS_MAX_STRLEN}) i."
StrCpy $2 $1 $0
StrCmp $2 "$(^Name)" 0 loop
System::call "user32::SetWindowPos(i r1, i -1, i 0, i 0, i 0, i 0, i 0x02|0x01) i."
Abort
ok:
Well, I try a lot of time... But impossible to open MessageBox(s) with the name of the caption of each of window...
🙁
🙁