2011-05-10 2 views
5

모든 타사 프로젝트 위치를 나열하는 프로젝트 파일을 가리키는 가져 오기가 포함 된 csproj를 포함하는 프로젝트 템플릿을 만들었습니다. 저는 항상이 프로젝트 템플릿을 사용하여 같은 상대 디렉토리에 프로젝트를 만듭니다.csproj 템플릿에서 상대 가져 오기를 사용하려면 어떻게해야합니까?

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <Import Project="../../../3rdParty/ThirdParty.targets" /> 
    ... 
    <ItemGroup> 
    <Reference Include="Library, Version=$(LibraryVersion), Culture=neutral, PublicKeyToken=$(LibraryPublicKeyToken), processorArchitecture=MSIL"> 
     <SpecificVersion>False</SpecificVersion> 
     <HintPath>$(LibraryDir)LibraryDll.dll</HintPath> 
    </Reference> 
    </ItemGroup> 
    ... 
</Project> 

csproj 파일은 Visual Studio 및 명령 프롬프트에서 msbuild를 실행할 때 제대로 작동합니다.

C:\Users...\AppData\Local\Temp\534cylld.o0p\Temp\MyModule.csproj(3,3): The imported project "C:\Users...\AppData\Local\3rdParty\ThirdParty.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

Visual Studio를 먼저 임시 위치에서 프로젝트를 열려고하는 것 같다 : 나는 다음과 같은 오류가 프로젝트 템플릿을 사용하여 프로젝트를 만들려고합니다. $ (MSBuildProjectDirectory)를 의도 한 위치를 사용하도록 강제 할 수도 있기를 바라는 가져 오기 위치에 추가하려고 시도했지만 작동하지 않습니다.

제안 사항?

+0

가져온 파일을 사용하여 사용자 지정 빌드 작업을 실행한다는 점을 제외하고는 똑같은 문제가 발생합니다. 이 경로는 소스 제어 폴더 계층에 상대적이기 때문에 상대 경로 여야합니다. – madd0

+0

@Christo : 명령 줄에서 빌드를 실행중인 디렉토리에 전체 pah를 제공 할 수 있습니까? – sll

답변

7

vstemplate의 CreateInPlace 속성을 true으로 설정해야합니다. documentation 당신이 임시 위치에 프로젝트가 아닌, 을 만들 어디 장소에서 발생하는 매개 변수 교체해야, 상대 경로가 작동하려면

Specifies whether to create the project and perform parameter replacement in the specified location, or perform parameter replacement in a temporary location and then save the project to the specified location.

을 말한다.

1

내 템플릿 중 일부는 이미 마법사가 필요하기 때문에 주로 Wizards with Project Templates을 사용하여 솔루션을 선택했습니다.

나는 확장하는 모든 내 다른 마법사가 해야하는 기본 클래스를 만들거나 그건 그냥 기본 기능 자체로 사용할 수 있습니다

public class AddTargetsWizard : IWizard 
{ 
    private const string RELATIVE_PATH_TO_TARGETS = @"..\..\..\..\PATH\TO\Custom.Tasks.Targets"; 

    private const string TASK_NOT_FOUND_MESSAGE = @"A project of this type should be created under a specific path in order for the custom build task to be properly executed. 

The build task could not be found at the following location: 
    {0} 

Including the build task would result in unexpected behavior in Visual Studio. 

The project was created, but the build task WILL NOT BE INCLUDED. 
This project's builds WILL NOT benefit from the custom build task."; 

    private string _newProjectFileName; 

    private bool _addTaskToProject; 

    private Window _mainWindow; 

    public AddTargetsWizard() 
    { 
     this._addTaskToProject = true; 
    } 

    protected Window MainWindow 
    { 
     get 
     { 
      return this._mainWindow; 
     } 
    } 

    public virtual void BeforeOpeningFile(EnvDTE.ProjectItem projectItem) 
    { 
    } 

    public virtual void ProjectFinishedGenerating(EnvDTE.Project project) 
    { 
     this._newProjectFileName = project.FullName; 

     var projectDirectory = Path.GetDirectoryName(this._newProjectFileName); 

     var taskPath = Path.GetFullPath(Path.Combine(projectDirectory, RELATIVE_PATH_TO_TARGETS)); 

     if (!File.Exists(taskPath)) 
     { 
      MessageBox.Show(
       this.MainWindow, 
       string.Format(TASK_NOT_FOUND_MESSAGE, taskPath), 
       "Project Creation Error", 
       MessageBoxButton.OK, 
       MessageBoxImage.Error, 
       MessageBoxResult.OK, 
       MessageBoxOptions.None); 

       this._addTaskToProject = false; 
     } 
    } 

    public virtual void ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) 
    { 
    } 

    public virtual void RunFinished() 
    { 
     if (this._addTaskToProject) 
     { 
      var project = new Microsoft.Build.Evaluation.Project(this._newProjectFileName); 

      project.Xml.AddImport(RELATIVE_PATH_TO_TARGETS); 

      project.Save(); 
     } 
    } 

    public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) 
    { 
     var dte = (EnvDTE80.DTE2)automationObject; 

     var mainWindow = dte.MainWindow; 

     foreach (var proc in System.Diagnostics.Process.GetProcesses()) 
     { 
      if (proc.MainWindowTitle.Equals(mainWindow.Caption)) 
      { 
       var source = HwndSource.FromHwnd(proc.MainWindowHandle); 
       this._mainWindow = source.RootVisual as System.Windows.Window; 
       break; 
      } 
     } 

     this.OnRunStarted(automationObject, replacementsDictionary, runKind, customParams); 
    } 

    protected virtual void OnRunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) 
    { 
    } 

    public virtual bool ShouldAddProjectItem(string filePath) 
    { 
     return true; 
    } 
} 

This walkthrough이 마법사를 연결하는 방법에 대한 매우 좋은 설명을 제공합니다 프로젝트 (또는 항목) 템플릿

당신은 내가하지 않는 일을, 같은 표시 마법사 창 등의 추가 기능을 제공 할 필요가 자식 마법사에 대한 가상 OnRunStarted 방법을 제공하는 등, 사전

를 교체를 채우는하고 있음을 알 수 있습니다 이 접근 방식 및/또는 내 구현에 대한 :

  • 일반 프로젝트 템플릿보다 훨씬 복잡합니다.
  • 내 마법사 창 (모든 WPF)이 Visual Studio가 소유자 인 실제 모달 창인 경우 현재 인스턴스의 제목을 사용하여 HWND를 확인하고 연결된 Window을 확인하는 것보다 더 좋은 방법을 찾지 못했습니다.
  • 예상되는 폴더 계층 구조에서 프로젝트를 만들었지 만 Visual Studio가 이상하게 작동하면 (그렇지 않으면 도움이되지 않는 대화 상자가 튀어 오름) 그렇지 않은 경우 모두 좋습니다. 그래서 오류 메시지를 표시하고 현재 프로젝트의 위치가 상대 경로로 작동하지 않으면 Import을 삽입하지 않기로 결정한 것입니다.

누구나 다른 아이디어가 있다면, 나는 여전히 귀입니다.

0

기본 동작은 임시 폴더에 템플릿의 압축을 풉니 다. 그런 다음 매개 변수 대체가 수행됩니다. 어떻게 든 상대 경로는 테스트되고 임시 위치에서는 파일이 존재하지 않습니다.

가져 오기 전에 다음 줄을 추가하려고 했습니까?

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
+0

Microsoft.CSharp.targets을 가져 오면 문제를 해결하는 데 아무런 도움이되지 않습니다. – madd0

0

대신 environment variable을 사용한다고 생각합니다. 귀하의 상황에서 효과가 있습니까?그리고 개발자들 사이에서 프로젝트 템플릿을 공유해야한다면, 자동으로 환경 변수를 설정하거나 개발자가 템플릿 디렉토리가 어디에 있는지 묻는 powershell 스크립트에서 멋진 것을 할 수 있습니다.

[Environment]::SetEnvironmentVariable("3rdPartyTargets", "%ProgramFiles%/3rdParty/ThirdParty.targets", "User") 

그리고 csproj 매크로

는 :

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <Import Project="$(3rdPartyTargets)" /> 
    ... 

아 기다립니다. 그것은 C++에서 작동하지만, C#/vb.net 프로젝트에서는 to use msbuild 일 수 있습니다.

관련 문제