.Net Core open external terminal

☆樱花仙子☆ 提交于 2019-12-11 02:15:40

问题


I'm migrating batch script to .Net core and I'm trying to open another terminal from current terminal and run a command (I don't need stderr o stout).

With batch only needs this command: start cmd /K gulp. I'm trying to do the same with .Net core but only found the way to run the command inside current terminal.

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;
}

I'm trying changing this properties in order to open in another terminal:

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

But make an exception:

UseShellExecute must always be set to false.


回答1:


From the MSDN docs:

UseShellExecute must be false if the UserName property is not null or an empty string, or an InvalidOperationException will be thrown when the Process.Start(ProcessStartInfo) method is called.

startInfo.UserName = null;

edit: I'm not sure why you have to pass in the arguments, but if all you want is a new CMD window try this:

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);
}

You wont need startInfo.UserName in this case because you are specifying a working directory.




回答2:


Thanks to @bender-bending answer I found a way to solve it. Due security limitations need user/password credentials in order to autorice current terminal to open a new one.

WorkingDirectory, user, password and domain are required.
Create no window, redirect output and redirect error must be false, in order to see command result in new window.

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 doesn't have a method to obtain user and domain. We can use this class to get this values from environment variables.

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");
    }
}

Hope it helps!



来源:https://stackoverflow.com/questions/45382418/net-core-open-external-terminal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!