How do I hide a shell window in Linux? - c

I'm developing an application using C that should run on Windows and Linux. This application should hide the shell it runs from. On Windows I was able to fix it by calling the ShowWindow function but on Linux I can't find a way to achieve the same effect.
void main(void)
{
do_stuff();
#ifdef _WIN32
ShowWindow(GetConsoleWindow(), SW_HIDE);
#else
// Linux hide current console
#endif
while(1)
{
do_other_stuff();
}
}

In linux, the "console" (I put quotes around the word for reasons explained below) you call is not such a console, but another application that runs separate of the main application, so you don't have normally full control of it (because the application doesn't know if it is running from the actual system console, from an xterm(1) application, gnome-terminal application, and the like)
Assume you are launching your application from an ssh connection to a remote server, with the DISPLAY environment variable indicating the X11 server to display the info. In that case, the command shell that spawns your application is not a graphical environment "console" but a local shell running on a ssh session started from a remote connection that is completely out of control.
Note about the term "console": The Windows term "console" makes reference to the common POSIX shell interface of starting a process with three (in windows, five) open file descriptors, standard input, standard output, and standard error (in MS-DOS also standard printer and standard communications port) descriptors to allow by default the program to read from its standard input, and write to its standard output and standard error. The term console comes from the fact that, in MS-DOS, (MS-DOS made an improvement from CP/M by making similar system calls as UNIX to read and write to descriptors) all this stuff happened on the console, so they selected (this time in windows) the term "a Windows console application" as a Windows normal application normally didn't provide this interface. For that, Windows requires your program to be linked as a "Windows console" this means to link a special library that opens a Windows window (under control of the application) and makes all input, output and standard error to go there. This makes Windows console applications being capable of controlling the console, as it is an application window, not the case of Linux, that can be, or can be not.
In UNIX systems, the term console applies to a special device (of similar characteristics that the ones used for user sessions) in which the kernel used to start communications with the administrator (something like ---but not equal--- the standard input, standard output and standard error of the kernel) A special device, normally attached to a printer, to show the kernel messages about device errors or kernel security messages. UNIX systems have normally many text devices attached and only one is selected as the console of the system, but due to this difference from Windows machines, Microsoft decided to reinterpret the term to their convenience. Probably a wrong, but accepted decision.

Related

Why does printf output show up in a command prompt?

We all know the basic Hello World program:
#include <stdio.h>
int main() {
printf("Hello World!");
return 0;
}
This will open up a command prompt and show us the "Hello, World" message.
My question is: Why? Why is the message shown in a command prompt and not in notepad for example? Why not as a Windows notification? Why is it specifically the command prompt and not something else?
When you “open” a file through Window’s File Explorer, the system (not necessarily the OS directly; various subcomponents are involved) examines the file. If it is a native Windows application, the system will execute it directly. If it is another kind of file, the system will look up an appropriate application for it. For example, if it is a Microsoft Word file, the system will start Microsoft Word with a request that it open the file.
If the file is a “command line” program, the system will start Windows Terminal (or similar program in various versions of Microsoft Windows) with a request to run the program. More specifically, it may start Windows Terminal with a request to run a particular command-line shell and to have that shell run your program.
The C language grew up in Unix-like environments where a command shell read input from a physical keyboard and write output to a physical display. In modern systems, these are usually replaced by pseudo-devices that perform the same functions in software. When the shell starts a command-line program, it creates a new process with the standard input and standard output streams of that process connected to the pseudo-device that provides the keyboard/display functions. (This is the default. You can also request a shell to start a program with input and output redirected from/to files and other devices.)
Then, when your program writes to standard output, it goes to the pseudo-device, which relays the data to the appropriate parts of the system that cause the text to be displayed in the terminal window.

Send Keystrokes via telnet

How to send multiple keystrokes via telnet. In daily routine, I connect to a server which accept "ESC+3" and "ESC+E" like keystrokes. Now I am trying to automate the process using some programs. For that I have to give keystrokes via programatically. If it is a single line command means, it doesn't make that much complex. But the application expect keystrokes also. So, is there any way to solve this problem.
ESC is just a normal (non printable) character with ASCII code 0x1b. So, if you have an open file descriptor fd to your service, for sending ESC+E the following will do:
write(fd, "\x1bE", 2);
For interactive ttys, there is a program called expect. I haven't used it for a long time, but I was able to find this link: https://www.lifewire.com/linus-unix-command-expect-2201096.
It'll do what you want, I think. It was originally written in TCL (back before Linux was invented). There might be newer versions in something like Python, or some such.
Here's the "blurb":
INTRODUCTION
Expect is a program that "talks" to other interactive programs
according to a script. Following the script, Expect knows what
can be expected from a program and what the correct response
should be. An interpreted language provides branching and
high-level control structures to direct the dialogue.

How to turn a Linux application in C/C++ into a Desktop Environment for a Linux distro?

Is it possible to write an program in C/C++ and then turn that into a Linux Desktop Environment?
I want to take an program, and then be able to boot into my Linux distro and just see that.
Say I have a Linux program which is a window containing "Hello World" on a white background.
How can I make that program into a Linux Desktop Environment for a distro, where you boot and just see: Hello World, on a white background.
Any ideas? Let me know if that made no sense.
Edit: I am not talking about cross-compiling.
You don't want to be modifying rc files. Use your distro's existing mechanism for controlling lightdm/gdm/other and starting X. You want to create a new X session type by writing an Xsession file, so that your DE shows up as another DE alongside KDE and GNOME. Put your script in /usr/share/xsessions (and see the existing examples there).
You either want to
create a boot loader, or
you want to replace the 'shell'.
This would be governed by per-user or global xinit and Xsession files.
Your requirement: Run your own GUI application automatically, after system starts up. Am I right?
Here is what I have done with such requirement (I succefully made it working under Slackware):
Allow auto-login after system boot
Make a customizable Window Manager to be default WM lauchedby startx (I use FVWM)
Configure WM to launch your application after it starts up, and disable unneeded shortcut keys
Edit user's startup script (such as .bashrc or .bash_profile) to startx
Now, you can reboot to see whether it works.

WinAPI C - RunAsUser from REDMON_USER and REDMON_SESSIONID

I installed a PostScript printer driver and have setup REDMON (redmonnt.dll) for redirecting postscript output to my program. In my rather simple c program I capture the data from STDIN and I am able to successfully save it into a .ps file. The file looks OK.
However, I want to start gsview.exe for viewing the file. If I call ShellExecute it fails in Windows 7 because of permission issues. It seems that my program is called under a different user account (LOCAL SERVICE). So I am looking for a way to run gsview.exe under a specific username (the user who initiated the print job) which is available to the program in a variable called REDMON_USER along with the SESSIONID as well.
Q: What are the minimum WinAPI calls required to start a program given a username and a sessionid?
Any code examples in C/C++, .NET would be very helpful.
EDIT: What I am trying accomplish is something very similar to redrunee (from redmonee). I don't want to use redrunee because it opens about a console window for a brief moment.
Note:
1) The program is called by the printer service as [LOCAL SERVICE] account.
2) The first parameter Username (REDMON_USER), in effect, points to the user currently looking at the screen
Look at CreateProcessAsUser.
Also look at CreateProcessWithLogonW and CreateProcess.
They are linked from the CreateProcessAsUser
EDIT In reply to comments by OP.
Follow advice from this thread.
I am copying this here verbatim, in case the original link stops working:
The same code works for us on Vista as
on XP, etc. The service is running as
the Local System.
use WTSGetActiveConsoleSessionId to get the ID of the current active
Windows session at the console (i.e.
the machine keyboard and display, as
opposed to WTS sessions).
use WTSQueryUserToken to get the token for that session.
use DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,
&hTokenDup) to duplicate that token.
use CreateEnvironmentBlock to create an environment that you will be
passing to the process.
use CreateProcessAsUser with the duplicated token and the created
environment. Actually, we use
CreateProcessAsUserW, since the A
version had some sort of bug on some
older systems.
Don't forget to CloseHandle on the various tokens, etc, and to
DestroyEnvironmentBlock the
environment.
Thank you efratian.
PS. Oh joy of Windows programming, did not do it for quite a while. Now I remember why. The only thing that is close or even worse documented is OpenSSH programming.
The documentation describes the "Run as User" feature, which seems to be exactly what you want:
Run as User is intended for launching a GUI program such as GSview locally via RedRun.

Starting process in new Terminal window on Mac

On Windows I can do CreateProcess(..., CREATE_NEW_CONSOLE, ...) and my child process (which is console app, not GUI) will be launched in a new window. What is the easiest way to emulate this on Mac OS?
open -a Terminal.app $(which program) gets a new terminal running the specified program (assuming you're using bash).
You can use execve() (possible after a fork()) to acheive the same thing in compiled code without knowing any Apple APIs (I imagine there is a proper way to do this...).
Read man open.
Edit: you don't need to specify the path to Terminal.app (the finder can figure that out).
If you have X running, it is even easier: just spawn a new xterm with xterm -e program &.
Read man xterm (which will take longer...).
I'll second Chris about the correct use (or lack thereof) of CLI for ordinary mac programs. In my buisness this is expected but the typical user will be {confused|angry|unhappy}.
The Terminal (Terminal.app, what you're referring to as "the console") is just another user-level application on Mac OS X, not a capability of the operating system. There is no direct way in the various APIs available on Mac OS X to just start an executable within a new Terminal window.
However, I believe you can open an executable with Terminal as if it was a document — whether in code or as a user — and it will run in a new session. However, this is not a normal Mac OS X user experience and should not generally be used in Mac software you're going to deliver to end users.
Mac OS X applications are applications. It's fine to provide tools that advanced users can interact with via Terminal, but Terminal is in no way, shape or form a substitute for a real application when delivering software to end users.
I'll add to this that if you're using Cocoa, you can use the NSTask class to start and interact with another process very easily.
Marc Liyanage does this neatly with "term", osascript tell application "Terminal":
http://www.entropy.ch/blog/Mac+OS+X/2005/02/28/Terminal_tricks_8220_term_8221_and_8220_clone_8221.html
(On "typical users": there are different universes, each finding the others strange.
Coming from Unix, I'm used to a process or "| pipe args" anywhere a file can be used;
this helps software componentry immensely.
But open -a does files only -- different universe).

Resources