Is there anything like this in Xojo? Double clicking a file from the app opens a new instance every time and this does not make sense for how this particular application is built. I’ve looked all around Xojo, searched, and can’t seem to find anything about this.
Windows does this by default
But you can override that behavior with a mutex
The example on the language reference page stops multiple version from running http://documentation.xojo.com/index.php/Mutex
I’d swear there is an example somewhere of making it so the new copy tells the already running one about the new document to be opened but I can’t seem to locate it right now
[quote=86292:@James Holy]Is there anything like this in Xojo? Double clicking a file from the app opens a new instance every time and this does not make sense for how this particular application is built. I’ve looked all around Xojo, searched, and can’t seem to find anything about this.
[/quote]
Here is how to do it in your app open process :
Do a shell “Tasklist”
In the result, use Instr() to find the name of your app executable (for instance “myapp.exe”)
If you do not find “myapp.exe”, then it is OK. If you find “myapp.exe”, the app is already running ; take appropriate action.
I have been using the tasklist command, so I did not think about Mutex. The advantage of Tasklist is that you can also list other applications and even terminate one using tkill.
What is tricky, though, is that Windows sends keys by the title of the open window. If you have dynamic titles or several windows open, then you have to manage that…
Usually the currently running instance has an ilc socket that a new instance can connect to and the new one sends a “open this document” command to the already running one then it quits so the document that was clicked on still gets opened in the already running instance
Turns out Aaron wrote about it years ago and its in his book
Page 59 Single-Instance Applications Using a Mutex
A quick google for it doesn’t reveal that it available anywhere but I know its in his book on xojolibrary.com
I just played with the example project/Communication/IPCSocket.xojo_binary_project
Build it, run the built, then run the project in the IDE. Click Listen on one copy . When you click Connect on the other, you can send messages back and forth.
I imagine transmitting the document to open can be done this way (pseudo code) :
[code]Upon launch ;
if mutex.tryenter
start listen
do your stuff
if IPCSocket.Datavailable then look for document to open
receive connect, then document to open.
When second app closes this generates error 102, close IPCSocket, then open and listen again.
if not mutex.tryenter
connect
send document to open information. Maybe shellpath ?
display the message “cannot run two copies”
close Mutex
quit
this send to first app an error 102 code, so it can close IPCSocket and start listening again
[/code]
From what I see, copy/paste from the example should work.
For windows you could also use WMI with OLEObject.
// This example will display windows searched process image name
//http://library.wmifun.net/cimv2/win32_process.html
//http://msdn.microsoft.com/en-us/library/aa394372%28v=vs.85%29.aspx
Dim locator, objWMIService, objs, objProperty As OLEOBJECT
Dim nobjs as Integer
Dim myApp As String
myApp = "myApp.exe" // Here the name of your app you want to check if running
// Connect to WMI
locator = new oleObject("WbemScripting.SWbemlocator", true)
Dim wmiServiceParams(2) as variant
wmiServiceParams(1) = "."
wmiServiceParams(2) = "root\\cimv2"
objWMIService= locator.invoke("ConnectServer", wmiServiceParams)
// Run the WMI query
objs = objWMIService.ExecQuery ("SELECT * FROM Win32_Process WHERE Name = '"+myApp+"' ")
If objs.count > 0 Then // Check if application myApp is running
nobjs = objs.count - 1
For i as integer = 0 to nobjs
Dim stringData As String
objProperty = objs.ItemIndex(nobjs)
// ItemIndex() is not supported in Windows XP only from Windows Vista and upwards
stringData = "CommadnLine: " + objProperty.Value("CommandLine") + EndOfLine
stringData = stringData + "Name: " + objProperty.Value("Name") + EndOfLine
msgbox stringData
Next
Else
Msgbox "No application with name: "+myApp+ " is running"
End if
locator = Nil
exception err as oleexception
msgbox err.message
I have aaron’s book somewhere. I just have to find it now. it is probably boxed up somewhere…
might be easier to find a new copy then it is to find my copy.
So I created an IPCsocket class and initialized it in the open event of app; then I tried to follow the suggestions above, but after writing myIPC.listen and myIPC.connect and launching a file related with the app itself, I always get the “You are not allowed to run multiple instances of the same app” message. Yet, the socket.dataavailable (msgbox me.readall) never shows me anything.
Does anybody have working code?
BTW: using Mutex.
Thanks,
Carlo