[英]Run Command Prompt Commands
有沒有辦法從 C# 應用程序中運行命令提示符命令? 如果是這樣,我將如何執行以下操作:
copy /b Image1.jpg + Archive.rar Image2.jpg
這基本上是在 JPG 圖像中嵌入一個 RAR 文件。 我只是想知道是否有辦法在 C# 中自動執行此操作。
這就是您從 C# 運行 shell 命令所要做的全部工作
string strCmdText;
strCmdText= "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
System.Diagnostics.Process.Start("CMD.exe",strCmdText);
編輯:
這是隱藏 cmd 窗口。
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
process.StartInfo = startInfo;
process.Start();
編輯2:
參數以/C
開頭很重要,否則它將不起作用。 正如@scott-ferguson所說: /C 執行字符串指定的命令,然后終止。
嘗試了RameshVel 的解決方案,但我無法在控制台應用程序中傳遞參數。 如果有人遇到同樣的問題,這里有一個解決方案:
using System.Diagnostics;
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine("echo Oscar");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
var proc1 = new ProcessStartInfo();
string anyCommand;
proc1.UseShellExecute = true;
proc1.WorkingDirectory = @"C:\Windows\System32";
proc1.FileName = @"C:\Windows\System32\cmd.exe";
proc1.Verb = "runas";
proc1.Arguments = "/c "+anyCommand;
proc1.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(proc1);
出於某種原因,上述答案都沒有幫助,似乎它們在地毯下掃除錯誤並使故障排除一個人的命令變得困難。 所以我最終選擇了這樣的東西,也許它會幫助別人:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = @"C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\tf.exe",
Arguments = "checkout AndroidManifest.xml",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
WorkingDirectory = @"C:\MyAndroidApp\"
}
};
proc.Start();
盡管從技術上講,這並不能直接回答提出的問題,但它確實回答了如何做原始海報想要做的事情的問題:合並文件。 如果有的話,這是一篇幫助新手了解 Instance Hunter 和 Konstantin 正在談論什么的帖子。
這是我用來組合文件的方法(在本例中為 jpg 和 zip)。 請注意,我創建了一個緩沖區,其中填充了 zip 文件的內容(以小塊而不是一個大的讀取操作),然后緩沖區被寫入 jpg 文件的后面,直到 zip 文件的結尾是到達:
private void CombineFiles(string jpgFileName, string zipFileName)
{
using (Stream original = new FileStream(jpgFileName, FileMode.Append))
{
using (Stream extra = new FileStream(zipFileName, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[32 * 1024];
int blockSize;
while ((blockSize = extra.Read(buffer, 0, buffer.Length)) > 0)
{
original.Write(buffer, 0, blockSize);
}
}
}
}
您可以在一行中使用CliWrap執行此操作:
var result = await Cli.Wrap("cmd")
.WithArguments("copy /b Image1.jpg + Archive.rar Image2.jpg")
.ExecuteBufferedAsync();
var stdOut = result.StandardOutput;
如果你想保持 cmd 窗口打開或想在 winform/wpf 中使用它,那么像這樣使用它
string strCmdText;
//For Testing
strCmdText= "/K ipconfig";
System.Diagnostics.Process.Start("CMD.exe",strCmdText);
/K
將保持 cmd 窗口打開
如果您想在異步模式下運行命令 - 並打印結果。 你可以上這堂課嗎:
public static class ExecuteCmd
{
/// <summary>
/// Executes a shell command synchronously.
/// </summary>
/// <param name="command">string command</param>
/// <returns>string, as output of the command.</returns>
public static void ExecuteCommandSync(object command)
{
try
{
// create the ProcessStartInfo using "cmd" as the program to be run, and "/c " as the parameters.
// Incidentally, /c tells cmd that we want it to execute the command that follows, and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
// The following commands are needed to redirect the standard output.
//This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
string result = proc.StandardOutput.ReadToEnd();
// Display the command output.
Console.WriteLine(result);
}
catch (Exception objException)
{
// Log the exception
Console.WriteLine("ExecuteCommandSync failed" + objException.Message);
}
}
/// <summary>
/// Execute the command Asynchronously.
/// </summary>
/// <param name="command">string command.</param>
public static void ExecuteCommandAsync(string command)
{
try
{
//Asynchronously start the Thread to process the Execute command request.
Thread objThread = new Thread(new ParameterizedThreadStart(ExecuteCommandSync));
//Make the thread as background thread.
objThread.IsBackground = true;
//Set the Priority of the thread.
objThread.Priority = ThreadPriority.AboveNormal;
//Start the thread.
objThread.Start(command);
}
catch (ThreadStartException )
{
// Log the exception
}
catch (ThreadAbortException )
{
// Log the exception
}
catch (Exception )
{
// Log the exception
}
}
}
是的,有(參見 Matt Hamilton 評論中的鏈接),但使用 .NET 的 IO 類會更容易更好。 您可以使用 File.ReadAllBytes 讀取文件,然后使用 File.WriteAllBytes 編寫“嵌入式”版本。
Interaction.Shell("copy /b Image1.jpg + Archive.rar Image2.jpg", AppWinStyle.Hide);
這也可以通過P/Invoking C 標准庫的system
函數來完成。
using System.Runtime.InteropServices;
[DllImport("msvcrt.dll")]
public static extern int system(string format);
system("copy Test.txt Test2.txt");
輸出:
1 file(s) copied.
這里有一點簡單和更少代碼的版本。 它也會隱藏控制台窗口-
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
process.Start();
我有以下方法,用於從 C# 運行命令提示符命令
在第一個參數中傳遞您要運行的命令
public static string RunCommand(string arguments, bool readOutput)
{
var output = string.Empty;
try
{
var startInfo = new ProcessStartInfo
{
Verb = "runas",
FileName = "cmd.exe",
Arguments = "/C "+arguments,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = false
};
var proc = Process.Start(startInfo);
if (readOutput)
{
output = proc.StandardOutput.ReadToEnd();
}
proc.WaitForExit(60000);
return output;
}
catch (Exception)
{
return output;
}
}
您可以通過使用以下方法來實現這一點(如其他答案中所述):
strCmdText = "'/C some command";
Process.Start("CMD.exe", strCmdText);
當我嘗試上面列出的方法時,我發現我的自定義命令無法使用上面某些答案的語法。
我發現更復雜的命令需要封裝在引號中才能工作:
string strCmdText;
strCmdText = "'/C cd " + path + " && composer update && composer install -o'";
Process.Start("CMD.exe", strCmdText);
您可以使用簡單地以.bat
格式擴展名編寫代碼,批處理文件的代碼:
c:/ copy /b Image1.jpg + Archive.rar Image2.jpg
使用這個 c# 代碼:
Process.Start("file_name.bat")
您可以使用RunProcessAsTask
並像這樣輕松地異步運行您的流程:
var processResults = await ProcessEx.RunAsync("git.exe", "pull");
//get process result
foreach (var output in processResults.StandardOutput)
{
Console.WriteLine("Output line: " + output);
}
這可能有點讀,所以我很抱歉提前。 這是我嘗試和測試的方法,可能有更簡單的方法,但這是我把代碼扔到牆上,看看卡住了什么
如果可以使用批處理文件完成,那么可能過於復雜的解決方法是讓 c# 編寫一個 .bat 文件並運行它。 如果您想要用戶輸入,您可以將輸入放入變量中並讓 c# 將其寫入文件。 這種方式需要反復試驗,因為它就像用另一個木偶控制一個木偶。
這是一個示例,在這種情況下,該功能是用於清除打印隊列的 Windows 論壇應用程序中的按鈕。
using System.IO;
using System;
public static void ClearPrintQueue()
{
//this is the path the document or in our case batch file will be placed
string docPath =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
//this is the path process.start usues
string path1 = docPath + "\\Test.bat";
// these are the batch commands
// remember its "", the comma separates the lines
string[] lines =
{
"@echo off",
"net stop spooler",
"del %systemroot%\\System32\\spool\\Printers\\* /Q",
"net start spooler",
//this deletes the file
"del \"%~f0\"" //do not put a comma on the last line
};
//this writes the string to the file
using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
{
//This writes the file line by line
foreach (string line in lines)
outputFile.WriteLine(line);
}
System.Diagnostics.Process.Start(path1);
}
如果您想要用戶輸入,那么您可以嘗試這樣的事情。
這是為了將計算機 IP 設置為靜態但詢問用戶 IP、網關和 dns 服務器是什么。
你需要這個才能工作
public static void SetIPStatic()
{
//These open pop up boxes which ask for user input
string STATIC = Microsoft.VisualBasic.Interaction.InputBox("Whats the static IP?", "", "", 100, 100);
string SUBNET = Microsoft.VisualBasic.Interaction.InputBox("Whats the Subnet?(Press enter for default)", "255.255.255.0", "", 100, 100);
string DEFAULTGATEWAY = Microsoft.VisualBasic.Interaction.InputBox("Whats the Default gateway?", "", "", 100, 100);
string DNS = Microsoft.VisualBasic.Interaction.InputBox("Whats the DNS server IP?(Input required, 8.8.4.4 has already been set as secondary)", "", "", 100, 100);
//this is the path the document or in our case batch file will be placed
string docPath =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
//this is the path process.start usues
string path1 = docPath + "\\Test.bat";
// these are the batch commands
// remember its "", the comma separates the lines
string[] lines =
{
"SETLOCAL EnableDelayedExpansion",
"SET adapterName=",
"FOR /F \"tokens=* delims=:\" %%a IN ('IPCONFIG ^| FIND /I \"ETHERNET ADAPTER\"') DO (",
"SET adapterName=%%a",
"REM Removes \"Ethernet adapter\" from the front of the adapter name",
"SET adapterName=!adapterName:~17!",
"REM Removes the colon from the end of the adapter name",
"SET adapterName=!adapterName:~0,-1!",
//the variables that were set before are used here
"netsh interface ipv4 set address name=\"!adapterName!\" static " + STATIC + " " + STATIC + " " + DEFAULTGATEWAY,
"netsh interface ipv4 set dns name=\"!adapterName!\" static " + DNS + " primary",
"netsh interface ipv4 add dns name=\"!adapterName!\" 8.8.4.4 index=2",
")",
"ipconfig /flushdns",
"ipconfig /registerdns",
":EOF",
"DEL \"%~f0\"",
""
};
//this writes the string to the file
using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
{
//This writes the file line by line
foreach (string line in lines)
outputFile.WriteLine(line);
}
System.Diagnostics.Process.Start(path1);
}
就像我說的。 它可能有點過於復雜,但除非我寫錯批處理命令,否則它永遠不會失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.