Reputation: 4763
I've created a program that has two projects: a windows UI and an "engine". I would like to make it so that the user can execute the program from a command prompt passing in some arguments and the engine will automatically execute them and spit out the results. OR the user can launch the UI and choose all of their options via dropdown lists and such and then click a button to tell the engine to do it's work. I actually already have it working using something I found a long time ago, but I'm trying to see if there's an easier way. The way I found involves adding a Win32 class and creating externals to AllocConsole, FreeConsole, and AttachConsole from kernel32.dll. Is there an easier way? Thanks.
Upvotes: 4
Views: 1825
Reputation: 66573
Create four separate configurations, two for GUI and two for Console:
The above screenshot is for solution configurations. You’ll have to do the same again for the project (in the above screenshot the project that has those four configurations is Rummage). Here is an excerpt from Rummage.csproj
:
[...]
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugGui|AnyCPU' ">
<OutputType>WinExe</OutputType>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseGui|AnyCPU' ">
<OutputType>WinExe</OutputType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugConsole|AnyCPU'">
<OutputType>Exe</OutputType>
<DefineConstants>DEBUG;TRACE;CONSOLE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseConsole|AnyCPU'">
<OutputType>Exe</OutputType>
<DefineConstants>TRACE;CONSOLE</DefineConstants>
<Optimize>true</Optimize>
</PropertyGroup>
[...]
Notice especially:
The Console configurations have <OutputType>Exe</OutputType>
(that makes them a console app) while the Release configurations have <OutputType>WinExe</OutputType>
.
Both Console configurations have the CONSOLE
constant defined. That way you can use #if CONSOLE [...] #else [...] #endif
to have console-/GUI-specific code. For example, the Main method might look like this:
[STAThread]
static int Main(string[] args)
{
#if CONSOLE
return MainConsole(args);
#else
return MainGui(args);
#endif
}
... and then you can have the WinForms stuff in MainGui
and the command-line parsing stuff in MainConsole
.
This way you can run (and debug) either the GUI or the console version in Visual Studio, while in a build script you can simply build all of them (and into different directories or different EXE file names).
Upvotes: 1
Reputation: 161773
It's even simpler. Create a Console application. It will parse the command line to get the parameters, then will call your engine.
Let the WinForms application worry about GUI, let the Console application worry about the command-line.
Upvotes: 1
Reputation: 44595
it's simple, make your windows forms application and in the Main
method check the command line parameters and in case your parameters are there, instead of calling
Application.Run(new Form1());
simply call your engine and start processing.
it's important to code your engine properly and have also the UI using the same engine when the user is starting those commands from the user interface, so to avoid any useless code duplication.
we use this approach in many programs and we are satisfied, if you do not call Application.Run(...)
your program will simply terminate when the Main
method ends.
Upvotes: 3