Page 1 of 2

Help with Singleinstance

Posted: 30 Oct 2020, 16:30
by elad770
Hi everyone

I'm new to this website and I'm very happy to be here. Could be someone already addressed this somewhere but this place is like an ocean. Wasn't sure where to look

I have downloaded a program called Single instance. It has an ahk file and basically, it prevents a program I have in windows to open more than 1 instance. Which is great except for one thing:

After activating it, i lunch the 2nd instant but instead of closing the 1st instant, it is closing the instant I've just opened.

What i would like it to do is:

When opening the second event I would like for the FIRST event to close before the 2nd is loaded. I hope it's clear and i have attached the file. Thank you so much for helping

Re: Help with Singleinstance

Posted: 31 Oct 2020, 01:52
by Rohwedder
Hallo,
this could only work if you don't open new programs yourself but let Autohotkey do it.
If you want to keep doing it yourself Autohotkey would need a time machine to close the previous instance of the program in the past.

Re: Help with Singleinstance

Posted: 31 Oct 2020, 18:12
by elad770
The way it works is that I press a key to open a file with a program. When I press the second key I would like the program to immediately terminate and immediately open the new file.

Ok, let's do a time machine. I have no idea what that is and how to do one. Can you guide me step by step?

I'm willing to pay for anyone who can help out. This is fairly simple but I never used AutoHotkey and have no idea how to program it. However, I know exactly what I want to be happening and willing to show anyone who's interested to help

Thanks

Re: Help with Singleinstance

Posted: 31 Oct 2020, 18:24
by elad770
I have and idea:

Let's say I have the command to open the file I want (a key For example)

What if I will assign the same key to close an open but the open will have a 0.5sec delay.

Will that work?

Re: Help with Singleinstance

Posted: 31 Oct 2020, 20:18
by boiler
If you’re using a key via script to open a file/app, you can have it close other instances of that file/app before opening the new one. At there doesn’t even need to be a 0.5 second delay or anything.

I think you misunderstood what Rohwedder was saying. He didn’t say you couldn’t close the original instance first if you’re opening it via a script. He was saying that if you’re opening the new instance yourself via Windows instead of a script, the script can’t know to close the first instance before the new instance starts to open.

I haven’t downloaded the SingleInstance script, but it doesn’t matter because instead of modifying that script, what you really want to do is write a new script that has hotkeys or buttons to launch programs from a pre-selected list of programs. That’s how it will know to close any existing instances first.

Re: Help with Singleinstance

Posted: 31 Oct 2020, 23:12
by elad770
I highly appreciate your response Boiler.

Can you please teach me how to do that?

Here's the problem exactly because I'm not sure if I'm the one who's activating the file according to you:

I have an mp3 file. ---This file is triggered by a midi SysEx message (I use different software for that, I wish I could do it here)

After the program executes the file, I'm triggering another file with another command. The application opens a new instance and that creates a lot of problems for me.

I would like ONLY the last file that was open to being working. For that, I need a command that closes the application/window immediately and opens the new instance.

One other thing to add is that when I'm making a change to the mp3 file the program will stop and ask me if I want to save the file, so, I would like in this example for the script/command to wait until I answer that question.

If saving was not required - It should open immediately upon closing the last instance
If saving is required, the script will allow me to answer first and immediately after loading the new instance.

I will contribute 100$ to this amazing platform if someone can help me with the script or give me another solution on how to get it done

Re: Help with Singleinstance

Posted: 01 Nov 2020, 07:24
by boiler
What you are describing falls outside of what I outlined, which is you launching the new instance via a script, which would allow the script to know to close the other instances before opening the new one. Perhaps someone else knows how to capture the event of an app/file being opened in general and act on it. It would seem to be quite difficult if it’s even possible.

P.S. If you do find someone that is able to make a time machine for you, make sure to invest. ;)

Re: Help with Singleinstance

Posted: 01 Nov 2020, 07:45
by mikeyww
I'm not sure why this would be difficult with a minor modification to the script. The script is actually tracking the PIDs and the process names. Since each window has a unique ID or hWnd, you can do the following.

1. Get the hWnd and its process name. Store both in an associative array.

2. If the process name of interest already exists in the array, then close the hWnd from that old one, and remove that entry from the array.

I think that's about all that's needed.

Re: Help with Singleinstance

Posted: 01 Nov 2020, 07:58
by boiler
I'm not seeing how to accomplish the part highlighted below, but I'm interested to see how you do it.
elad770 wrote:
30 Oct 2020, 16:30
When opening the second event I would like for the FIRST event to close before the 2nd is loaded.

Re: Help with Singleinstance

Posted: 01 Nov 2020, 08:08
by mikeyww
You're right. I missed that part! If that is essential, your solution makes sense, @boiler.

Re: Help with Singleinstance

Posted: 01 Nov 2020, 12:50
by elad770
Thank you so much mikeyww and boiler for your willingness to help. I now solved the main challenge you are having.

Now, I'm OK with the old instance to close AFTER the new one is open. Not a problem.

Again, let's back track and assume that the older instance will close immediately after the new one is open. Not a problem.

mikeyww, can you please revise the script for me or share it with me?

I need the new instance to activate and immediately the older instance to close.

Thank you so much

Re: Help with Singleinstance

Posted: 01 Nov 2020, 14:51
by mikeyww

Code: Select all

Global closeOldProcs := "notepad,iexplore" ; List of comma-separated process names to track (omit file extension)
Global handle := {}
Loop, parse, closeOldProcs, `,
{
 WinGet, win, List, % "ahk_exe " A_LoopField ".exe" ; Get all HWND for this process
 handle[A_LoopField] := win ? win1 : handle[A_LoopField] ; Store the first HWND for this process
}
; Detect newly created windows
; https://autohotkey.com/board/topic/80644-how-to-hook-on-to-shell-to-receive-its-messages/
Gui, +LastFound
hWnd := WinExist(), DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return

ShellMessage(wParam, lParam) { ; wParam = message number; lParam = HWND
 If (wParam != 1) ; 1 = Window was created
  Return
 ; A window was created
 WinGet, pname, ProcessName, % "ahk_id " lParam ; Get the new window's process name
 shortName := StrReplace(pname, ".exe") ; Get the process name without extension
 If shortName not in %closeOldProcs% ; Process is not of interest
  Return
 oldWin := "ahk_id " handle[shortName] ; Window title of the older instance
 If WinExist(oldWin) { ; Process of interest already exists as a window
  SoundBeep, 1500, 30
  MsgBox, 36, % Format("{:T}", shortName), Close the old window? ; Optional prompt
  IfMsgBox, No
   Return
  WinClose, %oldWin%
 }
 handle[shortName] := lParam ; Save the HWND
}

Re: Help with Singleinstance

Posted: 01 Nov 2020, 15:45
by elad770
I can not describe how appreciative I am.
Thank you

I will test it tonight.

I just wanted to clarify few things.

1. Is this script in addition to the current or replaces it?

Second question:
2.the original program came with the Ahk file (which I'm assuming is where I place your script) and a text file that I could open an specified the programs path. Do I still use that as normal?
In other words , is your script only replaces the Ahk file?

Thank you in advance

Re: Help with Singleinstance

Posted: 01 Nov 2020, 15:50
by mikeyww
This is a standalone script and requires no other scripts or files. You just have to specify the processes of interest at the top.

It won't work with everything: works on windows, not tray icons without windows. If you already have more than one instance open, it won't close all of them. You would have to make adjustments to do that.

It's fairly simple in what it does: stores the most recent window handle of processes of interest. When it finds a new window of the same process, it uses the old handle to close the old window, and then saves the new handle. That's it.

Good luck!

Re: Help with Singleinstance

Posted: 01 Nov 2020, 22:58
by elad770
You are amazing Mikey!!!

I ran the script and it does close the old window. There's only one tiny problem. It's asking me if I want to close the old window? I don't want to be asked if I want to close it or not

I want the window to close without asking me a question.

When I said that I want to reply before closing I was referring to the program itself. I was saying that if a file was changed the Program (running in the window) will ask if I want to save the changes or not. All I wanted to make sure is that
the script will not alter this behavior. (As opposed to "terminate" program that will occur from the task manager). But since the second instance is opened regardless either way, I would like to ask one final thing: if you can please remove the question that the script is asking and simply close the window.

Really looking forward to making it work :)

Re: Help with Singleinstance

Posted: 01 Nov 2020, 23:03
by mikeyww
I'm glad that it works. You can simply remove the optional prompt (noted as such) and the two lines that follow it. I believe that WinClose would then prompt you to save any unsaved work before the window closes (but I can't promise that).

The version below should work for you.

Code: Select all

Global closeOldProcs := "notepad,iexplore" ; List of comma-separated process names to track (omit file extension)
Global handle := {}, prompt := False
Loop, parse, closeOldProcs, `,
{
 WinGet, win, List, % "ahk_exe " A_LoopField ".exe" ; Get all HWND for this process
 handle[A_LoopField] := win ? win1 : handle[A_LoopField] ; Store the first HWND for this process
}
; Detect newly created windows
; https://autohotkey.com/board/topic/80644-how-to-hook-on-to-shell-to-receive-its-messages/
Gui, +LastFound
hWnd := WinExist(), DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return

ShellMessage(wParam, lParam) { ; wParam = message number; lParam = HWND
 If (wParam != 1) ; 1 = Window was created
  Return
 ; A window was created
 WinGet, pname, ProcessName, % "ahk_id " lParam ; Get the new window's process name
 shortName := StrReplace(pname, ".exe") ; Get the process name without extension
 If shortName not in %closeOldProcs% ; Process is not of interest
  Return
 oldWin := "ahk_id " handle[shortName] ; Window title of the older instance
 If WinExist(oldWin) { ; Process of interest already exists as a window
  SoundBeep, 1500, 30
  If prompt {
   MsgBox, 36, % Format("{:T}", shortName), Close the old window? ; Optional prompt
   IfMsgBox, No
    Return
  }
  WinClose, %oldWin%
 }
 handle[shortName] := lParam ; Save the HWND
}

Re: Help with Singleinstance

Posted: 01 Nov 2020, 23:07
by elad770
I removed some lines but the whole function didn't work.

I'm probably removing something I shouldn't remove.

Can you be more specific? Or maybe reupload the script?

Re: Help with Singleinstance

Posted: 01 Nov 2020, 23:08
by elad770
Silly me!

I didn't see that you already attached the revised version!

So sorry for that

Re: Help with Singleinstance

Posted: 01 Nov 2020, 23:24
by elad770
Thank you so much, Mikey!

It worked flawlessly with no issues.

As promised, a 100$ donation was made to AutoHotkey to support the community and amazing people like you who love helping!
(I attached the donation confirmation)

Can I ask one last question?

I know there's a way to place a script in an exe file (like an installation file). So, when I use it on another computer or give it to someone they will simply install like they normally would and the script will be activated.

Can you please refer me to a video tutorial of how this can be done? Something that is easy to understand? I would highly appreciate it

Sincerely

Re: Help with Singleinstance

Posted: 01 Nov 2020, 23:43
by boiler
elad770 wrote: As promised, a 100$ donation was made to AutoHotkey to support the community
:bravo:

elad770 wrote: I know there's a way to place a script in an exe file (like an installation file). So, when I use it on another computer or give it to someone they will simply install like they normally would and the script will be activated.

Can you please refer me to a video tutorial of how this can be done? Something that is easy to understand? I would highly appreciate it
Just right-click on the script file in File Explorer and select "Compile Script". It will create the .exe version in the same directory, then others can run that file without having to install AHK. The .exe file isn't an installation file. It is the script itself in an executable format.