Выполнение команды по пути без отображения нового окна

#.net #f# #f#-fake

#.net #f# #f #-подделка

Вопрос:

Я пытаюсь заменить скрипт rake на ПОДДЕЛЬНЫЙ, но сталкиваюсь с некоторыми проблемами при переносе в другое приложение. В rake я бы сделал что-то вроде sh 'bundle exec jekyll "#{outputDir}"' where bundle на моем PATH , но в .NET / FAKE я не могу запустить команду без появления нового окна.

Мой конкретный вариант использования предназначен для FAKE и его ProcessHelper, но я думаю, что этот вопрос можно обобщить на любое использование ProcessStartInfo.

Следующая команда выполняется успешно ( info является ProcessStartInfo ), но появляется новое окно:

 ExecProcess (fun info -> 
                   info.UseShellExecute <- true
                   info.CreateNoWindow <- true //doesn't apply when UseShellExecute is true
                   info.FileName <- "bundle"
                   info.WorkingDirectory <- workingDir
                   info.Arguments <- "exec jekyll ""   outputDir   "")
            (TimeSpan.FromMinutes 5.)
  

Для повторного использования текущего окна я установил UseShellExecute значение false , но затем команда «bundle» не найдена («Исключение: сбой запуска пакета процессов. Система не может найти указанный файл»). Я предполагаю, что без этого UseShellExecute PATH среда не установлена, отсюда и моя попытка вызвать setEnvironmentVariables :

 let pathEnv = Environment.GetEnvironmentVariable("PATH")
ExecProcess (fun info -> 
                   info.UseShellExecute <- false
                   info.FileName <- "bundle"
                   info.WorkingDirectory <- workingDir
                   info.Arguments <- "exec jekyll ""   outputDir   "")
                   setEnvironmentVariables info [("PATH", pathEnv)])
            (TimeSpan.FromMinutes 5.)
  

Есть ли способ настроить ProcessStartInfo для выполнения того, что мне нужно? Или есть альтернатива тому, ProcessStartInfo что я должен использовать?

Комментарии:

1. Я бы предположил, что когда ShellExecute имеет значение false, вам не нужен exec и вы можете просто вызвать jekyll напрямую.

2. @JohnPalmer Я думаю, что это все еще нужно запустить через bundler, но точная команда не важна. В качестве эквивалентного случая можно было бы использовать преобразование в то, ruby -e "puts 'hello'" где ruby находится путь.

3. Похоже, что это довольно четко описано в CreateNoWindow и UseShellExecute . Для последнего вам нужно установить значение false, чтобы первое вступило в силу, но тогда вам нужно использовать полный путь (свойство WorkingDirectory не используется для определения местоположения исполняемого файла).

4. @kvb — да, я надеялся, что есть способ найти программу через переменную окружения path. Возможно, мне придется просто вручную выполнить поиск по пути.

5. Так что это не ПОДДЕЛЬНАЯ проблема, верно? Работает ли это из какой-либо другой программы .NET?

Ответ №1:

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

 let findExecutableInPath (exe:String) =
    Environment.GetEnvironmentVariable("PATH").Split([| Path.PathSeparator |])
    |> Seq.append ["."]
    |> Seq.map (fun p -> p @@ exe)
    |> Seq.tryFind (File.Exists)
  

Я посмотрю, подойдет ли это для FAKE.

(Преобразовано в вики сообщества на случай, если у кого-то есть идея получше :))