2010-09-07 32 views
1

我创建了一个自定义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方法和SetMetaData对得到的项目项,后来我保存项目,并与DTE对象重新加载它,这又导致同样的错误作为前

我想感谢所有帮助与主题,我敢很难过。先谢谢你。

回答

1

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

  • 不停的占位符的的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);

0

我有完全相同的问题,它让我生气。

我已经找到了一个真正的解决办法脏然而:

在我的情况,我使用的方法RunStarted如下:

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

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

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

我希望这可以帮助,但如果你找到一个更好的方式来做到这一点,请让我知道!

+0

我还是设法找到一种解决方法,请参阅我的方法的答案,看看它是否适合你... – JohnoBoy 2010-09-19 06:29:34

+0

感谢您的解决方法,行之有效。唯一的问题似乎是运行后,我得到一个对话框,说“项目不可用”。我只需要点击“确定”,一切都很好(该项目是可用的,并按预期工作)。你知道如何防止这个错误出现吗?它发生在你身上吗? – user450354 2010-09-20 08:59:14

+0

我忘了添加下面的命令:'dte.ExecuteCommand(“Project.ReloadProject”);',我认为这会解决你的问题 – JohnoBoy 2010-09-21 09:36:44

0

,如果你不想更动IWizard另一种解决方案是设置CreateInPlace为true在TemplateData您vstemplate。

<CreateInPlace>true</CreateInPlace>