Control multiple program instances - open multiple files problem - c++

This shouldn't be an unusual problem, but I cannot find anything about it at google or at other search machine.
So, I've made an application using C++ and QtCreator. I 've made a new mime type for application's project files.
My system (ubuntu 10.10), when I right click a file and I choose "Open With 'Default Application'" the it runs
Code:
default_application path/to/the/selected/file1
So, if you select multiple files and select "Open With 'Default Application'" the system will call
Code:
default_application path/to/the/selected/file1
default_application path/to/the/selected/file2
default_application path/to/the/selected/file3
So, this is a big problem for me, because I handle the concurrent processes from inside the program, so when another instance of the program is running, a warning message is appeared. So, each application's call will recognize the others as currently running applications and so it'll show the message. I'll end up with 3 Messages saying that another process of the program is running --_--'
My application handles multiple URLs this way:
Code:
myapp path/to/the/selected/file1 path/to/the/selected/file2 path/to/the/selected/file3
How can I make my code handle all these multiple instances at the same time? Everything I've tried fails, because everything I've tried requires a check from the first instance called, which is too slow and other instances come app and all together are warning about concurrent processes of the same program
So, how can I fix this? is it system depended, or can I do something with the code?

The way is to make your application recognize that there is already an instance running and make the new instance just forward a request to the first instance before dying :)
EDIT:
The way to do that is to have your first application instance behave as a server. The pseudo algo is something like :
start();
try_to_contact_master_server_instance();
if(no_master())
{
I_am_master();
start_listening_server_that_wait_for_requests();
}
else
{
send_request_to_master("open file path/to/the/selected/file1");
send_request_to_master("open file path/to/the/selected/file2");
send_request_to_master("open file path/to/the/selected/file3");
die();
}
handle_incoming_requests();
I hope it's clearer ? Tell me if you need more precisions ...
For the server part, you can do your own or use some software bus provided by the OS like dbus or whatever, but it makes your application dependent, of course.
my2c

Related

How to be sure that mount command is actually finished in qt process

I'm developing a program written in qt5, where i need to mount some devices (USB DRIVE) and show in a GUI the contents of that device.
I'm using QProcess() to mount the device, and after that i explore the folder where the device should be mounted. Unfortunately only few files can be found.
I tryed to add a QThread::sleep() after the mount command, and this is actually work for small devices. So it seems that the correctness of my approach depends on how much i wait for the system to actually mount the device.
pr3.start("mount foo foo");
pr3.waitForFinished(-1);
QThread::sleep(6); //This is a patch but it fail depending on the amount of file stored in the device
Is there any way to be sure when the QProcess("mount") has finished correctly?
I tryed the wawtforfinished(-1) method of QProcess but it doesn't
seems to work.
Thanks
First thing, I would advise you to use the following signal finished() and connect it to a slot that checks the exit code and the exit status instead of using waitForFinished().
Indeed, the documentation states about waitForFinished() that:
Warning: Calling this function from the main (GUI) thread might cause your user interface to freeze.
Of course it assumes you have an event loop.
Other thing, your mount foo foo command seems wrong. The first parameter is the device itself and the second one is the directory where to mount the device. You cannot give twice the same parameter.
Please let me know if this does not help to solve your issue.
I tryed the wawtforfinished(-1) method of QProcess but it doesn't
seems to work.
That is big red flag something strange is going on.
When starting child processes programaticly a lot of error handling and reporting is typically in order.
Also this could include, but is not limited to, that the mount command is not working as expected, etc.

Creating a Launcher and sending info to second program

I have created a program that extracts data from a racing game and sends it to a speed gauge cluster. I call it the transfer program.
I need a simple user-friendly User Interface to start the transfer program, set some variables and choose a COM Port. At the moment I'm trying to do it with a C++ Windows Forms Application in a CLR Project on Microsoft Visual Studio 2015. When I tried to do it directly (creating the UI in the same project as the transfer program) I just get too many errors that I have no idea where they come from or why they are there.
So I've decided maybe I could try creating some sort of launcher, i.e. a completely different program that is only the UI to start the transfer program and send a few user-set variables to it on startup as well as choose a COM Port to communicate on.
Any idea on how to start on this? How do I execute the transfer program from the Launcher? How do I send variables and data to it?
Thank you very much!
There are basically two ways to pass information to your transfer program.
For simple use cases, just pass the values along on the command line. If you're still using the CLR, this is done using System.Diagnostics.Process. A nice example can be found in this answer: https://stackoverflow.com/a/33633148/127826
Use a shared configuration file. So the user interface loads the values from the config and also saves the file before executing the transfer program. The transfer program then reads the same configuration file to get the values it needs.
The second approach is far more flexible and is what I would use.

Code Blocks - empty console

When I'm running any project in Code Blocks I see this:
or
What should i do?
Thank you for your question and for using CodeBlocks as IDE.
The error message you are getting is because codeBlocks has no 'write' privileges to the folder where it wants to place the binary (or executable). You need to change the privileges of the folder where you ave your projects stored to Read/Write/Execute for all.
If you need to know how to do that, you need to put the specs of your system in the comments, I will tell you here on how to.
KR
Hewi
You usually get this message when you try to recompile an executable that is already running.
If you got this error, you should simply close your application. If you can't see an application window and you're still getting the error, open Task manager (Ctrl+Shift+Esc), find your program in processes list and close it from here.

How to make application not to run a new instance when openening a new file in Qt?

For example we have a TextEditor Application. Like notepad++. We have tabs at which file content was displaying.
The default text editor in OS is set to TextEditor Application. When we open a new file application added a tab and put content to it.
How to make an application not to run a new instance when opening a new file in Qt?
Which is the best way you think?
The problem is how can you make a single-instance application. When you open a file the operating system will open the associated application and give it the file as a command line argument. You cannot simply delegate an 'open file' command to a running application through OS mechanism, you have to implement it by yourself.
At the AppWhirr project we used QLocalServer/Client to communicate between instances: when the AppWhirr app is executed it checks whether a QLocalServer with a fix ID is already taken or not. If not this instance of the application is the first/only running instance. If the ID is already taken it means another instance of the application is already running so this second instance will only do 2 things: send the given input arguments to the other instance through Qt's local client/server communication, and when it's successfully finish the communication it will quit (the second instance).
That's one solution for the problem, requires quite a bit of coding and I would not recommend it if you don't want to use local client/server communication for anything else, but it's a viable solution.
Another solution would be that the first instance of the application creates a text file at a fixed location and writes our the instance's ID. After this the second instance can read the text file and send a message to the specified ID. And of course the first instance have to remove the text-file when it quits and probably you have to implement some fail-safe code to remove the text-file in case the first instance crashes. This solution will use less resource than the first one but requires a fail-safe cleanup code.
Or as a third option you can use third-party solutions like #Matteo Italia suggested.

How do I open a new document in running application without opening a new instance of the application?

I have a situation that has been partially covered by other answers at SO, but I cannot find a complete answer. In short, we are trying to use URL's for our specific data types that when double clicked will open up our application and load those data sets into that app. We have this part working.
(for example, an URL might look like this: resource://shaders/basic_shader.hlsl)
What we would like to do is to prevent new instances of the application from opening when a new URL is double clicked. For example, let's say we have a URL that opens up a shader in our shader editor. When clicking this resource URL, it will open our shader editor. When a new shader URL is clicked, we'd like to be able to open up the shader in the currently running application and have it open up the new shader in a new tab in our editor.
We can easily detect if another instance of our application is running. The problem that we don't know how to easily solve is how to tell the currently running application to open up this new file for editing. This behavior is very much like the Apple Finder.
In unix, you could emulate this behavior by having your application open some named pipe and then new apps could check if this pipe is active and then send the document data down the pipe. Is there a more standard windows way of achieving this behavior?
We need a C/C++ solution. Thanks.
Named pipe is the best way.
First instance of your application opens the pipe and listens to it (use PIPE_ACCESS_INBOUND as dwOpenMode and the same code will also allow you to detect running instances).
All subsequent instances check that they are not alone, send command line argument to the pipe and shut down.
Create a named mutex when application launches as David Grant said, then before displaying the UI for the second URL, check for this mutex, if it is already created then just quit by passing the new URL to the first launched application (Have interface in the application to set the URL and tell to redirect programatically)
You can't avoid the program associated with the url to be executed.
The "windows" solutions would be to send a message (via DDE in the old days but maybe there is something more "modern" now) to the previously running application with the url then quit ...
You can acquire a named mutex upon startup and enforce it that way.
http://www.google.com/search?hl=en&q=named+mutex+single+instance
CreateMutex on MSDN
I got this working pretty well for my C++ MFC application by following Joseph Newcomer's tutorial here. He uses a named mutex that is checked on startup and a message sent to the already-running application with the new resource to be opened.