কীভাবে: সি # তে কমান্ড লাইনটি কার্যকর করুন, এসটিডি আউট ফলাফল পাবেন


472

আমি কীভাবে সি # থেকে একটি কমান্ড-লাইন প্রোগ্রাম সম্পাদন করব এবং এসটিডি আউট ফলাফল পাব? বিশেষত, আমি প্রোগ্রাম হিসাবে নির্বাচিত দুটি ফাইলের উপর ডিআইএফএফ সম্পাদন করতে এবং ফলাফলকে একটি পাঠ্য বাক্সে লিখতে চাই।


2
এছাড়াও stackoverflow.com/a/5367686/492 দেখুন - এটি আউটপুট এবং ত্রুটিগুলির জন্য ইভেন্টগুলি দেখায়।
সিএডি

সম্পর্কিত (কিন্তু stdout- এ ক্যাপচার ছাড়াই): stackoverflow.com/questions/1469764
user202729

উত্তর:


523
// Start the child process.
 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "YOURBATCHFILE.bat";
 p.Start();
 // Do not wait for the child process to exit before
 // reading to the end of its redirected stream.
 // p.WaitForExit();
 // Read the output stream first and then wait.
 string output = p.StandardOutput.ReadToEnd();
 p.WaitForExit();

কোডটি এমএসডিএন থেকে ।


8
ব্যাচের ফাইল ছাড়াই এটি করার কোনও উপায় আছে? কথাটি হ'ল, আমাকে কমান্ডটিতে কিছু পরামিতি প্রেরণ করতে হবে। আমি xsd.exe <অ্যাসবেশন> / টাইপ: <ক্লাসনাম> ব্যবহার করছি, সুতরাং আমার বিধানসভা এবং ক্লাসনেম উভয়ই সেট করতে সক্ষম হওয়া দরকার এবং তারপরে কমান্ডটি চালানো উচিত।
কার্লো 17

26
আপনি {YourProcessObject}.StartInfo.Argumentsস্ট্রিংয়ের মাধ্যমে আপনার কলটিতে যুক্তি যুক্ত করতে পারেন ।
পৃষ্ঠপোষক

5
কিভাবে প্রশাসক হিসাবে প্রক্রিয়া চালানো?
সাহের আহওয়াল

5
আমি এই কোডটি ব্যবহার করে আমার প্রক্রিয়া পুরোপুরি থামিয়ে দিয়েছি এমন অনেকগুলি সমস্যার মুখোমুখি হয়েছি কারণ প্রক্রিয়াটি p.StandardErrorস্ট্রিমটিতে পর্যাপ্ত ডেটা লিখেছিল। প্রবাহ পূর্ণ হয়ে, এটি প্রদর্শিত হবে তাই আমি উভয় পড়তে আছে প্রক্রিয়া পর্যন্ত ডাটা ক্ষয়প্রাপ্ত হয় থেমে যাবে, StandardErrorএবং StandardOutputযে একটি টাস্ক সঠিকভাবে executes গ্যারান্টি করার জন্য।
টেড স্পেন্স

5
সি # সংকলক থেকে দ্রুত শিরোনাম: আইও স্ট্রিমগুলি পুনর্নির্দেশের জন্য প্রক্রিয়া অবজেক্টটিতে অবশ্যই ইউজশেলএক্সেকিউট সম্পত্তিটি মিথ্যাতে সেট করা উচিত।
ইব্রাহার মমতাজ

144

একটি দ্রুত নমুনা এখানে:

//Create process
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();

//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = strCommand;

//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = strCommandParameters;

pProcess.StartInfo.UseShellExecute = false;

//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;   

//Optional
pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;

//Start the process
pProcess.Start();

//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();

//Wait for process to finish
pProcess.WaitForExit();

2
কমান্ড-লাইন প্রোগ্রামটি চালানোর জন্য যুক্তিগুলি কীভাবে যুক্ত করবেন তা দেখানোর জন্য +1 (যা স্বীকৃত উত্তরটি নেই))
সুমন

104

সেখানে অন্য একটি প্যারামিটার আমি দরকারী খুঁজে পেয়েছি, যা আমি প্রক্রিয়া উইন্ডোটি অপসারণ করতে ব্যবহার করি

pProcess.StartInfo.CreateNoWindow = true;

এটি ব্যবহারকারীদের কাছ থেকে কালো কনসোল উইন্ডোটিকে পুরোপুরি আড়াল করতে সহায়তা করে, যদি এটি আপনার ইচ্ছা হয়।


3
আমাকে অনেক মাথাব্যথা বাঁচিয়েছে। ধন্যবাদ।
ভিভান্দিয়ার

2
"Sc" কল করার সময় আমাকে স্টার্টইনফোও উইন্ডো স্টাইল = প্রসেসওয়াইন্ডোস্টাইল.হাইডার সেট করতে হয়েছিল।
পেড্রো

90
// usage
const string ToolFileName = "example.exe";
string output = RunExternalExe(ToolFileName);

public string RunExternalExe(string filename, string arguments = null)
{
    var process = new Process();

    process.StartInfo.FileName = filename;
    if (!string.IsNullOrEmpty(arguments))
    {
        process.StartInfo.Arguments = arguments;
    }

    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.UseShellExecute = false;

    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;
    var stdOutput = new StringBuilder();
    process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data); // Use AppendLine rather than Append since args.Data is one line of output, not including the newline character.

    string stdError = null;
    try
    {
        process.Start();
        process.BeginOutputReadLine();
        stdError = process.StandardError.ReadToEnd();
        process.WaitForExit();
    }
    catch (Exception e)
    {
        throw new Exception("OS error while executing " + Format(filename, arguments)+ ": " + e.Message, e);
    }

    if (process.ExitCode == 0)
    {
        return stdOutput.ToString();
    }
    else
    {
        var message = new StringBuilder();

        if (!string.IsNullOrEmpty(stdError))
        {
            message.AppendLine(stdError);
        }

        if (stdOutput.Length != 0)
        {
            message.AppendLine("Std output:");
            message.AppendLine(stdOutput.ToString());
        }

        throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
    }
}

private string Format(string filename, string arguments)
{
    return "'" + filename + 
        ((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
        "'";
}

3
একটি খুব ব্যাপক উদাহরণ, ধন্যবাদ
শহীদআজিম

2
আউটপুটডেটা রিসিভ হ্যান্ডলারটি স্টডিআউট.অ্যাপেন্ডলাইন () এ বদলাতে পারে
পল উইলিয়ামস

3
আমার মতে এটি গৃহীত উত্তরের চেয়ে অনেক বেশি বিস্তৃত সমাধান। আমি এখন এটি ব্যবহার করছি, এবং স্বীকৃতটিকে ব্যবহার করি নি, তবে এটির সত্যিই অভাব রয়েছে বলে মনে হচ্ছে।
প্রোফেকে

1
এর জন্য ধন্যবাদ process.StartInfo.RedirectStandardError = true;এবং if (process.ExitCode == 0)যা গৃহীত উত্তর নেই।
জনবি 17'19

12

এই পৃষ্ঠায় গৃহীত উত্তরের একটি দুর্বলতা রয়েছে যা বিরল পরিস্থিতিতে ঝামেলাজনক। দুটি ফাইল হ্যান্ডল রয়েছে যা প্রোগ্রামগুলি কনভেনশন, স্টডআউট এবং স্টডার দ্বারা লিখিত। আপনি যদি কেবলমাত্র একটি একক ফাইল হ্যান্ডেল যেমন রেয়ের উত্তর, এবং আপনি যে প্রোগ্রামটি শুরু করছেন তা স্ট্ডারকে পর্যাপ্ত আউটপুট লেখেন তবে এটি আউটপুট স্ট্যাডার বাফার এবং ব্লক পূরণ করবে। তারপরে আপনার দুটি প্রক্রিয়া অচল অবস্থায় রয়েছে। বাফার আকার 4K হতে পারে। স্বল্প-স্থায়ী প্রোগ্রামগুলিতে এটি অত্যন্ত বিরল, তবে আপনার যদি দীর্ঘ সময় ধরে চলমান প্রোগ্রাম থাকে যা বারবার স্ট্যাডারকে আউটপুট করে, অবশেষে এটি ঘটবে। এটি ডিবাগ এবং ট্র্যাক ডাউন জটিল।

এটি মোকাবেলার জন্য বেশ কয়েকটি ভাল উপায় রয়েছে।

  1. একটি উপায় হ'ল আপনার প্রোগ্রামের পরিবর্তে cmd.exe চালানো এবং stdout এবং stderr কে একীভূত করতে বলার জন্য cmd.exe এর সাথে "2> & 1" যুক্তিটি সহ আপনার প্রোগ্রামটি শুরু করতে cmd.exe এর / c আর্গুমেন্ট ব্যবহার করুন।

            var p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
  2. অন্য উপায় হ'ল একটি প্রোগ্রামিং মডেল ব্যবহার করুন যা একই সাথে উভয় হ্যান্ডলগুলি পড়ে reads

            var p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = @"/c dir \windows";
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = false;
            p.OutputDataReceived += (a, b) => Console.WriteLine(b.Data);
            p.ErrorDataReceived += (a, b) => Console.WriteLine(b.Data);
            p.Start();
            p.BeginErrorReadLine();
            p.BeginOutputReadLine();
            p.WaitForExit();

2
আমি মনে করি এটি আসল প্রশ্নের উত্তম উত্তর দেয়, কারণ এটি সি # (কোনও ফাইল নয়) এর মাধ্যমে কীভাবে সিএমডি কমান্ড চালাবেন তা দেখায়।
টিনিআরাকুন

12
 System.Diagnostics.ProcessStartInfo psi =
   new System.Diagnostics.ProcessStartInfo(@"program_to_call.exe");
 psi.RedirectStandardOutput = true;
 psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
 psi.UseShellExecute = false;
 System.Diagnostics.Process proc = System.Diagnostics.Process.Start(psi); ////
 System.IO.StreamReader myOutput = proc.StandardOutput;
 proc.WaitForExit(2000);
 if (proc.HasExited)
  {
      string output = myOutput.ReadToEnd();
 }

প্রক্রিয়াটি প্রচুর ডেটা লিখলে অচলাবস্থার সৃষ্টি হতে পারে। প্রক্রিয়াটি চলমান অবস্থায় ডেটা পড়া শুরু করা ভাল।
জেনসজি

6

সক্ষম করার ProcessStartInfoসাথে আপনাকে ব্যবহার করতে হবে RedirectStandardOutput- তারপরে আপনি আউটপুট স্ট্রিমটি পড়তে পারেন। কোনও ফাইলের (আউট ওএসের মাধ্যমে) আউটপুট পুনর্নির্দেশ করতে আপনার ">" ব্যবহার করা আরও সহজ হতে পারে এবং তারপরে কেবল ফাইলটি পড়তে পারেন।

[সম্পাদনা করুন: রায় কী করেছে: +1]


10
এটি আপনাকে এমন কোনও ফাইল লিখতে বাধ্য করে যার জন্য আপনার অনুমতি দরকার, এর জন্য একটি অবস্থান এবং একটি নাম সন্ধান করা দরকার এবং এটি শেষ হয়ে গেলে মুছতে ভুলবেন না। RedirectStandardOutputআসলে ব্যবহার করা সহজ ।
পিএসআইআইআর

4

আপনি যদি কোনও নির্ভরতা প্রবর্তন করতে আপত্তি না করেন তবে ক্লাইবার্যাপ আপনার জন্য এটি সহজতর করতে পারে:

var cli = new Cli("target.exe");
var output = await cli.ExecuteAsync("arguments", "stdin");
var stdout = output.StandardOutput;

3

এটি সর্বোত্তম / সহজতম উপায় নাও হতে পারে তবে এটি একটি বিকল্প হতে পারে:

আপনি যখন আপনার কোডটি থেকে নির্বাহ করবেন, "> আউটপুট.txt" যুক্ত করুন এবং তারপরে আউটপুট.টেক্সট ফাইলটিতে পড়ুন।


3

আপনি প্রসেস ক্লাসটি ব্যবহার করে যে কোনও কমান্ড লাইন প্রোগ্রাম চালু করতে পারেন এবং আপনার তৈরি স্ট্রিম রিডার (কোনও স্ট্রিং বা মেমরির অবস্থানের উপর ভিত্তি করে) দিয়ে প্রক্রিয়া উদাহরণের স্ট্যান্ডার্ড আউটপুট সম্পত্তি সেট করতে পারেন। প্রক্রিয়াটি সমাপ্ত হওয়ার পরে, আপনি সেই প্রবাহে আপনার যা প্রয়োজন তার চেয়ে আলাদা করতে পারেন।


3

যদি আপনার পিসি / সার্ভারে স্থানীয় এআরপি ক্যাশেটি অনুসন্ধান করার চেষ্টা করা হয় তবে কারও পক্ষে এটি কার্যকর হতে পারে।

List<string[]> results = new List<string[]>();

        using (Process p = new Process())
        {
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.Arguments = "/c arp -a";
            p.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            p.Start();

            string line;

            while ((line = p.StandardOutput.ReadLine()) != null)
            {
                if (line != "" && !line.Contains("Interface") && !line.Contains("Physical Address"))
                {
                    var lineArr = line.Trim().Split(' ').Select(n => n).Where(n => !string.IsNullOrEmpty(n)).ToArray();
                    var arrResult = new string[]
                {
                   lineArr[0],
                   lineArr[1],
                   lineArr[2]
                };
                    results.Add(arrResult);
                }
            }

            p.WaitForExit();
        }

3

ওয়ান-লাইন রান কমান্ড:

new Process() { StartInfo = new ProcessStartInfo("echo", "Hello, World") }.Start();

রিবেল কোডের স্বল্পতম পরিমাণে কমান্ডের আউটপুট পড়ুন:

    var cliProcess = new Process() {
        StartInfo = new ProcessStartInfo("echo", "Hello, World") {
            UseShellExecute = false,
            RedirectStandardOutput = true
        }
    };
    cliProcess.Start();
    string cliOut = cliProcess.StandardOutput.ReadToEnd();
    cliProcess.WaitForExit();
    cliProcess.Close();


2

আপনি যদি cmd.exe তে কিছু কমান্ড চালাতে চান তবে আপনি নিম্নলিখিতটি করতে পারেন:

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C vol";
p.Start();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);

এটি কমান্ডের কেবলমাত্র আউটপুট দেয়:

এখানে চিত্র বর্ণনা লিখুন

আপনি এর StandardInputপরিবর্তে ব্যবহার করতে পারেন StartInfo.Arguments:

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.Start();
// Read the output stream first and then wait.
p.StandardInput.WriteLine("vol");
p.StandardInput.WriteLine("exit");
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);

ফলাফলটি এরকম দেখাচ্ছে:

এখানে চিত্র বর্ণনা লিখুন


0

কেবল মজাদার জন্য, ত্রুটি প্রতিবেদন সহ একটি বোতাম ক্লিকের অধীনে পাইথন আউটপুট পাওয়ার জন্য আমার সম্পূর্ণ সমাধানটি এখানে। কেবলমাত্র "butPython" নামক একটি বোতাম এবং "llHello" নামে একটি লেবেল যুক্ত করুন ...

    private void butPython(object sender, EventArgs e)
    {
        llHello.Text = "Calling Python...";
        this.Refresh();
        Tuple<String,String> python = GoPython(@"C:\Users\BLAH\Desktop\Code\Python\BLAH.py");
        llHello.Text = python.Item1; // Show result.
        if (python.Item2.Length > 0) MessageBox.Show("Sorry, there was an error:" + Environment.NewLine + python.Item2);
    }

    public Tuple<String,String> GoPython(string pythonFile, string moreArgs = "")
    {
        ProcessStartInfo PSI = new ProcessStartInfo();
        PSI.FileName = "py.exe";
        PSI.Arguments = string.Format("\"{0}\" {1}", pythonFile, moreArgs);
        PSI.CreateNoWindow = true;
        PSI.UseShellExecute = false;
        PSI.RedirectStandardError = true;
        PSI.RedirectStandardOutput = true;
        using (Process process = Process.Start(PSI))
            using (StreamReader reader = process.StandardOutput)
            {
                string stderr = process.StandardError.ReadToEnd(); // Error(s)!!
                string result = reader.ReadToEnd(); // What we want.
                return new Tuple<String,String> (result,stderr); 
            }
    }

0

সবচেয়ে উত্তর যেহেতু এখানে Dont বাস্তবায়ন usingজন্য statemant IDisposableএবং কিছু অন্যান্য কাপড় কোনটা আমি nessecary আমি এই উত্তর যোগ হবে হতে পারে মনে হয়।

সি # 8.0 এর জন্য

// Start a process with the filename or path with filename e.g. "cmd". Please note the 
//using statemant
using myProcess.StartInfo.FileName = "cmd";
// add the arguments - Note add "/c" if you want to carry out tge  argument in cmd and  
// terminate
myProcess.StartInfo.Arguments = "/c dir";
// Allows to raise events
myProcess.EnableRaisingEvents = true;
//hosted by the application itself to not open a black cmd window
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = true;
// Eventhander for data
myProcess.Exited += OnOutputDataRecived;
// Eventhandler for error
myProcess.ErrorDataReceived += OnErrorDataReceived;
// Eventhandler wich fires when exited
myProcess.Exited += OnExited;
// Starts the process
myProcess.Start();
//read the output before you wait for exit
myProcess.BeginOutputReadLine();
// wait for the finish - this will block (leave this out if you dont want to wait for 
// it, so it runs without blocking)
process.WaitForExit();

// Handle the dataevent
private void OnOutputDataRecived(object sender, DataReceivedEventArgs e)
{
    //do something with your data
    Trace.WriteLine(e.Data);
}

//Handle the error
private void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
{        
    Trace.WriteLine(e.Data);
    //do something with your exception
    throw new Exception();
}    

// Handle Exited event and display process information.
private void OnExited(object sender, System.EventArgs e)
{
     Trace.WriteLine("Process exited");
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.