views:

421

answers:

5

Hello,

I have a C# based solution in Visual Studio 2008 for a given problem domain. This solution has 1 + 5 projects. The first project is for resources that spans across the other 5 projects.

Each project has multiple forms. By default, the build generates one executable per project. What I want rather is each form, which has no mutual dependency to the rest, to produce a stand-alone executable.

I am aware that I could break each of the 5 prime projects into multiple projects and set "Startup Project" to "Multiple startup projects" and achieve my objective. But that will over-populate the solution with the number of projects increasing to mid double digits. I do not want to pursue the route of having a separate solution for the each of the 5 projects.

Right now I invoke Application.Run as follows to accomplish my goal:

Application.Run(new fooForm());

and when I need to create an executable for another independent form, I change the form value to

Application.Run(new barForm());

and so on until I need another shot of espresso.

Any hack to accomplish what I intend without me having to jump out of the window?

A: 

There's nothing built into Visual Studio to give you what you want.

Any hack to accomplish what I intend without me having to jump out of the window?

If you're after a hack, you might want to look at running ilasm.exe and ildasm.exe as part of a post build step: disassemble the 5 EXEs and reassemble them into >5 EXEs according to whatever rule you're following.

Tim Robinson
@Tim Robinson: Thanks for your recommendation. For lack of time and proficiency, I deferred taking the route of using ilasm.exe, ildasm.exe.
t3
A: 

I would suggest creating a template .csproj file and creating many of them with a small C# or Perl program, filling in the template with the values based on the forms in your solution. You could then aggregate the .csproj files using a batch or Perl script for compilation using devenv.exe from the command line.

No real "clean" way.

sixlettervariables
@sixlettervariables: I combined your recommendation and Oliver John's to create a batch of scripts that works to my content. You are right, no "clean" way!
t3
+2  A: 

Perhaps it is an option for you to leave everything in one EXE file per project and decide at running time which Form to start with. For example, you could make copies of your EXE file with different names, determine the name of the EXE from

  Assembly.GetExecutingAssembly().Location

and use this information to select the Form you put to 'Application.Run'.

Or, you don't make copies and call your EXE with appropriate command line parameters. It depends on how your users select between the different database reports.

Edit: here is a simple example (untested):

[STAThread]
static void Main(string[] args)
{
    if(args.Length<1)
         return;
    if(args[0]=="Form1")
         Application.Run(new Form1());
    else if(args[0]=="Form2")
         Application.Run(new Form2());
}
Doc Brown
It is a viable option to leave everything in one .exe file per project. I am going to experiment with the first part of your recommendation.Can you please give me an example of how to call a single .exe that has multiple forms bundled to run a different form based on a command line parameter?
t3
+1  A: 

Using Doc Brown's idea of just using different names for the exe-files, the following code will run the app using a form with the same name as the exe (MyNamespace.MyForm.exe will start the app with MyNamespace.MyForm as startup-form)

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        string FullPath = Assembly.GetExecutingAssembly().Location;
        string ExeName = Path.GetFileNameWithoutExtension(FullPath);
        Type TypeBasedOnExeName = Assembly.GetExecutingAssembly().GetType(ExeName);
        Form StartupForm = (Form)Activator.CreateInstance(TypeBasedOnExeName);

        Application.Run(StartupForm);
    }
Oliver John
@Oliver John: Thanks. I combined your recommendation and sixlettervariables' to create a batch of script that works to my content.
t3
+1  A: 
  1. Add the Main-function to each form-class and have it run itself.
  2. Create a batch-file per form/exe to compile the project using the command-line compiler (csc.exe for C#), specifying which class (form) contains the Main-method to use.

    public partial class Form2 : Form { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form2()); } }

Compile an executable for form2 using something like: csc.exe /out:Form2.exe Form2.cs Form2.designer.cs /Main:WindowsFormsApplication1.Form2

Oliver John