আমি কীভাবে সি # থেকে একটি কমান্ড-লাইন প্রোগ্রাম সম্পাদন করব এবং এসটিডি আউট ফলাফল পাব? বিশেষত, আমি প্রোগ্রাম হিসাবে নির্বাচিত দুটি ফাইলের উপর ডিআইএফএফ সম্পাদন করতে এবং ফলাফলকে একটি পাঠ্য বাক্সে লিখতে চাই।
আমি কীভাবে সি # থেকে একটি কমান্ড-লাইন প্রোগ্রাম সম্পাদন করব এবং এসটিডি আউট ফলাফল পাব? বিশেষত, আমি প্রোগ্রাম হিসাবে নির্বাচিত দুটি ফাইলের উপর ডিআইএফএফ সম্পাদন করতে এবং ফলাফলকে একটি পাঠ্য বাক্সে লিখতে চাই।
উত্তর:
// 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();
কোডটি এমএসডিএন থেকে ।
{YourProcessObject}.StartInfo.Arguments
স্ট্রিংয়ের মাধ্যমে আপনার কলটিতে যুক্তি যুক্ত করতে পারেন ।
p.StandardError
স্ট্রিমটিতে পর্যাপ্ত ডেটা লিখেছিল। প্রবাহ পূর্ণ হয়ে, এটি প্রদর্শিত হবে তাই আমি উভয় পড়তে আছে প্রক্রিয়া পর্যন্ত ডাটা ক্ষয়প্রাপ্ত হয় থেমে যাবে, StandardError
এবং StandardOutput
যে একটি টাস্ক সঠিকভাবে executes গ্যারান্টি করার জন্য।
একটি দ্রুত নমুনা এখানে:
//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();
সেখানে অন্য একটি প্যারামিটার আমি দরকারী খুঁজে পেয়েছি, যা আমি প্রক্রিয়া উইন্ডোটি অপসারণ করতে ব্যবহার করি
pProcess.StartInfo.CreateNoWindow = true;
এটি ব্যবহারকারীদের কাছ থেকে কালো কনসোল উইন্ডোটিকে পুরোপুরি আড়াল করতে সহায়তা করে, যদি এটি আপনার ইচ্ছা হয়।
// 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) +
"'";
}
process.StartInfo.RedirectStandardError = true;
এবং if (process.ExitCode == 0)
যা গৃহীত উত্তর নেই।
এই পৃষ্ঠায় গৃহীত উত্তরের একটি দুর্বলতা রয়েছে যা বিরল পরিস্থিতিতে ঝামেলাজনক। দুটি ফাইল হ্যান্ডল রয়েছে যা প্রোগ্রামগুলি কনভেনশন, স্টডআউট এবং স্টডার দ্বারা লিখিত। আপনি যদি কেবলমাত্র একটি একক ফাইল হ্যান্ডেল যেমন রেয়ের উত্তর, এবং আপনি যে প্রোগ্রামটি শুরু করছেন তা স্ট্ডারকে পর্যাপ্ত আউটপুট লেখেন তবে এটি আউটপুট স্ট্যাডার বাফার এবং ব্লক পূরণ করবে। তারপরে আপনার দুটি প্রক্রিয়া অচল অবস্থায় রয়েছে। বাফার আকার 4K হতে পারে। স্বল্প-স্থায়ী প্রোগ্রামগুলিতে এটি অত্যন্ত বিরল, তবে আপনার যদি দীর্ঘ সময় ধরে চলমান প্রোগ্রাম থাকে যা বারবার স্ট্যাডারকে আউটপুট করে, অবশেষে এটি ঘটবে। এটি ডিবাগ এবং ট্র্যাক ডাউন জটিল।
এটি মোকাবেলার জন্য বেশ কয়েকটি ভাল উপায় রয়েছে।
একটি উপায় হ'ল আপনার প্রোগ্রামের পরিবর্তে 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";
অন্য উপায় হ'ল একটি প্রোগ্রামিং মডেল ব্যবহার করুন যা একই সাথে উভয় হ্যান্ডলগুলি পড়ে 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();
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();
}
সক্ষম করার ProcessStartInfo
সাথে আপনাকে ব্যবহার করতে হবে RedirectStandardOutput
- তারপরে আপনি আউটপুট স্ট্রিমটি পড়তে পারেন। কোনও ফাইলের (আউট ওএসের মাধ্যমে) আউটপুট পুনর্নির্দেশ করতে আপনার ">" ব্যবহার করা আরও সহজ হতে পারে এবং তারপরে কেবল ফাইলটি পড়তে পারেন।
[সম্পাদনা করুন: রায় কী করেছে: +1]
RedirectStandardOutput
আসলে ব্যবহার করা সহজ ।
আপনি যদি কোনও নির্ভরতা প্রবর্তন করতে আপত্তি না করেন তবে ক্লাইবার্যাপ আপনার জন্য এটি সহজতর করতে পারে:
var cli = new Cli("target.exe");
var output = await cli.ExecuteAsync("arguments", "stdin");
var stdout = output.StandardOutput;
আপনি প্রসেস ক্লাসটি ব্যবহার করে যে কোনও কমান্ড লাইন প্রোগ্রাম চালু করতে পারেন এবং আপনার তৈরি স্ট্রিম রিডার (কোনও স্ট্রিং বা মেমরির অবস্থানের উপর ভিত্তি করে) দিয়ে প্রক্রিয়া উদাহরণের স্ট্যান্ডার্ড আউটপুট সম্পত্তি সেট করতে পারেন। প্রক্রিয়াটি সমাপ্ত হওয়ার পরে, আপনি সেই প্রবাহে আপনার যা প্রয়োজন তার চেয়ে আলাদা করতে পারেন।
যদি আপনার পিসি / সার্ভারে স্থানীয় এআরপি ক্যাশেটি অনুসন্ধান করার চেষ্টা করা হয় তবে কারও পক্ষে এটি কার্যকর হতে পারে।
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();
}
ওয়ান-লাইন রান কমান্ড:
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();
পাবলিকডোমাইন ওপেন সোর্স কোডে একটি প্রসেসহেল্পার ক্লাস রয়েছে যা আপনার আগ্রহী হতে পারে।
আপনি যদি 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);
ফলাফলটি এরকম দেখাচ্ছে:
কেবল মজাদার জন্য, ত্রুটি প্রতিবেদন সহ একটি বোতাম ক্লিকের অধীনে পাইথন আউটপুট পাওয়ার জন্য আমার সম্পূর্ণ সমাধানটি এখানে। কেবলমাত্র "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);
}
}
সবচেয়ে উত্তর যেহেতু এখানে 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");
}