dparsons
dparsons

Reputation: 2866

Running a Windows application as a Command Line application

I am working on a migration tool that is primarily a Windows Forms application. What I want to do is provide the ability to run the application as a sort of command line utility where parameters can be passed in and the migration occurs completely void of the GUI. This seems straight forward enough and the entry point for my application looks like this:

    [STAThread]
    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainWindow());
        }
        else
        {
            //Command Line Mode
            Console.WriteLine("In Command Line Mode");
            Console.ReadLine();
        }
    }

The problem I am running into is that when execution passes into the else block the text is not wrote back to the user at the command prompt which is problematic as I want to update the user at the command prompt as various executions complete. I could easily write a standalone console application but I was hoping to provide a single tool that allowed to different types of entries for a given scenario. Is what I am looking to do possible and, if so, how is it achieved?

Thanks!

Upvotes: 2

Views: 4105

Answers (3)

BogdanRB
BogdanRB

Reputation: 158

Here is completed runnable example. Compile with:

csc RunnableForm.cs RunnableForm.Designer.cs

RunnableForm.cs:

using System;
using System.Linq;
using System.Windows.Forms;

namespace Test
{
    public partial class RunnableForm : Form
    {
        public RunnableForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("bang!");
        }

        [STAThread]
        static void Main()
        {

            string[] args = Environment.GetCommandLineArgs();
            // We'll always have one argument (the program's exe is args[0])
            if (args.Length == 1)
            {
                // Run windows forms app
                Application.Run(new RunnableForm());
            }
            else
            {
                Console.WriteLine("We'll run as a console app now");
                Console.WriteLine("Arguments: {0}", String.Join(",", args.Skip(1)));
                Console.Write("Enter a string: ");
                string str = Console.ReadLine();
                Console.WriteLine("You entered: {0}", str);
                Console.WriteLine("Bye.");
            }
        }
    }
}

RunnableForm.Designer.cs:

namespace Test
{
    partial class RunnableForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(42, 42);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(153, 66);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // RunnableForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Controls.Add(this.button1);
            this.Name = "RunnableForm";
            this.Text = "RunnableForm";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button button1;
    }
}

Upvotes: 0

Knaģis
Knaģis

Reputation: 21475

Here is a topic that discusses this: http://social.msdn.microsoft.com/forums/en-US/Vsexpressvb/thread/875952fc-cd2c-4e74-9cf2-d38910bde613/

The key is calling AllocConsole function from kernel32.dll

Upvotes: 3

Fenton
Fenton

Reputation: 250802

The usual pattern for this would be to write the logic into a class library that you either call from a visual UI or from a command line application.

For example, if on the UI you accepted "Width", "Height" and "Depth" and then calculated volume you would put the calculation into the class library.

So you have either a Console app accepting three arguments, or a forms app with three inputs, and in both cases, they make the same call...

var volumeCalculations = new VolumeCalculations();
var volume = volumeCalculations.GetVolume(width, height, depth);

The console app is very thin and the forms app is very thin, because all they do is get the inputs to pass to the class library.

Upvotes: 2

Related Questions