Where am I building?

One of the cool things about Visual Studio is that it hides much of the project deployment and configuration from the developer.  For example, if you create a new console project in Visual Studio 2010, type in a couple lines of code,  and hit Run (F5), things just work.  You get a .exe created and it runs.

Microsoft does a good job explaining all that is going on here.  If you haven’t read through these posts, I highly recommend that you do – you can understand the magic that is going on.  There are some conventions that Visual Studio uses that are not necessarily documented clearly.  Note that I am using C#.

When you create a new Console project, Visual Studio places a directory on your file system that you specify in the Location text box.

image

In that directory, it creates a .csproj file, a Program.cs file, and 3 directories.

image

If you open bin, there is a folder called Debug and in that folder, there are these files that VS2010 created for you:

image

These files are the linkers between your soon-to-be-running .exe and visual studio – it associates VS2010 debugging with your project.  A full explanation can be found here.   If you double-click on it (it is a .exe after all)…. Nothing happens. 

The obj folder has a series of subfolders and 1 file:

image

The stuff in the obj folder is none of your concern.  It is the place where Visual Studio 2010 takes your source files and creates a working assembly.   If you open the .cache file in notepad, you get semi-readable stuff:

image

In any event. the last folder, Properities, contains code files that you can update.  In this case, it contains a file called AssemblyInfo.  This file contains meta data about your application.  If you open it in notepad, it looks like this:

image 

You can enter info there, or you can use that fancy-pants IDE VS2010 via the Properties Page->AssemblyInformation button:

image

image

However, once you alter it via VS2010, the Properties file does not reflect it until you save the file…

The last stop on this little tour is the .csproj file.  This file is actually a MSBuild file – which means

1) It is well-formed XML

2) It is really hard to read

Most of the projects that I see that are in trouble suffer from dependency bloat – they rely on tons and tons of 3rd party libraries (each versioned differently), other parts of the .NET framework, etc..  The .csproj file is where VS2010 keeps tracks of these dependencies.  This is also where VS2010 keeps tracks of all of those code files that you create/write that vshost uses.

Next, in the build tab of the project properties, there is an Output Path field.  The default is bin\Debug.

image 

This is where VS2010 (vshost actually)  actually creates the .exe.  The reason I bring this up is that if you have 3rd party components that your application is using that are not in the GAC,  VS2010 attempts to build those .dlls and place them in the same directory as the running .exe (assuming you had it marked as Copy Local)

image

If you don’t want VS2010 to put the dependent .dlls, mark them as copy local – false and have them placed in the output directory manually.

Anyway – hope this helped someone  – it certainly helped me…

Start me up!

When you create a new Windows Form project, you get a Form1 out of the box.  In that Form’s code behind, you get a constructor with a call to initialize component.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
}

When you hit F5 to run the application, how does the .NET runtime know to launch Form1?  The answer is that Visual Studio pre-builds another module called Program where there is 1 method, static void Main, that looks like this.

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

So how does the .NET runtime know to look for Program.Main to run?  The answer is that the .NET runtime has hard-coded into its logic to look for static void Main() as described here.  That means that you can put static void Main anywhere in your project and the .NET Runtime will find it.*

The reason I bring this up is because I was peer-reviewing a Windows Form project that had removed the Program file/class and stuck static void main in the code behind of Form1 – and static void main called, you guessed it, Form1.  For a second I froze thinking that they created a recursive loop, when I realized that static void Main only gets called once – Form1 never actually uses it.

In any event, a better practice would be to have a separate module (called Program, MyGreatProgram, whatever) to launch the Form(s) and do whatever pre-processing I necessary.

 

 

* Note that you can override this default behavior by using the Startup object property in the project’s property page:

image

By having as (Not Set), the .NET runtimes looks for static void Main.  You can override this with your own class.method.  For example:

public class MyStartupClass
{
    public static void Main()
    {
        Application.Run(new Form1());
    }
}

and then point to it:

image

Note that if you remove all static void main methods in your project, you will get this exception:

Error    1    Program ‘C:\Users\Jamie\Documents\Visual Studio 2010\Projects\Tff.FormStartupExample\Tff.FormStartupExample\obj\x86\Debug\Tff.FormStartupExample.exe’ does not contain a static ‘Main’ method suitable for an entry point    Tff.FormStartupExample