2012-05-16 2 views
2

문제점 : 실행 파일을 빌드하는 프로세스가 있습니다. setup/deploy 프로젝트 빌드를 실행하기 전에 setup/deploy 프로젝트의 FileSystem/Common Documents 폴더에 포함되어야하는 파일을 빌드합니다. 파일 이름이 항상 동일한 파일 이름으로 작성되는 경우에는 매우 간단합니다. 그러나 프로세스가 각각의 연속 실행시 고유 한 파일 이름을 만들 수 있기 때문에 파일 이름을 미리 결정할 수없는 경우가 있습니다..NET의 ProjectSystem에 프로그램 적으로 파일을 추가 프로젝트 설치

질문 : 프로그래밍 방식으로 파일 시스템/공통 문서 폴더에 파일을 추가하려면 어떻게합니까?

내 연구 : 나는 사용자 지정 작업으로 보였지만/설정의 파일 시스템을 참조 나는이 파일을 추가 할 수 있도록 프로젝트를 배포하는 방법을 확실 해요했다.

상세 정보는 우리의 일상 빌드 프로세스의 일환으로 , 우리는 * .cfs의 형태로 파일이 전날 다른 파일 이름을 가질 수 http://lucene.apache.org/ (루씬) 인덱스를 만들 수 있습니다. Visual Studio에서 vdproj 파일을 열지 않고 파일 시스템 편집기를 사용하여 파일 이름을 수동으로 바꾸기를 원하지 않기 때문에보다 자동화 된 접근 방식이 필요했습니다. 우리의 솔루션

는 솔루션으로서, 나는 TFS 팀 빌드에 http://www.ewaldhofman.nl/post/2011/04/06/Customize-Team-Build-2010-e28093-Part-16-Specify-the-relative-reference-path.aspx (에 발트 호프만의) 훌륭한 튜토리얼을 사용했다. 여기서는 체크 아웃 활동 및 체크인 활동을 복제하면서 vdproj 파일을 열고 사전 생성 된 Lucene 색인 파일 이름에 따라 파일을 편집하는 자체 사용자 정의 활동을 추가했습니다.

코드 예

 

    protected override void Execute(CodeActivityContext context) 
    { 

     string fileFullName = context.GetValue(this.FileFullName); 

     string dropFolder = context.GetValue(this.DropLocation); 

     string[] indexerNames = context.GetValue(this.LuceneIndexes); 

     try 
     { 
      //read the vdproj file into memory 
      string text = File.ReadAllText(fileFullName); 

      //for each lucene index folder 
      foreach (string index in indexerNames) 
      { 

       //traversing twice so that the lucene index and spell index can be handled 
       //these are subfolder names we use to segregate our normal lucene index from our spelling indexes. 
       foreach (string subFolderInLuceneIndex in new string[] { "en_US_9", "en_US_9_sp" }) 
       { 

        //retrieve all the files in folder \\[DropFolder]\[index]\[subFolderInLuceneIndex]\*.cfs 
        foreach (string file in Directory.GetFiles(System.IO.Path.Combine(dropFolder, index, subFolderInLuceneIndex), "*.cfs")) 
        { 
         FileInfo cfsFile = new FileInfo(file); 

         context.TrackBuildMessage(string.Format("Exiting file in lucene index directory: {0}", cfsFile.FullName)); 

         string fileNamePattern = ".+.cfs"; 

         string div = Dividor(4); 

         //matching pattern for sourcepath ie("SourcePath" = "8:\\\\...\\[index]\\[subFolderInLuceneIndex]\\_0.cfs") 
         string sourcePattern = string.Format("(\".+{1}{0}{2}{0}{3})", div, index, subFolderInLuceneIndex, fileNamePattern); 

         //matching pattern for targetname ie("TargetName" = "8:_0.cfs") 
         string targetPattern = string.Format("(\"TargetName\"\\s=\\s\"8:{0})", fileNamePattern); 

         StringBuilder sb = new StringBuilder(); 
         sb.Append(sourcePattern); 
         sb.Append("(.+\\r\\n.+)"); //carriage return between targetpattern and sourcepattern 
         sb.AppendFormat(targetPattern); 

         //(.+[index]\\\\[subFolderInLuceneIndex].+.cfs)(.+\r\n.+)(TargetName.+8:.+.cfs) 

         MatchCollection matches = Regex.Matches(text, sb.ToString(), RegexOptions.Multiline); 
         //if more than one match exists, a problem with the setup and deployment file exists 
         if (matches.Count != 1) 
         { 
          throw new Exception("There should exist one and only one match."); 

         } 
         else 
         { 

          foreach (Match match in matches) 
          { 
           string newText = text; 

           string existingPattern = match.Value; 

           if (match.Groups != null) 
           { 
            //if the value found using the match doesn't contain the filename, insert the filename 
            //into the text 
            if (!match.Value.Contains(cfsFile.Name)) 
            { 
             //matched by sourcePattern 
             string sourceValue = match.Groups[1].Value; 

             //matched by targetPattern 
             string targetNameValue = match.Groups[3].Value; 

             int idIndex = targetNameValue.IndexOf("8:") + 2; 

             //get the old *.cfs file name 
             string oldFileName = targetNameValue.Substring(idIndex, targetNameValue.Length - idIndex); 

             //replace old cfs file name with new cfs file name in the target pattern 
             string newTargetNameValue = Regex.Replace(targetNameValue, oldFileName, cfsFile.Name); 

             //replace old cfs file name with new cfs file name in the source pattern 
             string newSourceValue = Regex.Replace(sourceValue, oldFileName, cfsFile.Name); 

             //construct the new text that will be written to the file 
             StringBuilder newSb = new StringBuilder(); 
             newSb.Append(newSourceValue); 
             //account for the quote, carriage return and tabs. this ensures we maintain proper 
             //formatting for a vdproj file 
             newSb.Append("\"\r\n\t\t\t"); 
             newSb.AppendFormat(newTargetNameValue); 

             newText = Regex.Replace(text, sb.ToString(), newSb.ToString(), RegexOptions.Multiline); 

             File.WriteAllText(fileFullName, newText); 

             context.TrackBuildMessage(string.Format("Text {0} replaced with {1}.", oldFileName, cfsFile.Name)); 

            } 
            else 
            { 
             context.TrackBuildMessage("No change applied for current file."); 
            } 
           } 
          } 
         } 
        } 
       } 

      } 

     } 
     catch (Exception ex) 
     { 

      context.TrackBuildError(ex.ToString()); 

      throw ex; 
     } 
    } 
    private static string Dividor(int n) 
    { 
     return new String('\\', n); 
    } 
 
+0

이것은 의미가 없습니다. 프로세스가 * after * 파일을 설치하면 매우 일반적입니다. 그러면 설치 프로그램에서 아무 것도 할 필요가 없습니다. –

+0

@HansPassant 그는 빌드 과정 중에 파일을 만들어야하고 설치 프로젝트에 추가해야한다고 생각합니다. –

+0

나는 그 일을 할 방법을 모르고 있습니다. 프로젝트 자체를 설치하기 전에 (즉, 단지 XML 일뿐입니다) 설치 프로세스를 수정해야합니다 (그래서 TFS 서버에 _clean_ 버전을 유지할 것입니다). –

답변

1

당신은 .V하기 위해 필요한 정보를 추가 할 필요가? PROJ (같은 C++에서이 파일 확장자 VDPROJ있다). 설치 프로그램 파일의 파일 섹션에 추가해야하는 필수 정보. 단일 단계 프로세스가 아니므로 설치 프로그램 프로젝트 파일 (VDPROJ 파일)을 통해 이해하십시오.

+0

내가 설명한 문제에는 두 가지 요구 사항이있었습니다. 1. 프로그래밍 방식으로 파일을 추가해야했습니다. 2. 미리 정해진 이름없이 파일을 추가하십시오. VDPROJ 파일을 이해하는 레벨은 문제가되지 않습니다. VDPROJ 파일이 제공하는 유연성은 다음과 같습니다.간단히 말해서 주어진 기술 내에서 모든 것이 가능하지는 않습니다. Wix 로의 이동이 해결책이었습니다. – JDennis

관련 문제