2017-05-15 4 views
2

나는 항상 좋은 작품 인 MyProject(P2P)과 같은 시각적 인 스튜디오 프로젝트를 가지고 있습니다. 내가 윅스의 빌드 오류가 발생했습니다 지금윅 스크립트의 이스케이프 대괄호

<Component Id="MyProject(P2P).exe" Guid="34565d5d-07d6-495d-a184-bb3bdebe1fb8"> 
    <File Source="$(var.MyProject(P2P).TargetPath)" KeyPath="yes" /> 
    </Component> 

: 이제

나는 MSI로이 프로젝트를 포장하는 윅스 (3)를 사용하고는 단계 중 하나는 구성 요소 노드를 작성하는 것입니다 프로젝트 :

Product.wxs (807,0) : 오류 CNDL0234 : 잘못된 형식의 전 처리기 함수 '$ var.MyProject (P2P) .TargetPath'. 함수는 접두어 (예 : 'fun.'), 최소 1 자 이상의 이름 및 열기 및 닫기 괄호와 일치해야합니다.

()을 탈출 할 필요가 있습니까? 그리고 어떻게?

답변

2

WIX 3.11부터 변수 이름에 괄호를 이스케이프 할 수있는 메커니즘이 없습니다. WIX 전 처리기는 괄호를 이스케이프 할 필요없이이 작업을 처리해야하지만, 경우에 따라 전 처리기의 버그 및/또는 제한 사항 때문에 그렇지 않습니다.

무슨 일이 일어나는지 이해하려면 https://github.com/wixtoolset/wix3/releases/tag/wix311rtm에서 다운로드 할 수있는 관련 WIX 소스 파일 src\tools\wix\PreProcessor.cs을 살펴 봐야합니다. 이 파일에서 함수 PreprocessString()은 문자열을 취해 $(...) 형태의 프로세서 전처리 변수를 해당 정의로 대체하려고 시도합니다 (이 함수는 매우 길기 때문에이 함수의 소스는 포함하지 않았습니다).

당신의 변수가 여는 괄호 문자가 포함되어 있기 때문에는 PreprocessString() 기능은 EvaluateFunction() 호출

/// <summary> 
    /// Evaluate a function. 
    /// </summary> 
    /// <param name="sourceLineNumbers">The source line information for the function.</param> 
    /// <param name="function">The function expression including the prefix and name.</param> 
    /// <returns>The function value.</returns> 
    public string EvaluateFunction(SourceLineNumberCollection sourceLineNumbers, string function) 
    { 
     string[] prefixParts = function.Split(variableSplitter, 2); 
     // Check to make sure there are 2 parts and neither is an empty string. 
     if (2 != prefixParts.Length || 0 >= prefixParts[0].Length || 0 >= prefixParts[1].Length) 
     { 
      throw new WixException(WixErrors.InvalidPreprocessorFunction(sourceLineNumbers, function)); 
     } 
     string prefix = prefixParts[0]; 

     string[] functionParts = prefixParts[1].Split(new char[] { '(' }, 2); 
     // Check to make sure there are 2 parts, neither is an empty string, and the second part ends with a closing paren. 
     if (2 != functionParts.Length || 0 >= functionParts[0].Length || 0 >= functionParts[1].Length || !functionParts[1].EndsWith(")", StringComparison.Ordinal)) 
     { 
      throw new WixException(WixErrors.InvalidPreprocessorFunction(sourceLineNumbers, function)); 
     } 
     string functionName = functionParts[0]; 

     // Remove the trailing closing paren. 
     string allArgs = functionParts[1].Substring(0, functionParts[1].Length - 1); 

     // Parse the arguments and preprocess them. 
     string[] args = allArgs.Split(argumentSplitter); 
     for (int i = 0; i < args.Length; i++) 
     { 
      args[i] = this.PreprocessString(sourceLineNumbers, args[i].Trim()); 
     } 

     string result = this.EvaluateFunction(sourceLineNumbers, prefix, functionName, args); 

     // If the function didn't evaluate, try to evaluate the original value as a variable to support 
     // the use of open and closed parens inside variable names. Example: $(env.ProgramFiles(x86)) should resolve. 
     if (null == result) 
     { 
      result = this.GetVariableValue(sourceLineNumbers, function, false); 
     } 

     return result; 

귀하의 문자열이 variableSplitter 문자로 구분 된 세 부분으로 구성되어, 첫 번째 테스트 2 != prefixParts.length 실패, 그래서 어떤 결과 '.' InvalidPreprocessorFunction 예외가 발생했습니다.

또한 함수에서 문자열을 함수로 평가하려고 시도하고 실패 할 경우 문자열을 변수로 평가합니다. 이것은 주석에 명시된 예 : $(env.ProgramFiles(x86))에서 작동합니다.

https://github.com/wixtoolset/issues/issues에 WIX 문제 버그 추적기 버그 보고서를 제기하는 것이 좋습니다.

해결 방법으로 설치 프로젝트에서 응용 프로그램 프로젝트까지의 상대 경로를 사용할 수 있습니다. 예 :

<Component Id="MyProject(P2P).exe" Guid="34565d5d-07d6-495d-a184-bb3bdebe1fb8"> 
    <File Source="..\Release\MyProject(P2P).exe" KeyPath="yes" /> 
</Component