2017-07-28 79 views
2

我正在將批處理腳本遷移到.Net核心,我試圖從當前終端打開另一個終端並運行命令(我不需要stderr o stout)。.Net核心打開外部終端

批量只需要這個命令:start cmd /K gulp。我試圖用.Net核心做同樣的事情,但只能找到在當前終端內運行命令的方式。

private static string Run(){ 
    var result = ""; 
    try 
    { 
     ProcessStartInfo startInfo = new ProcessStartInfo(); 
     startInfo.FileName = "cmd.exe"; 
     startInfo.Arguments = $"/c \"gulp browserSync\""; 
     startInfo.RedirectStandardOutput = true; 
     startInfo.RedirectStandardError = true; 
     startInfo.UseShellExecute = false; 
     startInfo.CreateNoWindow = true; 

     using (Process process = Process.Start(startInfo)) 
     { 
      result = process.StandardError.ReadToEnd(); 
      process.WaitForExit(); 
     } 
    } 
    catch (Exception Ex) 
    { 
     Console.WriteLine(Ex.Message); 
     Console.ReadKey(); 
    } 
    return result; 
} 

我想,才能在另一端,打開更改此屬性:

startInfo.RedirectStandardOutput = false; 
startInfo.RedirectStandardError = false; 
startInfo.UseShellExecute = true; 

但是破例:

UseShellExecute必須始終設置爲false。

+0

究竟是什麼問題?你想打開一個新的終端,它不會正確嗎? –

+0

我在一個終端上,我試圖打開一個新終端並運行一個命令。 – Equiman

回答

1

感謝@彎曲彎曲的答案我找到了一種方法來解決它。由於安全限制需要用戶/密碼憑據以自動授權當前終端打開新的終端。

WorkingDirectory,用戶,密碼和域是必需的。
創建沒有窗口,重定向輸出和重定向錯誤必須爲false,以便在新窗口中查看命令結果。

public static void Sample(){ 
    try 
    { 
     Console.Write("Password: "); 
     StringBuilder password = new StringBuilder(); 
     while (true) 
     { 
      var key = System.Console.ReadKey(true); 
      if (key.Key == ConsoleKey.Enter) break; 
      password.Append(key.KeyChar); 
     } 

     ProcessStartInfo startInfo = new ProcessStartInfo 
     { 
      FileName = "cmd.exe", 
      WorkingDirectory = "C:/path_to/Gulp", 
      Arguments = $"/c \"gulp browserSync\"", 
      UseShellExecute = false, 
      RedirectStandardOutput = false, 
      RedirectStandardError = false, 
      UserName = Machine.User(), 
      PasswordInClearText = password.ToString(), 
      Domain = Machine.Domain(), 
      CreateNoWindow = false 
     }; 

     Process proc = new Process(); 
     proc.StartInfo = startInfo; 
     proc.Start(); 
     //proc.WaitForExit(); 
    } catch (Exception ex) 
    { 
     System.Console.WriteLine(ex); 
     System.Console.ReadKey(); 
    } 
} 

.Net Core沒有獲取用戶和域的方法。我們可以使用這個類從環境變量中獲取這個值。

public static class Machine 
{ 
    public static string User(){ 
     return Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER"); 
    } 

    public static string Domain(){ 
     return Environment.GetEnvironmentVariable("USERDOMAIN") ?? Environment.GetEnvironmentVariable("HOSTNAME"); 
    } 
} 

希望它有幫助!

+0

該解決方案僅適用於Windows ...我在macOS上測試了它並說:此平臺不支持此操作,如果您需要可在兩個平臺上運行的解決方案:https://medium.com/@equiman/run-a-command-in-external-terminal-with-net-core-cc24e3cc9839 – Equiman

1

MSDN docs:如果用戶名屬性不爲null或空字符串,或者當的Process.Start(的ProcessStartInfo)方法被調用一個InvalidOperationException將被拋出

UseShellExecute一定是假的。

startInfo.UserName = null; 

編輯:我不知道爲什麼你的參數傳遞,但是如果你想要的是一個新的CMD窗口試試這個:

try 
{ 
    ProcessStartInfo startInfo = new ProcessStartInfo 
    { 
     FileName = "cmd.exe", 
     WorkingDirectory = @"C:/users/replace/where_gulp_is_located", 
     Arguments = @"/c gulp", // add /K if its required, I don't know if its for gulp for to open a new cmd window 
     UseShellExecute = false, 
     RedirectStandardOutput = true, 
     RedirectStandardError = true 
    }; 

    Process proc = new Process(); 
    proc.StartInfo = startInfo; 
    proc.Start(); 

    if (showOut) 
    { ///code } 

}catch(Exception ex) 
{ 
    Console.WriteLine(ex); 
} 

你不會需要startInfo.UserName在這種情況是因爲你指定了一個工作目錄。

+0

執行命令,但沒有打開一個新的終端:'( – Equiman