Take an example of Microsoft Teams. It (usually) starts automatically in background when Windows starts, and you can launch the main window either from the tray, or from the start menu. You can do both—it won't open the main window twice.
There are multiple options to ensure only one instance would run. You may check for them with a search query such as “c# prevent multiple instances,” replacing C# by your language of choice. The most popular techniques seem to be a global system resource exclusive acquisition. For instance, a named pipe, a plain file lock, a block of shared memory (relevant term in Microsoft's world: memory-mapped files), or a port can be used for that. Roughly, the idea is that the first instance that runs would take the ownership of a given resource. Then, another instance will be prevented from doing it.
Concrete example: the first instance of an application starts listening on TCP port 12345 when the PC starts. At this point, the application is shown in the tray, but its main window is not displayed. When the user tries to open the application from the start menu, this second instance would see that the port is already in use—and would send a packet to this port and then immediately close. The original instance, when receiving this packet, would know that it needs to show its main window. From the user's perspective, it's the user who just started the application. In reality, it was already running.
One or two processes?
It's up to you, as both approaches are valid. Actually, there are even more viable options:
Which one to chose depends on the complexity you are ready to face—and the actual requirements that can't be fulfilled with the simplest option of a single executable running a single thread (not counting UI thread, of course).
For example, you may have a requirement that if the application that handles “more powerful widgets” gets killed or crashes, this shouldn't affect the application that runs at the background. Valid need, that would be fulfilled by having two executable files.
If two, what do they communicate, and how?
Here again, there is no single standard. Anonymous pipes and named pipes are usually a way to do it on Windows, but you are by no means forced to use them. Sockets, for instance, are a viable alternative. Another option is for an application to write stuff to a file that is used as stdin of another application. Microsoft's documentation has a thing to tell on this matter:
The following IPC mechanisms are supported by Windows:
- Clipboard
- COM
- Data Copy
- DDE
- File Mapping
- Mailslots
- Pipes
- RPC
- Windows Sockets