'Gui-less' windows executable

B

Bit byte

I want to create a GUI-less windows executable (i.e. an executable that
has no gui) and no console. The idea is to have this running as a kind
of daemon (it can't be a service, for reasons I wont go into here ..).

I can't seem to find any code that shows how to do this which is
probably not suprising since Windows is essentially GUI oriented.

One possible hack is to go to the trouble of creating a window and then
making it invisible, but that seems aterrible waste of resources - is
there a cleaner way to do this?
 
G

Guest

You have to have at least one window somewhere, so that Windows can process
messages sent to your application by the system.

However, in Windows 2000 and later, you can make this window a message-only
window. A message-only window has no UI, but can send and receive messages.

You create a message-only window by calling CreateWindowEx and passing in
the value HWND_MESSAGE for the hWndParent parameter.

Sean
 
F

Frederico Pissarra

Bit byte said:
I want to create a GUI-less windows executable (i.e. an executable that has
no gui) and no console. The idea is to have this running as a kind of
daemon (it can't be a service, for reasons I wont go into here ..).

I can't seem to find any code that shows how to do this which is probably
not suprising since Windows is essentially GUI oriented.

One possible hack is to go to the trouble of creating a window and then
making it invisible, but that seems aterrible waste of resources - is
there a cleaner way to do this?

It's perfectly possible to write non console applications GUIless.... just
don't create any window!

There are some problems, f.i:: Timer will not work properly, because it
needs a message loop;

-----------%<------------%<----------
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
/* Example: Write a text file */
FILE *f;

f = fopen("test.txt", "w");
fprintf(f, "Hello\n");
fclose(f);

return 0;
}

-----------%<------------%<----------

[]s
Fred
 
F

Frederico Pissarra

Sean M. DonCarlos said:
You have to have at least one window somewhere, so that Windows can
process
messages sent to your application by the system.

There is no need to create a window if you don't need a message loop...
However, in Windows 2000 and later, you can make this window a
message-only
window. A message-only window has no UI, but can send and receive
messages.

You create a message-only window by calling CreateWindowEx and passing in
the value HWND_MESSAGE for the hWndParent parameter.

Great tip! Thanks!

[]s
Fred
 
J

Jeff Suddeth

Frederico Pissarra said:
It's perfectly possible to write non console applications GUIless.... just
don't create any window!

Here is another way, but it is more complicated. You can use the
FreeConsole() API. But then you have to write some kind of controller
program that starts the server with CreateProcess() and communicates with
that process through some IPC mechanism to shut it down or send other
commands.
 
A

adebaene

Bit said:
I want to create a GUI-less windows executable (i.e. an executable that
has no gui) and no console. The idea is to have this running as a kind
of daemon (it can't be a service, for reasons I wont go into here ..).

I can't seem to find any code that shows how to do this which is
probably not suprising since Windows is essentially GUI oriented.

One possible hack is to go to the trouble of creating a window and then
making it invisible, but that seems aterrible waste of resources - is
there a cleaner way to do this?

Create a GUI subsystem app (ie, one where the start function is
WinMain. With Visual C++, you create such an exe by using the flag
"/subsystem:windows" for the linker).

Simply do NOT create any window in WinMain : just put your processing
stuff here.

Arnaud
MVP - VC
 
W

William DePalo [MVP VC++]

Bit byte said:
I want to create a GUI-less windows executable (i.e. an executable that has
no gui) and no console. The idea is to have this running as a kind of
daemon (it can't be a service, for reasons I wont go into here ..).

As others have mentioned, an option is simply to create a windowed
application (check teh docs for WinMain) and simply choose to create no
windows.

Alternatively, you can create a console application - it's useful to have a
console for debugging - and then to create the process that runs it with
CreateProcess() with the DETACHED_PROCESS or CREATE_NO_WINDOW flag. Check
the docs for the details.

Regards,
Will
 
G

Guest

You have to have at least one window somewhere, so that Windows can
There is no need to create a window if you don't need a message loop...

Perhaps I should make sure to wake up fully before answering posts! :)

Yes, if you don't need a message loop, then you don't need a window. Thanks
for catching my mistake, Fred.

Sean
 
B

Bit byte

William said:
As others have mentioned, an option is simply to create a windowed
application (check teh docs for WinMain) and simply choose to create no
windows.

Alternatively, you can create a console application - it's useful to have a
console for debugging - and then to create the process that runs it with
CreateProcess() with the DETACHED_PROCESS or CREATE_NO_WINDOW flag. Check
the docs for the details.

Regards,
Will
Hi Will,

I like your approach the best. I have looked up the docu (and searched
Google), but all examples so far seem generic and not specific to the
scenario I described here. Could you please provide me with a 'boiler
plate' sample that I can start from.

This could be as simple as :

//Parent
int main(int argc, char* argv[]){
CreateProcess(/*RequiredParams*/); //It would be very useful if you
could show the parent passing some data to the child
}


//child
int main(int argc, char* argv[]){
fprintf(fp,"I was started succesfully\n");
return ;
}


Thanks
 
W

William DePalo [MVP VC++]

Bit byte said:
I like your approach the best.
:)

I have looked up the docu (and searched Google), but all examples so far
seem generic and not specific to the scenario I described here. Could you
please provide me with a 'boiler plate' sample that I can start from.

OK. This example starts the built-in messenger application to pop-up a
message box on the workstation where the user "william" is logged in

char szDir[MAX_PATH + 1];
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };

GetSystemDirectory(szDir, MAX_PATH);

si.cb = sizeof(si);

if ( CreateProcess("c:\\windows\\system32\\cmd.exe", // executable
"/C net send william hello", //
arguments
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
NULL,
szDir,
// default directory
&si,
&pi) )
{
// Don't leak handles

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

My quick hack is an ANSI application. In a UNICODE build, you'd be better
off not using string literals but rather wide-character string buffers
because (at least one of ) the parameters need to be writable.

Regards,
Will
 
J

Jochen Kalmbach [MVP]

Hi William!
if ( CreateProcess("c:\\windows\\system32\\cmd.exe", // executable
"/C net send william hello", // arguments

Just a small note...
This is a bad example, because your passed non-NULL to the first
parameter ;-)

If you pass non-NULL to the fist parameter you should also pass the name
of the EXE as first argument to the second parameter!
Most programs will get confused if you do it they way you have shown ;-)

Greetings
Jochen
 
W

William DePalo [MVP VC++]

Jochen Kalmbach said:
If you pass non-NULL to the fist parameter you should also pass the name
of the EXE as first argument to the second parameter!
Most programs will get confused if you do it they way you have shown ;-)

Right you are. I should learn to stifle the urge to post before 9AM my time.
:)

OP if you are still with us the argument string should have been written as

"cmd.exe /C net send william hello"

You can fully qualify the name of the executable or not. Mostly it doesn't
matter. And by default the traditional array of string arguments (argv) will
be created using spaces to delimit the elements of the array.

Regards,
Will
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top