I'm reading through a tutorial on using voice commands to control applications and, in an example of controlling rhythmbox, it suggests commands such as the following can be executed:
rhythmbox-client --play
rhythmbox-client --pause
Why does this not simply open a new instance of the program, and how can I emulate the functionality in my own programs? For example, how could I pass a string to a particular instance of a program?
Thanks
Rhythmbox uses inter-process communictation to achieve this type of functionality, and this can be implemented in a number of different ways. One of them is to use D-Bus, like Rhythmbox does.
Using D-Bus is not very easy, but the basic idea is that you register your application in D-Bus, so other applications can call different procedures your app exports (for example play/stop actions), and then in the same application implement a client. This way, if arguments like --play are passed, you don't run the usual code, but just check for an instance of the running app and send a command to your already running program.
On the other hand, when no arguments are passed, your program just starts and registers the proper triggers, so that a later called instance can control it.
Here is a tutorial on dbus, and the DBus homepage
There are several techniques to have only one application instance running. In these terms calling yyy --play would generally mean the same as
INSTANCE = GET_RUNNING_INSTANCE()
IF INSTANCE == NULL
INSTANCE = CREATE_NEW_INSTANCE()
SEND_MESSAGE(INSTANCE, PLAY)
For example, how could I pass a string to a particular instance of a program?
You'll need to use whatever interprocess communication facilities your operating system offers. Sockets or named pipes, for example, or messages.
Related
I am creating process using create process does anyone knows how to use create function if process is already running not create or externally having any other way to detect process is running.
On Windows, you use the Process Status API (PSAPI) to search through all the processes running on the system. The degree of access you have to this resource will depend on the privileges that the program is running under.
See the MSDN article
Specifically, you would invoke the EnumProcesses function to get a full list of the running processes IDs, then, using those IDs use other functions in the API to get information about them. For example, to get a processes name, and have it's ID already, you could call GetProcessImageFileName.
Beware that these functions have ASCII and Wide-character versions.
I have a C++ COM (multi-threaded apartment model) application that I build with Visual C++ 2019. I am playing with the COM-based Active Script interfaces and classes. I have a JavaScript ("JScript" really, CLSID {F414C260-6AC0-11CF-B6D1-00AA00BBBB58}) Active Script COM object created and set up. Everything works surprisingly well (for something that is falling into obscurity, unfortunately).
Is there an idiomatic approach to registering and calling event listeners where a script can use an API like like https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener and where I can dispatch events from the script host (C++)? To clarify, I am well able to call IDispatch interface methods from scripts, I want to call script functions that were passed earlier with such methods to the program, from the program. GetScriptDispatch is something else -- it lets me call methods available in the global script namespace, but I need to call functions that I pass to a proxied (from the script) "addEventListener" method.
I depend on this functionality because I want to dispatch events. Basically I want addEventListener to be available on certain proxied (e.g. objects added to script namespace with AddNamedItem) objects and I need to call event listeners added through calls to that method, when certain events in the C++ application happen.
I have read something about IConnectionPoint, and the Active Script documentation briefly mentions "event sinks" a couple of times, without there being examples on how and for what these can be used for. There is also the IBindEventHandler interface, without much explanation again as to what to use it for.
I understand this is ancient stuff, but I like COM and Active Script interface has several implementations, which to me adds utility.
You need to create an object that implements events (see IConnectionPoint).
After starting the script you can call AddNamedItem. The script now knows the interface of you object. If it implements it can register to this events when the state changes to SCRIPTSTATE_CONNECTED.
If an event is fired, the script will receive the event and will execute the appropriate code section.
There are old samples:
Q168214 SAMPLE: MFCAXS (you might find it in the wayback engine)
And there is a sample here in code project
For ATL samples for Events look here
I have created two executables that accept command line arguments. Now, I want to pass arguments to available executables using C++ (executing on Windows). What is the best way of doing it?
I have used CreateProcess(); it's working fine for static input but I want to input dynamically through CLI.
The command-line (with arguments) is one of the parameters to CreateProcess(). Just put whatever arguments you want to pass on to the child executable in there.
What problems are you having with non-static input?
I usually use system(const char*) and it works for me :)
You pass over a string which contains the command as you type it in the command line. In your case it means the path to the exe file and the arguments it takes, with just spaces in between. It runs the specified process as if it was run from command-line.
For more information: http://www.cplusplus.com/reference/cstdlib/system/
It sounds as though you already understand that string arguments can be sent via CreateProcess at launch time. If you want to continue to send data at run time, you have a couple options.
Use console redirection. Since you are already using the Win32 API, it is not too far of a stretch to write to cin of the child process after you have launched it. See this MSDN article. I think this might be what you mean by "input dynamically through CLI"
Use some sort of IPC. There are Win32 ways of doing this such as message queues, and more platform independent methods such as Protocol Buffers, Thrift, or Boost.Interprocess.
There is really more than one way to skin a cat when it comes to IPC and your goal is to do your research and make sure you have made the correct design decisions early on for how your processes will communicate.
If you do decide to use a more full-blown IPC rather than something like console redirection to solve a smaller problem, some questions you should ask yourself are:
Will I be able to send all the types of data using this type of IPC?
Will this communication ever need to cross network boundaries?
And, the two big questions that always show up are:
How maintainable will this be in the future?
Will this code ever have to run on another platform?
Hopefully this response is not overkill for your question.
I have a Windows local service that may spawn off a process to execute a JScript script (in a .js file) via the Windows Script Host. The issue is that I need to notify my service of the results generated by the script in the .js file. A transfer or a simple 32-bit integer, or a string would suffice. What would be the way to do this?
PS. The code must run on Windows XP SP3 or later OS.
Your best bet is to create an out of process COM object that executes within your service. Just implement the necessary scripting interfaces and provide a member function to match the notification and call it from your script as such:
newObj = new ActiveXObject("localserver.mynotify");
newObj.Notify("finished");
Would the exit code of the process be enough?
Windows Scripting host has has a .Quit(errorCode) method that allows you to set the exit code.
You should be able to call WSH directly from the service and get the return code with GetProcessExitCode() by passing the process handle that you received after spawning it.
Note that almost everything you can do from a JScript file can also be done with native code.
Do you have to execute the .js file as an external process? Windows Scripting has COM objects that an app can use to run scripts within its own process. I use this to execute script files within my service processes, and it works fine. The hosting process can even implement its own IDispatch-based classes and pass them to the scripting engine to expose to scripts as global objects so the scripts can communicate with the hosting process without having to use new ActiveXObject or CreateObject() to access those objects.
I see your script is written in JScript and your app in C++.
Perhaps the easiest way to accomplish what you want is by writing a file, say, to programdata folder which your service should have access to. Maybe use a GUID for the particular request, pass that to the JScript so it's guaranteed to be a unique file. Not ideal.
Another way to get JScript output ... Can you call out to managed code (C#)? If so, you could use a .NET-based or .NET-callable JavaScript compiler/interpreter. This would allow you to avoid IActiveScript and also to grab the values right out of the script context or from function return. I've used Jurassic and JavaScriptDotNet, both very easy to use and extend.
This might open a problem if you heavily rely on ActiveXObject calls (ie: FileSystemObject) and don't want to write components. JuraScript wraps the Jurassic engine and add ActiveXObject support to it for COM automation.
I am a C++ newb, so I don't know how much of a leap this is for you although I know it's possible to interop between managed/C++.
Just thought I'd mention these scenarios as I didn't see them listed in answers.
What's the approved way to handle second, third, etc launches of application in Windows (C++) application? I need the running (first) instance to take some special action (pop up a dialog) in this case, but for the secondary instances to terminate.
On Mac, AppleEvents sends you a 're-open' message in this scenario. Mozilla on Windows uses DDE to check for an existing instance and pass the command line through. It feels like a pretty nasty solution, all the same.
The windows way is to open a named mutex and, if you can acquire it, it means you're the first instance, if not, there is another one. At this point you can register a windows message (the function is literally RegisterWindowsMessage) which gives you a WM_ msg you can send to all windows and only your app would know to catch it, which allows you to tell your initial copy to open a dialog box or w/e.
How to limit 32-bit applications to one instance in Visual C++
"The method that is used in this article is the one that is described in MSDN under the WinMain topic. It uses the CreateMutex function to create a named mutex that can be checked across processes. Instead of duplicating the same code for every application that you will use as a single instance, the code that you must have is in a C++ wrapper class that you can reuse across each application."
SendMessage Function
"Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message."
"Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication."
RegisterWindowMessage
"The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages."
On windows there is not really solution for that at least not out of the box.
You can use mutex to do such things, basically the app check for the mutex at startup create it if it doesn't exist.
There is one issue with CreateMutex method that you might need to consider - the named mutex might have been created by a third party. Now, most of the time, this won't be an issue, there would be no reason for someone else to block your application. However, if you're making a program that does something important, it may be an issue. Consider, if your program was a virus scanner, a virus could disable it by creating the mutex.
Usually, CreateMutex should do the job, but you should be aware of the limits of this method.