Проверьте, определена ли переменная в PostBuildEvent - PullRequest
0 голосов
/ 18 июня 2019

Я использую следующее PostBuildEvent

<PostBuildEvent>
  IF DEFINED $(MyEnvVar) (
   mkdir "C:\tmp\"
   copy "$(TargetPath)" "$(MyEnvVar)/Addins/Software/bin/$(PlatformName)/$(TargetFileName)"
 )
</PostBuildEvent>

Это событие работает, если определено мое MyEnvVar.Тем не менее, я получаю сообщение об ошибке MSB3073 (выход с кодом 255), если переменная не определена.

Как определить задачу PostBuild для выполнения некоторых операций cmd (создание папок, копирование файлов)как показано выше), если переменная существует, или ничего не делать, если ее нет?

Ответы [ 3 ]

2 голосов
/ 19 июня 2019

Вы должны не действительно использовать события после сборки, вообще, когда-либо . Просто создайте цель и запустите ее после цели сборки. В этой цели скопируйте нужные файлы. Как то так:

<Target Name="CopyMyStuff" AfterTargets="Build" Condition="exists('$(MyEnvVar)')" >
   <Copy SourceFiles="$(TargetPath)" DestinationFolder="$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" SkipUnchangedFiles="true" />
</Target>

Я думаю, что эта задача копирования создаст каталог, если он не существует. Приятный бонус.

2 голосов
/ 21 июня 2019

Visual Studio заменяет все вхождения $(Variable) на строку переменной Visual Studio в значении элемента XML PostBuildEvent перед созданием пакетного файла с текстом PostBuildEvent для временного выполнения после успешной компиляции и процесса компоновки.

Если ссылочная переменная Visual Studio, такая как MyEnvVar, вообще не существует, ее ссылка $(Variable) заменяется пустой строкой. Это приводит здесь в командной строке:

IF DEFINED  (

Процессор команд Windows, выполняющий пакетный файл, ожидает имя переменной среды после DEFINED в этом IF условии, а не открывающая скобка. Это синтаксическая ошибка, обнаруженная cmd.exe при оценке аргументов команды IF , приводящая к выходу из обработки командного файла.

Одно решение использует:

<PostBuildEvent>
  set "MyEnvVar=$(MyEnvVar)"
  if defined MyEnvVar (
   mkdir "C:\tmp\"
   copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\$(TargetFileName)"
 )
</PostBuildEvent>

Первая строка назначает текущее строковое значение переменной Visual Studio MyEnvVar переменной среды MyEnvVar. Поэтому переменная окружения MyEnvVar либо определена со строкой из-за set "MyEnvVar=string value", либо определенно не определена (больше) после этой первой строки, в случае переменной Visual Studio MyEnvVar не существует или имеет пустую строку, приводящую к выполнению set "MyEnvVar=".

Команда IF всегда имеет допустимый синтаксис, поскольку теперь в этой командной строке всегда указывается имя переменной среды для проверки определения независимо от наличия и строкового значения переменной Visual Studio MyEnvVar.

Дополнительное примечание: Разделитель каталогов в Windows - \, а не /, используемый в целевом пути. Файловая система Windows, обращающаяся к функциям ядра, автоматически заменяет все / на \ в полном определенном имени целевого файла как часть автоматического исправления пути к файлу. Но лучше написать код события после сборки со 100% правильным синтаксисом и не зависеть от автоматического исправления ошибок в пути к файлу.

1 голос
/ 19 июня 2019

Я скопировал ваш скрипт и встретил ту же проблему. Согласно сообщению об ошибке The syntax of the command is incorrect, что-то не так с синтаксисом, может быть пробел, новая строка, в которой я точно не уверен: (

Как определить задачу PostBuild для выполнения некоторых операций cmd (создать папки копируют файлы, как показано выше), если переменная существует, или ничего, если это не так?

В качестве обходного пути: Возможно, вы можете удалить оператор суждения изнутри PostBuildEvent. Затем используйте msbuild условие , чтобы определить, определена переменная или нет, попробуйте использовать скрипт, подобный этому:

  <!--<PropertyGroup>
    <MyEnvVar>C:\Test</MyEnvVar>
  </PropertyGroup>-->
  <PropertyGroup>
    <PostBuildEvent Condition="$(MyEnvVar)!=''">
      IF NOT EXIST "C:\tmp\" mkdir "C:\tmp\"
      IF NOT EXIST "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" mkdir "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
      copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
    </PostBuildEvent>
  </PropertyGroup>

В vs щелкните правой кнопкой мыши проект и добавьте в него скрипт, местоположение должно быть:

<Project...>
    ...
  <!--<PropertyGroup>
    <MyEnvVar>C:\Test</MyEnvVar>
  </PropertyGroup>-->

  <PropertyGroup>
    <PostBuildEvent Condition="$(MyEnvVar)!=''">
      IF NOT EXIST "C:\tmp\" mkdir "C:\tmp\"
      IF NOT EXIST "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" mkdir "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
      copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
    </PostBuildEvent>
  </PropertyGroup>
</Project>

Затем right-click the project, выберите reload project и проверьте, помогает ли это в достижении вашей первоначальной цели.

1. PostBuildEvent будет работать только тогда, когда MyEnvVar определено и имеет свое значение.

2. Две команды mkdir будут вызываться, когда каталог C:\tmp\ и $(MyEnvVar)\Addins\Software\bin\$(PlatformName)\ не существует

3. Затем команда copy скопирует вывод вашего проекта в папку назначения. Я удаляю $(TargetFileName), поскольку он представляет собой xxx.exe или xxx.dll, я думаю, что в этом нет необходимости, или, возможно, вы действительно хотите $(AssemblyName). Пожалуйста, дайте мне знать, если это поможет решить вашу проблему:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...