65.9K
CodeProject is changing. Read more.
Home

Programmatically add references to Visual Studio .NET

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (13 votes)

Sep 16, 2005

4 min read

viewsIcon

91354

downloadIcon

2703

How to programmatically add references to Visual Studio .NET.

Programmatically Add References Demo

Introduction

In the last few months, I worked on a component that visualizes 3D objects. This component uses MS DirectX and, of course, needs a reference to its DLLs. When I had to test this component, I created a project on the same solution, I added my component to the form, and I saw that Visual Studio automatically added the necessary references to the new project: this was exactly what I expected. On the contrary, when I tried to do the same thing on a new solution (using, as any customer, directly the component) I've noticed a problem: in some conditions Visual Studio is not going to add the references to the new project (although their DLLs are copied into the bin folder)! When I discovered this, I decided to understand how to programmatically add a reference to my project, because I needed to be sure that my dependencies would never be missing. In this way, when the user is adding my control to a form, I check if the references are correctly set (in the Initialize function of my control's designer); in case I don't find them, I try to add them to the project with the code proposed below.

Using the code

All the code is contained in a single class: elRefManager, and the main function you should call is the CheckReferences. This function will do all the job of checking and adding (if necessary) references.

/// <summary>
/// When pressing the button on the form, we check
/// for the presence of the reference indicated in the text box.
/// If that reference is not found, then we will add it to the current project.
/// If the reference cannot be found, an error message is displayed
/// </summary>

private void button1_Click(object sender, System.EventArgs e)
{
    int ec;
    ec=elRefManager.CheckReferences(null, new string[] {textBox1.Text});

    if (ec<0)
        MessageBox.Show("An error occurred adding this reference");
    if (ec>0)
        MessageBox.Show("Could not add " + textBox1.Text + 
                    "\nCheck its spelling and try again");
}

This function requires two parameters, two arrays of strings.

The second array is the list of references to be added (simple names, as you can read them in the references tree of your solution, like System or Microsoft.DirectX).

The first array is a kind of "filter". Since this routine actually works on the active project of all instances of Visual Studio, even the ones you're not interested in, you may want to require a known reference in order to actually add the others you're depending on. I will explain this with a real life example. I've used this filter for the following reason: when the user adds my control to a form, Visual Studio adds a reference to the DLL containing my control (MyControl.dll), but it fails adding the references to the DLLs my control depends on (MyDepDll.dll). Therefore I check if the project contains the reference to my DLL (MyControl.dll) before going on and trying to add the others (MyDepDll.dll).

How the code works

The first thing we should do in order to add new references to the currently open projects, is to get a handle to the instance of Visual Studio. You can see it in the function CheckReferences that we call:

// Get references to the available instances of msdev
ArrayList msdev = GetMSDEVFromGIT();

This function, posted by Ed Dore [MSFT] (thanks Ed!), gets the running object table and looks for the Visual Studio DTE.

Now that we have this array of instances, we loop through each of them, requesting the active project and feeding it to the function CheckReferenceInProject that will actually perform the job of checking and adding references.

When going inside this function, we can see the following block of instructions:

  • Get an instance of VSProject from the Project that has been passed to the function.
  • Test if the filter (where applicable) is compatible with the current project.
  • Loop through all the references that should be added to the project and, for each of them:
    • Check if the reference is already present.
    • If not present, try to add it from the path specified in the registry.
    • If the reference has not yet been found, try to look for it in the path where other references have been found.
    • If the reference is still missing, increase the counter of missed references.

The registry keys that give us the search path for assemblies are the following:

rootkey\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders
rootkey\SOFTWARE\Microsoft\VisualStudio\#.#\AssemblyFolders 
(#.# can be, for example, 7.1 for Visual Studio 2003)

where rootkey can be HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.

As we have just seen, in case we don't find the reference in these folders, we try to look also in the folders where the other references are deployed. Actually it may happen that my DLL (MyControl.dll) and its dependencies (MyDepDll.dll) are on a path that has not been added to the registry. In this case, I can find the reference of the dependant DLLs simply looking into the folder where Visual Studio has found my control's DLL (MyControl.dll).

History

This is the first release.