GUI and Console Apps

M

MumboJumbo

Hi I have a really basic question hopefully some can help me with:

Can you write a (i.e. one) C# project that works from the cmd line and gui?

I seems if i write a GUI app it can't write to console using
System.Console.WriteLine if thge project has its "Output Type" to
"Windows Application".

However I can write to stdio if i set output type to "Console
Application". When I do this I unfortunately get a "console box" as well
as the UI when i start the UI without command line instructions.

Cheers,
JIm
 
G

Guest

Surely if you want to write to the console then you'd want to see the
console box as you want to write to it?

or do you only want to see the console when it's run from cmd? (in which
case, compile as GUI, run from cmd)

I think I'm not understanding what you want.... can you explain more?
 
M

MumboJumbo

I want an app that will do this:

cmd.exe ... start the gui with a new workspace
cmd.exe file.xml ... start the gui with file.xml

But when a certain group of extra args are used it will run as a console
app ... -applytransform junk.xlst file.xml ... etc ...


Jim
 
G

Guest

"or do you only want to see the console when it's run from cmd? (in which
case, compile as GUI, run from cmd)"

Sorry, thats clearly not true - what was I thinking!

I think my question back to you is; Why do you want to write to the console
when the application is a GUI?

If for debugging only --> System.Console writes to the output window of
Visual Studio, so you'll see it when developing / debugging etc.

If for other reasons, maybe write to a log file on disk? Maybe only create
the log file when the App.config has a "log=on" flag set - allow it to be
turned on / off ?
 
G

Guest

Compile as GUI --> you can still start it from the command line.

make your main like this:

static void Main(string[] args) {
//do argument "magic" here:
if (args!=null){
string firstParameter = args[0];
}
}

--> Check this for some nice code to pull out your parameters:
http://www.codeproject.com/csharp/CpCommandLineEmailer.asp
//take a look at Main and CommandLineParser(string sCommandLine)

Assuming you don't want to run in a batch environment - I'd personally not
bother with the command line parameters, and use the App.config to push
parameters into the application. If you are running in batch - don't do a GUI
!

If the parameters change frequently, maybe have the ability to store them in
a file somewhere and then read that file in.

If you want to kick it off from the command line and then have it auto kill
the "black window" - I'm not sure this is possible....

Check out using App.config and look into
System.Configuration.ConfigurationSettings.AppSettings
 
W

William Stacey [MVP]

A common pattern to achieve this is:
- Create two apps. One gui and one console by the same name and put them in
the same directory.
- Name the console version *.com and the gui *.exe. The .com will be found
first in the normal search order so you console app will start first.
- Your console app will parse the command line. If console args, the app
continues as your normal.
- If args dictate GUI args, you Process start the *.exe command in same dir
passing in the args.

This will allow your console version to use the parent console as you would
expect (i.e. no new console). And will also allow you to start the GUI
version based on args and leave the current console intact. A desktop icon
or start menu would point the exe version if you wanted gui. From console
you could also specify *.exe if you wanted direct access to the gui version.
hth
 
M

MumboJumbo

Sorry I have a requirement from my boss that:

1.) i have 1 executable ...
2.) this one excutable will start in GUI mode when started with no args ...
3.) and start in CLI mode when there is args ...
4.) The CLI has to be executable from with in a makefile and should be
seemless ...


The GUI code is nearly 3 years old ... and now I need CLI functioanality
....

Thanks again,
Jim
 
M

MumboJumbo

Thank you ... this is what i was trying to get at ...

So you must have two apps if you would like "typical" console
interaction ...

Thanks,
Jim
 
M

Manfred Braun

Hi All,

I really thought, there would be some help by the experts I am not of this
type], but I have stored some - for me importent - resoures.

Try the code [C#] at the end, it works for me.

Hope, this helps,
Best regards,
Manfred Braun

(Private)
Mannheim
Germany

mailto:[email protected]
(Remove the anti-spam-underscore to mail me!)

===================================================================

/*
Compile: csc /t:exe /out:DualTest2.exe DualTest2.cs
from http://www.dotnet247.com/247reference/msgs/17/88693.aspx
Other console-realted code was published by Matthias Sjögren.
*/

using System;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Runtime.InteropServices; //Needed for WIN32API-calls.
using System.Threading;
using System.Windows.Forms;


class DualTest
{
private static string strAppName = "DualTest";
public static bool useWindow = false;
public static Form Form1 = new Form();
public static int intFreeConsoleRTC;

static int Main(string[] args)
{
//Read application specific settings:
try
{
useWindow =
bool.Parse(ConfigurationSettings.AppSettings["AlwaysUseWindow"]);
}
catch(System.Exception)
{}

if( (args.Length == 0) || (useWindow) )
{
Console.WriteLine("No args, using a window...");
intFreeConsoleRTC = FreeConsole();
if(intFreeConsoleRTC != 0)
{
try
{
/*
The Thread.Sleep() demonstrates, that the console is detached. If one
starts this proggi with a doubleclick in windows explorer, first,
a console window opens. After calling "FreeConsole()", the
console window disappears. The delay is made, to show this effect,
because opening the form is delayed.
*/
Thread.Sleep(2500);

//First method, de-commented now:
Application.Run(Form1);

//This could also be used!
//System.Windows.Forms.MessageBox.Show("Hello, world!");
}
catch(Exception e)
{
//Do something here
}
}
else
{
//The console was NOT detached for some reasons, we can continue writing
there...
Console.WriteLine("Console was NOT freed, reason:" +
intFreeConsoleRTC );
}
return 1;
}
else
{
//We use the existing arguments and proceed...
Console.WriteLine(strAppName + ", have all, NOT using a window.");

return 0;
}
}


[DllImport("kernel32.dll")]
private static extern int FreeConsole(); //BOOL FreeConsole(VOID);
}

===================================================================
 
W

William Stacey [MVP]

Yes. The best I have been able to find over the years. MS also uses this
pattern for many of their tools that have both gui and console versions. I
am all ears if anyone has a better way.
 
M

MumboJumbo

Thats perfect!!!!!!!!


Thank you soooo much ...


Jim

Manfred said:
Hi All,

I really thought, there would be some help by the experts I am not of this
type], but I have stored some - for me importent - resoures.

Try the code [C#] at the end, it works for me.

Hope, this helps,
Best regards,
Manfred Braun

(Private)
Mannheim
Germany

mailto:[email protected]
(Remove the anti-spam-underscore to mail me!)

===================================================================

/*
Compile: csc /t:exe /out:DualTest2.exe DualTest2.cs
from http://www.dotnet247.com/247reference/msgs/17/88693.aspx
Other console-realted code was published by Matthias Sjögren.
*/

using System;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Runtime.InteropServices; //Needed for WIN32API-calls.
using System.Threading;
using System.Windows.Forms;


class DualTest
{
private static string strAppName = "DualTest";
public static bool useWindow = false;
public static Form Form1 = new Form();
public static int intFreeConsoleRTC;

static int Main(string[] args)
{
//Read application specific settings:
try
{
useWindow =
bool.Parse(ConfigurationSettings.AppSettings["AlwaysUseWindow"]);
}
catch(System.Exception)
{}

if( (args.Length == 0) || (useWindow) )
{
Console.WriteLine("No args, using a window...");
intFreeConsoleRTC = FreeConsole();
if(intFreeConsoleRTC != 0)
{
try
{
/*
The Thread.Sleep() demonstrates, that the console is detached. If one
starts this proggi with a doubleclick in windows explorer, first,
a console window opens. After calling "FreeConsole()", the
console window disappears. The delay is made, to show this effect,
because opening the form is delayed.
*/
Thread.Sleep(2500);

//First method, de-commented now:
Application.Run(Form1);

//This could also be used!
//System.Windows.Forms.MessageBox.Show("Hello, world!");
}
catch(Exception e)
{
//Do something here
}
}
else
{
//The console was NOT detached for some reasons, we can continue writing
there...
Console.WriteLine("Console was NOT freed, reason:" +
intFreeConsoleRTC );
}
return 1;
}
else
{
//We use the existing arguments and proceed...
Console.WriteLine(strAppName + ", have all, NOT using a window.");

return 0;
}
}


[DllImport("kernel32.dll")]
private static extern int FreeConsole(); //BOOL FreeConsole(VOID);
}

===================================================================
Thank you ... this is what i was trying to get at ...

So you must have two apps if you would like "typical" console
interaction ...

Thanks,
Jim

William Stacey [MVP] wrote:

them in
found

app

dir

would

icon

console

version.
 
M

MumboJumbo

I found this code in german online ... it prevents one problem with that
last code posting: "the exec crashes if you call
system.console.writeline()" ...

Jim

[DllImport("Kernel32.dll")]
private static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd,Int32 nCmdShow);

/// <summary>->Set to true, if the Application should run again
/// even after closing. This is used for setting a new Language.</summary>
public static bool RunAgain=false;

private const Int32 SW_HIDE = 0;

/// <summary>The main entry point for the application.</summary>
[STAThread]
static void Main()
{
try {IntPtr hwnd = GetConsoleWindow();
if (hwnd!=IntPtr.Zero) ShowWindow(hwnd, SW_HIDE);}
catch {}
AnzArgs= Environment.GetCommandLineArgs().Length;
Args = Environment.GetCommandLineArgs();
if (AnzArgs != 1) // Console
{
Console.WriteLine(Application.ProductName+ " started.");
Application.Run(new Form1());
Console.WriteLine(Application.ProductName+ " finished."));
return;
}
do {Application.Run(new Form1());} while (RunAgain);
// Letzteres ist für dynamische Sprach-Umschaltung.

}
Thats perfect!!!!!!!!


Thank you soooo much ...


Jim

Manfred said:
Hi All,

I really thought, there would be some help by the experts I am not of
this
type], but I have stored some - for me importent - resoures.

Try the code [C#] at the end, it works for me.

Hope, this helps,
Best regards,
Manfred Braun

(Private)
Mannheim
Germany

mailto:[email protected]
(Remove the anti-spam-underscore to mail me!)

===================================================================

/*
Compile: csc /t:exe /out:DualTest2.exe DualTest2.cs
from http://www.dotnet247.com/247reference/msgs/17/88693.aspx
Other console-realted code was published by Matthias Sjögren.
*/

using System;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Runtime.InteropServices; //Needed for WIN32API-calls.
using System.Threading;
using System.Windows.Forms;


class DualTest
{
private static string strAppName = "DualTest";
public static bool useWindow = false;
public static Form Form1 = new Form();
public static int intFreeConsoleRTC;

static int Main(string[] args)
{
//Read application specific settings:
try
{
useWindow =
bool.Parse(ConfigurationSettings.AppSettings["AlwaysUseWindow"]);
}
catch(System.Exception)
{}

if( (args.Length == 0) || (useWindow) )
{
Console.WriteLine("No args, using a window...");
intFreeConsoleRTC = FreeConsole();
if(intFreeConsoleRTC != 0)
{
try
{
/*
The Thread.Sleep() demonstrates, that the console is detached. If
one
starts this proggi with a doubleclick in windows explorer, first,
a console window opens. After calling "FreeConsole()", the
console window disappears. The delay is made, to show this effect,
because opening the form is delayed.
*/
Thread.Sleep(2500);

//First method, de-commented now:
Application.Run(Form1);

//This could also be used!
//System.Windows.Forms.MessageBox.Show("Hello, world!");
}
catch(Exception e)
{
//Do something here
}
}
else
{
//The console was NOT detached for some reasons, we can continue
writing
there...
Console.WriteLine("Console was NOT freed, reason:" +
intFreeConsoleRTC );
}
return 1;
}
else
{
//We use the existing arguments and proceed...
Console.WriteLine(strAppName + ", have all, NOT using a window.");

return 0;
}
}


[DllImport("kernel32.dll")]
private static extern int FreeConsole(); //BOOL FreeConsole(VOID);
}

===================================================================
Thank you ... this is what i was trying to get at ...

So you must have two apps if you would like "typical" console
interaction ...

Thanks,
Jim

William Stacey [MVP] wrote:


A common pattern to achieve this is:
- Create two apps. One gui and one console by the same name and put


them in
the same directory.
- Name the console version *.com and the gui *.exe. The .com will be

found

first in the normal search order so you console app will start first.
- Your console app will parse the command line. If console args, the

app

continues as your normal.
- If args dictate GUI args, you Process start the *.exe command in same

dir

passing in the args.

This will allow your console version to use the parent console as you

would

expect (i.e. no new console). And will also allow you to start the GUI
version based on args and leave the current console intact. A desktop

icon

or start menu would point the exe version if you wanted gui. From

console

you could also specify *.exe if you wanted direct access to the gui

version.

hth
 
M

MumboJumbo

Sorry thats: "the exec crashes if you call
system.console.writeline() after FreeConsole()"
I found this code in german online ... it prevents one problem with that
last code posting: "the exec crashes if you call
system.console.writeline()" ...

Jim

[DllImport("Kernel32.dll")]
private static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd,Int32 nCmdShow);

/// <summary>->Set to true, if the Application should run again
/// even after closing. This is used for setting a new Language.</summary>
public static bool RunAgain=false;

private const Int32 SW_HIDE = 0;

/// <summary>The main entry point for the application.</summary>
[STAThread]
static void Main()
{
try {IntPtr hwnd = GetConsoleWindow();
if (hwnd!=IntPtr.Zero) ShowWindow(hwnd, SW_HIDE);}
catch {}
AnzArgs= Environment.GetCommandLineArgs().Length;
Args = Environment.GetCommandLineArgs();
if (AnzArgs != 1) // Console
{
Console.WriteLine(Application.ProductName+ " started.");
Application.Run(new Form1());
Console.WriteLine(Application.ProductName+ " finished."));
return;
}
do {Application.Run(new Form1());} while (RunAgain);
// Letzteres ist für dynamische Sprach-Umschaltung.

}
Thats perfect!!!!!!!!


Thank you soooo much ...


Jim

Manfred said:
Hi All,

I really thought, there would be some help by the experts I am not of
this
type], but I have stored some - for me importent - resoures.

Try the code [C#] at the end, it works for me.

Hope, this helps,
Best regards,
Manfred Braun

(Private)
Mannheim
Germany

mailto:[email protected]
(Remove the anti-spam-underscore to mail me!)

===================================================================

/*
Compile: csc /t:exe /out:DualTest2.exe DualTest2.cs
from http://www.dotnet247.com/247reference/msgs/17/88693.aspx
Other console-realted code was published by Matthias Sjögren.
*/

using System;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Runtime.InteropServices; //Needed for WIN32API-calls.
using System.Threading;
using System.Windows.Forms;


class DualTest
{
private static string strAppName = "DualTest";
public static bool useWindow = false;
public static Form Form1 = new Form();
public static int intFreeConsoleRTC;

static int Main(string[] args)
{
//Read application specific settings:
try
{
useWindow =
bool.Parse(ConfigurationSettings.AppSettings["AlwaysUseWindow"]);
}
catch(System.Exception)
{}

if( (args.Length == 0) || (useWindow) )
{
Console.WriteLine("No args, using a window...");
intFreeConsoleRTC = FreeConsole();
if(intFreeConsoleRTC != 0)
{
try
{
/*
The Thread.Sleep() demonstrates, that the console is detached.
If one
starts this proggi with a doubleclick in windows explorer, first,
a console window opens. After calling "FreeConsole()", the
console window disappears. The delay is made, to show this effect,
because opening the form is delayed.
*/
Thread.Sleep(2500);

//First method, de-commented now:
Application.Run(Form1);

//This could also be used!
//System.Windows.Forms.MessageBox.Show("Hello, world!");
}
catch(Exception e)
{
//Do something here
}
}
else
{
//The console was NOT detached for some reasons, we can continue
writing
there...
Console.WriteLine("Console was NOT freed, reason:" +
intFreeConsoleRTC );
}
return 1;
}
else
{
//We use the existing arguments and proceed...
Console.WriteLine(strAppName + ", have all, NOT using a window.");

return 0;
}
}


[DllImport("kernel32.dll")]
private static extern int FreeConsole(); //BOOL FreeConsole(VOID);
}

===================================================================

Thank you ... this is what i was trying to get at ...

So you must have two apps if you would like "typical" console
interaction ...

Thanks,
Jim

William Stacey [MVP] wrote:


A common pattern to achieve this is:
- Create two apps. One gui and one console by the same name and put



them in

the same directory.
- Name the console version *.com and the gui *.exe. The .com will be



found

first in the normal search order so you console app will start first.
- Your console app will parse the command line. If console args, the



app

continues as your normal.
- If args dictate GUI args, you Process start the *.exe command in
same



dir

passing in the args.

This will allow your console version to use the parent console as you



would

expect (i.e. no new console). And will also allow you to start the
GUI
version based on args and leave the current console intact. A
desktop



icon

or start menu would point the exe version if you wanted gui. From



console

you could also specify *.exe if you wanted direct access to the gui



version.

hth
 

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