1

I am new to c# and .net app development. Currently I built small windows form project. This project has multiple '.cs' forms. I complied the project to an executable and call it from a .net application with the command below. Everything works fine.

System.Diagnostics.Process.Start("C:\Users\WEI\Desktop\Release\DepartmentManagement.exe");

I have a new requirement to open a specific form dynamically when the executable is run. I hard coded the form I want to open by default inside "Program.cs" like below. In this example below I hard coded it to open "ProductionSystem" form by default. I want to make that dynamic.

   namespace TestWinform
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new ProductionSystem());
            }
        }
    }

I want to pass a value to the executable while executing the app. If for example I want to open the form "ProductionDowntime.cs" by default not the "ProductionSystem" then I would like to pass 'ProductionDowntime' as parameter basically making it dynamic. System.Diagnostics.Process.Start("C:\Users\WEIRepService\Desktop\Release\DepartmentDowntime.exe 'ProductionDowntime' "); I want to control this from outside the executable(not from within). Please help. Thanks in advance.

spottedmahn
  • 14,823
  • 13
  • 108
  • 178
user1529514
  • 75
  • 1
  • 9

3 Answers3

3

Try it with a factory method that would encapsulate form instantiating logic

static class Program
{
    static Form CreateFormToOpen(string formName)
    {
        switch (formName)
        {
            case "ProductionDowntime":
                return new ProductionDowntime();

            //  insert here as many case clauses as many different forms you need to open on startup

            default:
                return new ProductionSystem();  //  ProductionSystem is a default form to open
        }
    }

    [STAThread]
    static void Main(string[] args)
    {
        string formName = args.Length > 0 ? args[0] : null;   //  extract form name from command line parameter
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(CreateFormToOpen(formName));    //  use factory method to instantiate form you need to open
    }
}

}

  • THanks for your help. What will be the syntax for command line parameter. I tried below and it didn't work. – user1529514 Nov 10 '17 at 21:56
  • It runs like this: WindowsFormsApp1.exe ProductionDowntime Running without parameter like this: WindowsFormsApp1.exe is equivalent to WindowsFormsApp1.exe ProductionSystem for ProductionSystem is a default – Oleksandr Tyshchenko Nov 10 '17 at 22:54
2

In program.cs you can change

static void Main()

to

static void Main(string[] args)

then use whatever is in args to trigger the right form.

You'd call your program like this

System.Diagnostics.Process.Start("C:\Users\WEI\Desktop\Release\DepartmentManagement.exe TriggerForm1");

where TriggerForm1 is basically the string that would be available in args

using System;
using System.Windows.Forms;

namespace CommandLineParameters_47230955
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());

            if (args.Length > 0)
            {
                switch (args[0].ToLower())
                {
                    case "triggerform1":
                        Application.Run(new Form1());
                        break;
                    case "triggerform2":
                        Application.Run(new Form2());
                        break;
                    default:
                        break;
                }
            }

        }

    }
}
blaze_125
  • 2,262
  • 1
  • 9
  • 19
  • :) I was rushing to test it and you had already provided the example! cheers to you!!! – oetoni Nov 10 '17 at 21:26
  • iam just curious, and testing this. it's said `'The system cannot find the file specified'`. why ?. and i have follow all you instruct. what am i missing ? – chopperfield Nov 13 '17 at 10:55
  • in my main program, iam calling other project with this `System.Diagnostics.Process.Start(@"C:\Users\budi\Documents\Visual Studio 2017\Projects\cs2\cs2\bin\Debug\cs2.exe triggerform1");` – chopperfield Nov 13 '17 at 10:59
2

a piece of cake with using System.Reflection :) I did a small test based on an answer I found here which Kay Programmer has explained incredibly well

Basically you are calling the from from the form's name through its String value. That way you can assign pragmatically any value you like to it.

The "query" part is searching for the specific name of the Form by applying the String argument that we are passing into it and thus at the end using the result in order to initialize the Form for us without using its specific Class name :)

to adapt your example with it try this:

using System.Reflection;    // add this ;)

namespace TestWinform
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)    // change this ;)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (args.Length > 0)       // check here ;)
            {
                var _formName = (from t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
                    where t.Name.Equals(args[0])
                    select t.FullName).Single();
                var _form = (Form) Activator.CreateInstance(Type.GetType(_formName));     // get result and cast to Form object in order to run below
                if (_form != null)
                    _form.Show();
            }
            else
            {
                //no argument passed, no form to open ;)
            }


        }
    }
}

Like @blaze_125 mentioned in his answer you can SWITCH / CASE if you need to send multiple form names and apply a function logic to this.

For example

static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        //Application.Run(new Form1());

        if (args.Length > 0)       
        {
            OpenForm(args[0]);
        }

    }

        public static void OpenForm(string FormName)
        {
            var _formName = (from t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
                where t.Name.Equals(FormName)
                select t.FullName).Single();
            var _form = (Form)Activator.CreateInstance(Type.GetType(_formName));
            if (_form != null)
                _form.Show();
        }
oetoni
  • 3,269
  • 5
  • 20
  • 35