JohnoBoy
JohnoBoy

Reputation: 565

Add a link to an existing item during project creation

I've created a custom VS template which uses an IWizard class to do some automatic actions when a user creates a project to set project properties and paths, I've managed to set some project properties like build path by saving the .csproj file with parameters inside $ signs and setting those parameters in the replacementDictionary, during the RunStarted method.

Unfortunately I'm having trouble adding items as links to the .csproj using the same method. I have a .cs file I need to add as an existing and as a link item to each project created, it's path would be determined by where the user chooses to save the project. I've got to the part where I know the path of the .cs file, (absolute and relative to the project's path).

Here's what I've tried so far:

I've tried doing this with both absolute and relative paths, but this for some reason makes VS replace the path with a completely different relative path under Documents and Settings\user\Local Settings.

I'd appreciate any help with the subject, I'm pretty much stumped. Thank you in advance.

Upvotes: 1

Views: 1810

Answers (3)

tofutim
tofutim

Reputation: 23374

An alternative solution if you don't want to mess around with IWizard is to set CreateInPlace to true in your vstemplate in TemplateData.

    <CreateInPlace>true</CreateInPlace>

Upvotes: 1

user450354
user450354

Reputation: 11

I'm having exactly the same problem and it's driving me mad.

I have found one really dirty workaround however:

In my situation I am using the following in the RunStarted method:

EnvDTE.DTE dte = automationObject as EnvDTE.DTE;
string solutionPath = System.IO.Path.GetDirectory(dte.DTE.Solution.FullName);

This returns a path which includes the folder "documents". Calling System.IO.Directory.Exists() confirms that this is a valid directory, however on checking my file system, it seems that this does not exist. If you replace "documents" with "my documents", and then continue to use that path for the linked item, all works perfectly.

So it seems that VS is getting confused with the "documents" directory alias and therefore defaulting to some crazy "AppData" directory instead.

I hope this helps, but if you find a better way to do this, please let me know!

Upvotes: 0

JohnoBoy
JohnoBoy

Reputation: 565

I managed to "solve" this issue, what I did is the following:

  • Kept the placeholder in the csproj, but never added the related parameters to the replacement dictionary:

    <Compile Include="$path_to_cs_file$\$cs_file_name.cs$">
    <Link>$cs_file_name.cs$</Link>
    </Compile>

  • At the ProjectFinishedGenerated method, unloaded the project, edited the csproj file to replace the paths, and reloaded the project:

    projectFileName = project.FullName
    // Unload file and manually add the linked item
    dte.ExecuteCommand("File.SaveAll");
    dte.ExecuteCommand("Project.UnloadProject"); // See Note Below
    StreamReader reader = new StreamReader(projectFileName);
    string content = reader.ReadToEnd();
    reader.Close();
    content = Regex.Replace(content, @"\$path_to_cs_file\$", ...);
    content = Regex.Replace(content, @"\$cs_file_name\$", ...);
    StreamWriter writer = new StreamWriter(projectFileName);
    writer.Write(content);
    writer.Close(); dte.ExecuteCommand("Project.ReloadProject");

Note: The above code assumes the project needed modifying is currently selected project, usually when ProjectFinishedGenerating runs this is the case, however in a multi-project template or if you've added a project manually to the solution this might not be the case, you'll have to call dte methods to choose your "main" project in the project explorer, then go on with unloading, editing, and reloading. The code to do so would look something like this:
UIHierarchy UIH = dte2.ToolWindows.SolutionExplorer;
UIHierarchyItem UIHItem = UIH.UIHierarchyItems.Item(1);
UIHItem.UIHierarchyItems.Item(testProjectName).Select(vsUISelectionType.vsUISelectionTypeSelect);

Upvotes: 2

Related Questions