Updating Visual Studio project references programa

2019-01-18 13:06发布

I wish to programatically update the references in the projects in my Visual Studio solution.

I have roughly 15 projects in my solution and when I am developing/debugging I want the references to point to the projects within the solution.

As part of my release procedure I sometimes need to make a copy of one project and then update the references to point to built dlls in a certain folder.

I can work out the structure of the project files and how references work within them and I am thinking of building a command line tool to parse the project files and change references as required.

My questions are:
1. Does this sound a sensible thing to do
2. Has anyone experience of this and/or how do they handle switching between developing and release modes
3. Does anyone have any libraries that deal with parsing Visual Studio project files.

CLARIFICATION:

Thanks for the responses. Perhaps I should clarify a few situations where I wish to use this.

a) My application contain 15 projects. I try and keep the solution as small as possible for what I am working on, so say I have 5 projects in my solution. I now need to debug/develop one of the projects not in the solution so I add this project but I have to: - set the references in the original projects to point to project references rather than compiled dlls - change the references in the newly added project to point to the appropriate project references

I would like my tool to do this automatically and the only way I know to so this at present is manipulating the project files

b) As part of a service pack build procedure I take a copy of one of the projects, make the necessary code changes and build using Visual Studio. To do this I have to change all the references to the compiled dlls

6条回答
姐就是有狂的资本
2楼-- · 2019-01-18 13:47

I don't think there is an easy answer to your first question. As a rule, I would recommend avoiding this situation. It's difficult to handle manually, and the code to manage it is not trivial.

That said, I have run into a situation at my job where I simply couldn't get around the problem. In our case, we were working to release an SDK which needed to include a set of sample projects. The "development" version of those projects used both project references as well as references to 3rd party libraries.

That brings us to #3 which is basically, yes. I have actually released an open source project with a library, a simple windows utility and a NAnt extension to automatically change project references to dll references. In fact, it also handles moving those 3rd party libraries to the same local folder and updates those references in the project file.

This solution isn't perfect and there are a lot of improvements I'd like the time to add, but it does work for our situation. Part of our release script which is all in NAnt runs this process to swap out all of the references to a relative path. Then we can easily bundle this whole setup. One day maybe I'll get the time to add an MSBuild Task along with the project.

Again, I think it is best to avoid this as much as possible, but if you get stuck like me - the code I released should at least help.

查看更多
Luminary・发光体
3楼-- · 2019-01-18 13:48

Tiger, Tiger ROAR !!!

This is using the DTE and VSProject to programmatic add references. I commented the code for the majority of the explanation. But to add I did throw a ton of different extra references because i'm kinda lazy. But just sort with Visual Studio and you should be okay. If for any reason this doesn't compile feel free to yell at me.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using EnvDTE;
using EnvDTE80;
using EnvDTE90;
using EnvDTE90a;
using Extensibility;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Design;
using Microsoft.VisualStudio.Shell.Interop;
using VSLangProj;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //Disclaimer: 
            //I am doing this through an extention, Getting 
            //a ref to DTE may not work quite the same for you as 
            //there are several different ways to do it. But the 
            //VSProject stuff shouldn't be an issue

            //Get your DTE Reference, I'm using DTE2 from EnvDTE80 
            //I hadn't dug into whats the earilest compatible version
            //The Package is Microsoft.VisualStudio.Shell.Package
            DTE2 _appObject = Package.GetGlobalService(typeof(DTE)) as DTE2;

            //This gets the first project in the solution set and casts it as a VSProject
            //Note that Web projects use a different type , Something like VSWebProject 
            //or something I forget...
            var pj = (VSProject)_appObject.Solution.Projects.Item(1).Object;

            //Your dll path
            pj.References.Add(@"c:\MyRefs\Pastry.dll");
        }
    }
}


查看更多
做个烂人
4楼-- · 2019-01-18 13:55

I think if you use the Microsoft.Build.BuildEngine library you can manipulate the projects programmatically after loading.

http://msdn.microsoft.com/en-us/library/microsoft.build.buildengine.aspx

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-18 14:00

I think a better approach to this would be to use Conditional blocks on your references inside the project file directly. Then all you need to do is set a particular flag during the msbuild for the "release" build and it will pick up the correct references.

For instance

<ItemGroup Condition="'$(IsRelease)'=='True'">
  <Reference Include="..." />
</ItemGroup>
<ItemGroup Condition="'$(IsRelease)'!='True'">
  <Reference Include="..." />
</ItemGroup>
查看更多
smile是对你的礼貌
6楼-- · 2019-01-18 14:01

There is tool on visual studio gallery that might help you.

It can replace references on your solution with projects when adding them and vice versa if removed.

https://visualstudiogallery.msdn.microsoft.com/056617a4-da39-4d7b-8ecf-933009d9b721

查看更多
Fickle 薄情
7楼-- · 2019-01-18 14:06

Sounds like an odd situation.

My suggestion is this.

  1. Split off the projects that have prebuilt versions into a separate solution. Have them all build to

    \assemblies\fromsource

  2. Copy the prebuilt ones into;

    \assembly\prebuilt

  3. Before developing the rest of the projects, copy either directory into

    \assembly\development

  4. Change your projects to point to the versions in \assembly\development.

So now, you always build your product against precompiled binaries in a known folder, so you never need to change your project. But you can swap between versions at will.

For bonus points, change a prebuild event to copy the dlls across before things start building, and have the source folder vary based on configuration. Then add a PREBUILT configuration alongside DEBUG and RELEASE.

查看更多
登录 后发表回答