Can I add Imports as well as References into project files?

Oct 6, 2010 at 10:20 PM

I would like to make a package that delivers libraries, one of which contains an MSBuild task. In addition to adding references (or instead of?) I would like to add an <Import ... /> Is this possible? Can I add a feature request for this?

Oct 6, 2010 at 10:29 PM

You should be able to do all kind of things that are not directly supported by writing an install.ps1 that automates the VS DTE.  For an example of this, take a look at the install.ps1 that comes with the SQLCE package.  It adds a post build event to the project using DTE.

Oct 6, 2010 at 10:30 PM

You can add an install.ps1 script file to your package that adds the <Import /> element to the project file. install.ps1 is executed after your package is added to the host project.

Oct 6, 2010 at 10:34 PM

awesome. I'm assuming install.ps1 is executed by convention? Is the tools directory the right place to put assemblies that you don't want added as a reference? 

Oct 6, 2010 at 11:12 PM

Probably better to use the DTE api rather than modifying the project file.

Oct 6, 2010 at 11:30 PM

Correct about convention and it needing to be under Tools.

Oct 7, 2010 at 1:48 AM

I will post some api only examples in the next day or two. I have them all ready to go. Life happened so I will get the examples up as I get back into the swing of things.

On Oct 6, 2010 5:31 PM, "davidebb" <> wrote:
> From: davidebb
> Correct about convention and it needing to be under Tools.
Oct 7, 2010 at 5:02 AM

"Probably better to use the DTE api rather than modifying the project file."

Is that possible to do using the ps1 install script?

Oct 7, 2010 at 5:12 AM

Yep. $dte is available in the environment. We also give access to the project in the install (take a look at the SQLCE package). You could do something like this in your install:

$otherProject = Get-Project SomeOtherProject


Oct 7, 2010 at 5:12 AM

Yes, we provide a variable $dte for you to reference DTE.

Oct 7, 2010 at 6:17 AM

NUnit also has a Logo.ico and a .html file in the package directory. Are those used anywhere by convention?

Oct 7, 2010 at 6:23 AM

Nope not right now.

Oct 7, 2010 at 3:42 PM

So I searched all over the web and it seems that there is no way to add an Import element via automation. The closest technique that works is to unload the project, edit it manually, then reload it. I have created a method to do this but trying to do it in PowerShell is very difficult.

Here's the method:

private static void AddImport(string targetPath, DTE dte, IVsSolution solution, Project project)
	string fullName = project.FullName;
	dte.ExecuteCommand("File.SaveAll", string.Empty);

	IVsHierarchy selectedHierarchy;
	solution.GetProjectOfUniqueName(project.UniqueName, out selectedHierarchy);

	var ns = XNamespace.Get("");
	var doc = System.Xml.Linq.XDocument.Load("file://" + fullName);
	var element = new XElement(ns + "Import");
	var attribute = new XAttribute("Project", targetPath);


	dte.ExecuteCommand("Project.ReloadProject", string.Empty);

I did this in a sample VSPackage I created to test this stuff out (since debugging those ps1 scripts during the install is evil!). It works but I don't know how to get the IVsHierarchy and call that crud from the script. You can just call ExecuteCommand("Project.UnloadProject") but it fails if the project node isn't selected (which it won't be if they're clicking on the references node). 

So would it be unreasonable to ask for this as a type of helper method I can call from my script? I can get the path I need for the targets file easily enough, I'm just not sure there's a better way. The lack of support for inserting Imports is pretty dissapointing (in VS automation).

Maybe I'll fork the code and submit a patch...?