What Windows IPC method is better for short commands? - winapi

I need one way IPC method for 2 Windows applications (both on the same machine).
Which one is better in case that my applications are CLI based + windows service.
P.S. I've implemented message queue in destination process (CLI application) in separate thread. And posting my message from source process (GUI application) via PostThreadMessage.
So. When both applications were run from the same user - everything is OK. When I'm running my destination application via Task Scheduler under Local Service user I'm getting 1444 error code (Wrong Thread ID).
Any ideas?
P.P.S. From MSDN
This thread must have the SE_TCB_NAME privilege to post a message to a thread that belongs to a process with the same locally unique identifier (LUID) but is in a different desktop. Otherwise, the function fails and returns ERROR_INVALID_THREAD_ID.
This thread must either belong to the same desktop as the calling thread or to a process with the same LUID. Otherwise, the function fails and returns ERROR_INVALID_THREAD_ID.
So. I should determine how to setup SE_TCB_NAME to my thread from my source process.

WM_COPYDATA message or custom message code (if you don't plan to transfer text or binary data) would work. WM_COPYDATA message lets you transfer binary data and Windows does copying across process boundaries itself.
In GUI -> CLI application you would need to create an invisible window in CLI process to receive messages (if you want messages to be SENT and not POSTed from the GUI application). If you just POST messages from GUI to CLI, then PostThreadMessage() function would be enough and there's no need for a window.
In CLI -> GUI direction there are no complexities at all as the window is already (usually) present in GUI application.

There is also nice solution - Message Queue from boost library.

Related

Are Windows-GUI calls (creating visible windows, etc.) allowed in a Windows-Service?

First off, I know some proper ways of making a truly interactive Windows Service.
The situation is, I do have a tool that does not interact with the user as such. However, it does display non-blocking notifications both via popup windows and via the Windows Notification Area (aka System Tray). It also writes a logfile of the notifications it displays.
This tool is normally spawned by a main user application and as long as the main application is a normal application, these notifications do work as intended.
When this tool is spawned by a Windows Service, no notifications are displayed, naturally. (The Desktop Session for the service isn't visible.) But this would be OK, we have the logfile and these notifications are just - notifications, nothing the user absolutely must see under all circumstances.
The question now becomes: Is a process running in the context of a Service (the Service itself or any process it starts) "allowed" to make Windows API calls that display a visible GUI?
Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session of the service?
Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?
And yes, calling ::MessageBox is a bad idea because it will block. But I can handle these calls.
And yes, this could be designed better, but it's what I have at the moment and it would be nice if I hadn't to rip the whole tool apart to make sure no GUI related code is run in the service.
GUI elements from a Windows Service are shown on Session 0. On Windows XP & 2003, users were allowed to log in to Session 0 and interact normally with the windows created by a service, but Microsoft put a knife in the heart of interactive services in Vista (and beyond) by isolating Session 0.
So, to answer your specific questions:
Is a process running in the context of a Service (the Service itself
or any process it starts) "allowed" to make Windows API calls that
display a visible GUI?
Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session
of the service?
Yes, GUI calls are allowed and should succeed as normal. The only notable exceptions that I know of are those related to tray icons because the process providing the task bar (explorer.exe) is not running in the isolated Session 0.
Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?
That should not be necessary, though you should proceed cautiously with any GUI interaction from your service. Test thoroughly!
I would like to provide some info wrt. Raymonds Chen's comment to the other answer
You should avoid presenting UI in a service because you may trigger
the UI Detection Service which will switch the user to your service UI
temporarily. – Raymond Chen
I find these good articles:
What is Interactive Services Detection and Why is it Blinking at Me?
Inside Session 0 Isolation and the UI Detection Service, Part1, Part2
Where one can find explanation on what the UI detection service (UI0Detect) is and does and how it's supposed to work.
Interactive Services Detection (the blinking button on the taskbar) is
a mitigation for legacy applications that detects if a service is
trying to interact with the desktop. This is handled by the
Interactive Services Detection (UI0Detect) service.
However, one must note that this only can work if the service that is trying to view a GUI has the flag "Allow service to interact with desktop" set, because only then the service process will be running on WinSta0of Session0 even allowing it to show anything at all.
Alex Ionescu mentions this:
If UI0Detect.exe ...
the SCM has started it at the request of the Window Hook DLL. The
service will proceed ...
The service first does some
validation to make sure it’s running on the correct WinSta0\Default
windowstation and desktop and then notifies the SCM of success or
failure.
So, to come back to Raymond's comment: As far as I can see, as long as a service doesn't tick the type= interact option (see sc.exe), and normally you don't tick this, the UI0Detect service doesn't do anything and there shouldn't be any "danger" of triggering it.
Note: The information above is based on my limited research and tests on only a single Windows 7 PC.

When does a Windows thread need a message loop and why?

When do I need a message loop in a Windows application?
For example, for a Windows service do I need a message loop for every thread that I created or just for the main service process?
while(true)
{
GetMessage(&messageHandle, 0, 0, 0);
DispatchMessage(&messageHandle);
}
Every native Windows programs contains at least one message loop (often called a "message pump") like the one you give an example of.
This is to enable the handling of Windows events initiated by the program itself, other applications or the operating system.
Example of Windows events can be for timers, socket communication, GUI actions, clipboard, etc.
Many APIs and frameworks implement a message loop for you. This will depend on what you are using in your particular case.
(Check the answers in this Stack Overflow question for more information on message loops/message pump.)
Now to the gist of your question: many or most programs will work fine with one message-loop. The cases where you would want more than one is typically if processing a Windows event can take a long time (i.e. it locks the current thread) and there are requirements that require you too keep processing new window events. I can think of two concrete examples:
One is in a GUI application where you're showing a modal dialog (which usually freezes the main message pump and spins up a new one for the dialog)
A service of some kind where processing of I/O events can take a long time because of external dependencies and timeliness of processing of new I/O events is critical
In (1) this is very often a consequence of the GUI framework you are using and not something you have to do explicitly. In (2) a better way of handling it would be to asynchronously "do the work" of each event rather than blocking the message pump.
In conclusion: it depends. :-) In most cases you shouldn't need to use more than one message loop, but if you have to, do it!
Apps:
Essentially, when the thread is going to create and manage windows. This includes 'hidden' windows that support COM STA and the like.
No windows, no windows messages, no message loop required.
Services:
Service manager needs to handle the service messages, and so requires a service message loop for Start/Stop/whatever.
For other threads started in a service, no message loop is required.

Is it possible to track a PostMessage between processes?

We have a system where there are typically two processes running on the same system. One process handles the GUI and the other runs like a service (although for historical reasons, it's not a service, just an exe with no visible window).
The two processes undertake IPC mainly via registered messages asynchronously - i.e. we use RegisterWindowMessage() in both processes to define a large'ish set of messages that effectively form the API to the server process.
I have written a "hands-free" monitoring application that uses SetWindowsHookEx() to monitor and display the message queues of both processes and provide some level of decoding of the way the API is being utilised and how notifications are being propagated to the GUI process (each individual window can subscribe to notifications from the server directly).
So, there are a large number of messages in both directions so I have filtering and summary counts etc. so I can focus on particular activity. All this can be done without affecting the live code, which is good.
This all works well, but it now would be very useful to be able to "tag" a message originating in the GUI so I can trace the same message when it's processed by the server. This would be enormously useful for debugging and diagnosing system issues, but I can't find a clean way (actually I can't find any way!) of doing this without adding such support to our registered message API, which would be a lot of work and involves more risk than I'm comfortable with at the moment. It gets further complicated by the fact that the server pre-processes some messages and then does a PostMessage() back to itself to perform the action, so the originating message can get "lost".
Has anyone here tackled this type of problem? If so, can you give me some pointers? If not, then are there any documented or undocumented ways of adding a small block of data to a Windows message and retrieving it later? I've looked at SetMessageExtraInfo() but that seems to be per-queue rather than per-message.
FindWindow or FindWindowEx will give you the details of the GUI Window. Compare the details with message intercepted

Calling a .EXE from Websphere-MQ

This a follow-up based on MQ (Websphere 7) persist message to file system.
How do you set up an .exe program from an MQ support pack (such as the Q utility in MA01) to execute each time a message is received? Can this be setup in MQ Explorer? (We are using 7.0 on Windows 2008/R2).
There are a few ways to do this.
Set the application up under Windows control (since you mentioned the QMgr is on Windows.) The app would run as a service, with recovery options to restart it if the service fails. The application would be programmed (or configured in the case of Q) to process the queue using GETs with a VERY long wait period. Some additional error handling is required to do something sensible when the QMgr is not available. This works great for copying messages to multiple queues but isn't appropriate for queue-to-file since the file would never close.
Run the application as a WebSphere MQ service. Defining the SERVICE object using CONTRIL(QMGR) causes MQ to start the service when the QMgr boots and stop it when the QMgr is shut down. Since the service is a child process of the QMgr, no need to worry about how to handle errors when the QMgr isn't available.
Trigger the program based on non-zero queue depth. Define a process object describing the command to be executed, enable triggering on the queue with TRIGTYPE(FIRST) and run a trigger monitor. Whenever the queue has depth > 0 and no open input handles, the process object fires and executes the command. The thing you start must know how to parse the command line so the easiest thing to do if you have someone else's executable is use a script to start it. The script parses the trigger message and fires off the executable. Or perhaps the script ignores the trigger message and just runs the exe. I generally use Korn Shell or Perl and both are available on Windows.
I wrote an article showing how to keep event queues from filling using a triggered version of Q. The article assumes you want the queues to remain mostly full so uses triggering on depth of about 80%. The same techniques could be used (in a much simpler implementation, by the way) to fire off the Q program whenever the queue depth became non-zero.
UPDATE
Probably should have linked the article. ;-)
Mission:Messaging: Easing administration and debugging with circular queues

Is there a programmatic way to detect if the process can interact with desktop

I have an executable that can run normally or as service. At the startup it may show an error message if there is an error (using MessageBox api). This can cause failure if the application is running as service but not allowed to interact with desktop.The process may appear to be hanging. Is there a programmatic way to detect if the application can interact with desktop ? I can then use some other error notification mechanism (log file etc)
You could specify MB_SERVICE_NOTIFICATION when calling MessageBox(), which will display the message in the currently active session.
But, displaying a message box from within a service is not what you really want.
Services are supposed to run in the background and not interact with users directly. One of their characteristics is that they can (and often do) run even when no user is logged on. In Windows Vista they even run in a totally different session than all other users'. Displaying a MessageBox could result in your services being blocked, because the message was invoked in your service's own session without the user knowing about it.
Writing to some sort of a log file or using windows' EventLog is the prefered method.
From MSDN:
To determine whether a service is running as an interactive service,
call the GetProcessWindowStation function to retrieve a handle to the
window station, and the GetUserObjectInformation function to test
whether the window station has the WSF_VISIBLE attribute.
In .NET you can use Environment.UserInteractive
The UserInteractive property reports false for a Windows process or a
service like IIS that runs without a user interface. If this property
is false, do not display modal dialogs or message boxes because there
is no graphical user interface for the user to interact with.
From http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx:
To determine whether a service is running as an interactive service, call the GetProcessWindowStation function to retrieve a handle to the window station, and the GetUserObjectInformation function to test whether the window station has the WSF_VISIBLE attribute.

Resources