在项目创建期间添加指向现有项目的链接

时间:2010-09-07 13:12:45

标签: visual-studio

我创建了一个自定义VS模板,当用户创建项目来设置项目属性和路径时,它使用IWizard类进行一些自动操作,我设法通过保存来设置一些项目属性,如构建路径。在runStarted方法中,带有$ signs内部参数的csproj文件并在replacementDictionary中设置这些参数。

不幸的是,我在使用相同的方法添加项目作为.csproj的链接时遇到了问题。我有一个.cs文件,我需要添加为现有的和作为创建的每个项目的链接项,它的路径将由用户选择保存项目的位置决定。我已经到了我知道.cs文件路径的部分(绝对和相对于项目的路径)。

这是我到目前为止所尝试的内容:

  • 使用项目的部分保存.csproj文件,并使用路径占位符:
    <Compile Include="$path_to_cs_file\cs_file_name.cs$">
    <Link>$cs_file_name.cs$</Link>
    </Compile>

我已尝试使用绝对路径和相对路径执行此操作,但出于某种原因,这会使VS在Documents and Settings \ user \ Local Settings下使用完全不同的相对路径替换路径。

  • 在RunStarted中,将automationObject转换为DTE并调用它的ItemOperations.AddExistingItem方法。使用任一路径都会导致错误(参数不正确)。

  • 在ProjectFinishedGenerating中,保存项目的路径,然后在RunFinished中,使用该路径创建Microsoft.Build.BuildEngine.Project对象,调用DTE命令保存所有文件并卸载项目,然后调用项目对象的AddNewItem生成的ProjectItem上的方法和SetMetaData,之后我保存项目并使用DTE对象重新加载它,这再次导致与之前相同的错误

我很感激这个主题的任何帮助,我很难过。提前谢谢。

3 个答案:

答案 0 :(得分:2)

我设法“解决”了这个问题,我做了以下几点:

  • 将占位符保留在csproj中,但从未将相关参数添加到替换字典中:

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

  • 在ProjectFinishedGenerated方法中,卸载项目,编辑csproj文件以替换路径,然后重新加载项目:

    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");

注意:上面的代码假设需要修改的项目是当前选定的项目,通常在ProjectFinishedGenerating运行时就是这种情况,但是在多项目模板中或者如果你已经手动将项目添加到解决方案中可能不是这种情况,您必须调用dte方法在项目资源管理器中选择“主”项目,然后继续卸载,编辑和重新加载。这样做的代码看起来像这样:
    UIHierarchy UIH = dte2.ToolWindows.SolutionExplorer;
UIHierarchyItem UIHItem = UIH.UIHierarchyItems.Item(1);
UIHItem.UIHierarchyItems.Item(testProjectName).Select(vsUISelectionType.vsUISelectionTypeSelect);

答案 1 :(得分:1)

如果您不想使用IWizard,另一种解决方法是在TemplateData中的vstemplate中将CreateInPlace设置为true。

    <CreateInPlace>true</CreateInPlace>

答案 2 :(得分:0)

我遇到了完全相同的问题,这让我很生气。

我发现了一个非常脏的解决方法:

在我的情况下,我在RunStarted方法中使用以下内容:

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

这将返回包含文件夹“documents”的路径。调用System.IO.Directory.Exists()确认这是一个有效的目录,但是在检查我的文件系统时,它似乎不存在。如果您将“文档”替换为“我的文档”,然后继续对链接项使用该路径,则一切都可以正常工作。

因此,似乎VS与“documents”目录别名混淆,因此默认为某些疯狂的“AppData”目录。

我希望这会有所帮助,但如果您找到更好的方法,请告诉我们!