5

I have a simple question and I'm sure it's been answered, but I can't seem to find the solution I'm looking for.

My basic question is that I've created a console app in .Net that runs automatically on a task scheduler every day, but now my clients also want a windows form-based interface that they can use to run special runs (they use the GUI to specify a few parameters - such as specific dates, etc - to make the program run a bit differently).

The way I thought to do this would be to convert my console app to a WinForm solution and to include Command Line Arguments for when I wanted it to run as the original console app with defaults, but I'm thinking that's not the right way since it would still involve a form load.

My other thought was to convert the "engine" part to a DLL and to make 2 executables - One a console app and one a winforms app, but I'm not sure if that's right either / could lead to more maintenance.

What is the correct way to do this?

I'm writing this in VB, but am equally comfortable with C# solutions if that is easier for you.

Thanks!!

John Bustos
  • 17,454
  • 15
  • 77
  • 131
  • I am very certain that this is a duplicate. EDIT: [Found it](http://stackoverflow.com/questions/4362111/how-do-i-show-a-console-output-window-in-a-forms-application). – Jashaszun Aug 06 '14 at 19:38
  • 3
    You can do what you say and no form must be loaded, modify your Program.cs to parse the command line and if no argument has been passed the create the form (that's the Application.Run line on your Program.cs). – Gusman Aug 06 '14 at 19:42
  • @Jashaszun, thanks for finding that other question, I saw that one too, but the question wasn't HOW to show the console from the forms app, it was whether to go that way or not.... As you can see from the solution I received, the answer told me what to do... Thanks, though!!! – John Bustos Aug 06 '14 at 19:43
  • @JohnBustos Ah I see. Well, I did not mark this as a dup because I thought that it might not be... now I'm glad I didn't. – Jashaszun Aug 06 '14 at 19:44
  • @Gusman - That's an awesome idea too!!!! - Probably even easier than the multiple project solution I was discussing with Reed below!! Thanks! - +1 – John Bustos Aug 06 '14 at 19:44
  • Thanks @Jashaszun!! - Hate that "dupe" flag :p – John Bustos Aug 06 '14 at 19:45
  • @Gusman, I actually like your solution the most!! - Least amount of code changes by far!! - pposada posted something similar and I'd happily accept that as the solution, but you truly did answer first, just via comment... If you want to post a solution saying what you suggest, I'll happily mark it as my answer.... – John Bustos Aug 06 '14 at 19:49
  • 1
    @JohnBustos Don't worry, I'm not here to gain points, I like to help people ;) – Gusman Aug 06 '14 at 19:53

5 Answers5

12

Typically, I'd split the logic into a library, then make a simple console app and a simple Forms app to call into the logic in the library.

You can then distribute these separately and use them as they are intended, without duplication of code.

Reed Copsey
  • 522,342
  • 70
  • 1,092
  • 1,340
  • Thank you so much!! - With all the upvotes, apparently LOTS of people agree :)) - So, to understand, one solution with 3 projects? one .dll, one console app and one winform? – John Bustos Aug 06 '14 at 19:36
  • 1
    @JohnBustos Exactly. Makes life easier over time, even if its more work to setup initially. The "hacks" you can do to make it work otherwise typically make the Forms experience less than ideal. – Reed Copsey Aug 06 '14 at 19:38
  • Thank you SO much!!! - Implementing that now... Too quick to accept your solution as the final answer, but as soon as SO lets me, I will... Thanks again!!!! – John Bustos Aug 06 '14 at 19:40
9

You can modify your Program.cs to accept arguments, then if some args had been passed to your app prcess them and exit from main, else start your main form, something like this:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {

        if (ProcessCommandLine(args))
            return;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    static bool ProcessCommandLine(string[] args)
    {
         //Process it, if some has been processed return true, else return false
    }
}
Gusman
  • 13,944
  • 2
  • 26
  • 43
  • 1
    You can even create a console app, add a reference to System.Windows.Forms and then do Application.Run(whateferformdoyouhave) XD. Visual Studio is making people think a Windows form app is not the same executable type as a Console app, but they are exactly the same, it's just a different template. – Gusman Aug 06 '14 at 20:01
  • Gusman, truly the best solution for what I wanted! - Thank you!! – John Bustos Aug 06 '14 at 20:09
2

Or you can make the form invisible and go with your first option, reading the commandline.

here is a way of making the invitial form invisible. Form Invisible

pposada
  • 93
  • 5
  • Thank you SO MUCH, @pposada!! - Exactly what I'm looking for and would happily mark it as the solution, but Gusman actually posted the same idea earlier in a comment, so I offered him to make his comment a solution since it was the first real solution, but I truly can't thank you enough - It's exactly what I needed!!!! – John Bustos Aug 06 '14 at 19:51
2

Three projects as Reed suggested is a correct approach, however if you really need 1 executable (which we for some reason really wanted in one case) you can do following:

static class Program
{
    [STAThread]
    static void Main(string[] args)
    {
      if (args[0]== "-ui")
      {
         System.Windows.Forms.Application.EnableVisualStyles();
         System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
         System.Windows.Forms.Application.Run(new MyFormWork());
      }
      else if (args[0] == "-console")
      {
         Helper.AllocConsole();
         DoYourConsoleWork();
         Helper.FreeConsole();
      }
}

    public static class Helper
    {

        [DllImport("kernel32.dll")]
        public static extern Boolean AllocConsole();

        [DllImport("kernel32.dll")]
        public static extern Boolean FreeConsole();
    }
Biggles
  • 1,266
  • 1
  • 11
  • 20
0

1: you can use XML for arguments. your console just need to read XML for its argument. then create a form app just for editing XML and save.

Benefit: your app is running by task scheduler so your form do not need to . for user it's easy to open form app and change something that will save to xml

Console --run every day without any notice
Argument.xml  -- argument for Console .
Form  -- user interface 

2: you can mix both within a form but it will run every day in form base not good idea

naqib
  • 60
  • 4