Chạy các lệnh nhắc nhở


605

Có cách nào để chạy các lệnh nhắc lệnh từ trong ứng dụng C # không? Nếu vậy làm thế nào tôi sẽ làm như sau:

copy /b Image1.jpg + Archive.rar Image2.jpg

Điều này về cơ bản nhúng một tệp RAR trong hình ảnh JPG. Tôi chỉ tự hỏi liệu có cách nào để làm điều này tự động trong C #.


6
Bản sao của stackoverflow.com/questions/181719/ khăn (có một câu trả lời ở đó thực hiện những gì bạn muốn).
Matt Hamilton

stackoverflow.com/a/5367686/492 có câu trả lời tốt hơn
CAD bloke

Câu trả lời:


918

đây là tất cả những gì bạn phải làm để chạy các lệnh shell từ C #

string strCmdText;
strCmdText= "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
System.Diagnostics.Process.Start("CMD.exe",strCmdText);

BIÊN TẬP:

Điều này là để ẩn cửa sổ 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();

EDIT: 2

Quan trọng là đối số bắt đầu bằng /Ccách khác nó sẽ không hoạt động. Làm thế nào Scott Ferguson nói: nó "Thực hiện lệnh được chỉ định bởi chuỗi và sau đó chấm dứt."


166
/ C Thực hiện lệnh được chỉ định bởi chuỗi và sau đó chấm dứt
Scott Ferguson

16
Nó chỉ để báo cho cmd chạy và chấm dứt (đừng đợi bất kỳ đầu vào nào của người dùng đóng cửa sổ)
RameshVel

3
Cảm ơn bạn, một câu hỏi nữa. Có cách nào để ẩn dấu nhắc lệnh trong thời gian này không?
người dùng

9
Tôi không thấy tôi là người duy nhất nghĩ rằng đây là một ý tưởng khủng khiếp. Vâng, điều này sẽ làm việc, nhưng nó hoàn toàn và hoàn toàn sai. Sinh ra các quy trình CMD để thực hiện các hoạt động IO đơn giản là sai, ngay cả khi nó hoạt động. Đọc qua tài liệu về không gian tên System.IO. Có quá nhiều chức năng trong đó để làm những gì bạn cần làm mà không sinh ra các quy trình không cần thiết.
Thợ săn sơ thẩm

56
FYI: Sử dụng process.WaitForExit () để chờ quá trình hoàn tất trước khi tiếp tục và process.ExitCode để lấy mã thoát của quy trình.
shindigo

122

Đã thử giải pháp @RameshVel nhưng tôi không thể truyền đối số trong ứng dụng bảng điều khiển của mình. Nếu bất cứ ai gặp vấn đề tương tự ở đây là một giải pháp:

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

2
Tôi cũng không có cơ hội nghĩ rằng trên máy của mình có một số hạn chế quản trị hoặc chống vi-rút nhưng .. đoạn mã trên hoạt động! cảm ơn Ogglas
Pete Kozak

6
dòng này: cmd.StartInfo.CreateNoWindow = true; đã cứu ngày của tôi.
Ganesh Kamath - 'Mã điên cuồng'

Có cách nào để thực thi nhiều lệnh trong một lần khôngcmd.StandardInput.WriteLine(@"cd C:\Test; pwd")
Zach Smith

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

2
Là gì @dấu trong C #?
Pacerier

6
@Pacerier Nó báo cho trình biên dịch thoát tất cả các ký tự thường phải thoát trong chuỗi, trong trường hợp này \. Vì vậy, nếu không có \, mã của bạn sẽ trông như thếproc1.FileName = "C:\\Windows\\System32\\cmd.exe";
James Ko

1
Bạn nên lưu ý rằng proc1.Verb = "runas";làm cho quá trình này chạy với các đặc quyền nâng cao ... Điều này không phải lúc nào cũng có ý định.
Dinei

1
Làm thế nào tôi có thể làm cho cửa sổ cmd này không đóng sau khi hoàn thành?
Hrvoje T

1
Tôi thấy rằng việc gọi 'đường dẫn cd' được nối bởi '&&' với các lệnh khác trong dòng luôn thực thi lần cuối ngay cả khi nó đi trước. của bạn: 'Proc1.WorkingDirectory = @ "C: \ Windows \ System32";' rất hữu ích Cảm ơn!
Nozim Turakulov

11

Không có câu trả lời nào ở trên giúp được vì một số lý do, có vẻ như họ quét lỗi dưới tấm thảm và khiến việc xử lý sự cố của một người gặp khó khăn. Vì vậy, tôi đã kết thúc với một cái gì đó như thế này, có thể nó sẽ giúp người khác:

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

Nếu tôi muốn biên dịch nó thành một ứng dụng giao diện điều khiển độc lập, mã nào khác sẽ phải được thêm vào để làm cho nó hoạt động? (Tôi là một người mới cho tất cả các công cụ lập trình này, chỉ thực hiện một số kịch bản). Tôi đang sử dụng csc.exe btw.
script'n'code

@copyitright Một không gian tên và lớp. Nếu bạn chỉ tạo một dự án mới, họ sẽ được tạo cho bạn.
coinbird

Ah. đừng bận tâm. nếu bạn sử cmd.exedụng ứng dụng, bạn có thể truyền lệnh dưới dạng đối số.
Zach Smith

Đối với hậu thế: Tôi muốn quá trình chạy echo Hello World!và hiển thị đầu ra lệnh trong cửa sổ cmd bật lên. Vì vậy, tôi đã cố gắng: Filename = @"echo", Arguments = "Hello World!", UseShellExecute = false, RedirectStandardOuput = false, CreateNoWindow = false. Điều này cho phép cửa sổ cmd của ứng dụng mẹ hiển thị "Hello World!" (điều này có ý nghĩa vì thiết bị xuất chuẩn không được chuyển hướng đến quy trình con).
Minh Trần

10

Mặc dù về mặt kỹ thuật, điều này không trả lời trực tiếp câu hỏi được đặt ra, nhưng nó trả lời câu hỏi về cách thực hiện những gì người đăng ban đầu muốn làm: kết hợp các tệp. Nếu bất cứ điều gì, đây là một bài viết để giúp người mới hiểu Instance Hunter và Konstantin đang nói về điều gì.

Đây là phương pháp tôi sử dụng để kết hợp các tệp (trong trường hợp này là jpg và zip). Lưu ý rằng tôi tạo một bộ đệm chứa đầy nội dung của tệp zip (trong các đoạn nhỏ thay vì trong một thao tác đọc lớn), và sau đó bộ đệm được ghi vào mặt sau của tệp jpg cho đến khi kết thúc tệp zip đạt:

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

9

Nếu bạn muốn giữ cửa sổ cmd mở hoặc muốn sử dụng nó trong winform / wpf thì hãy sử dụng nó như thế này

    string strCmdText;
//For Testing
    strCmdText= "/K ipconfig";

 System.Diagnostics.Process.Start("CMD.exe",strCmdText);

/ K

Sẽ giữ cho cửa sổ cmd mở


Đẹp. Tìm thấy tài liệu này cho cmdlệnh và các tham số của nó.
pius

8

Vâng, có (xem liên kết trong nhận xét của Matt Hamilton), nhưng sẽ dễ dàng hơn và tốt hơn khi sử dụng các lớp IO của .NET. Bạn có thể sử dụng File.ReadAllBytes để đọc các tệp và sau đó File.WriteAllBytes để viết phiên bản "nhúng".


11
Tải toàn bộ tệp vào bộ nhớ chỉ để nối thêm một tệp khác không hiệu quả lắm, đặc biệt là nếu các tệp đủ lớn.
Konstantin Spirin

7
Hãy cố gắng nhìn vào tinh thần của câu trả lời. Vấn đề là .NET có quá nhiều lớp và chức năng IO để thực hiện việc này mà không cần phải gọi ra hệ điều hành. Các chức năng cụ thể tôi đã đề cập có thể không phải là tốt nhất, nhưng đó chỉ là những chức năng đơn giản nhất. Nó hoàn toàn không có ý nghĩa gì khi gọi vỏ để làm điều này.
Thợ săn sơ thẩm

7

Bạn có thể làm điều này bằng CliWrap trong một dòng:

var stdout = new Cli("cmd")
         .Execute("copy /b Image1.jpg + Archive.rar Image2.jpg")
         .StandardOutput;

Tôi đã ủng hộ điều này ... nhưng hiện tại repo vẫn còn thiếu:Unable to find package 'CliWrap' at source
Zach Smith

1
@ZachSmith không chắc ý của bạn là gì, nuget.org/packages/CliWrap dường như hoạt động tốt. Các liên kết ban đầu quá.
Tyrrrz

Xin lỗi .. vì một số lý do khi tôi không thể kết nối với repo nuget của mình qua vpn, tôi không thể cài đặt gói này. nuget vẫn chủ yếu là một bí ẩn đối với tôi. phải cài đặt sai
Zach Smith


5

Đây là phiên bản ít đơn giản và ít mã. Nó cũng sẽ ẩn cửa sổ giao diện điều khiển-

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

5

nếu bạn muốn chạy lệnh ở chế độ không đồng bộ - và in kết quả. bạn có thể lớp học này:

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

}

2

Bạn có thể đạt được điều này bằng cách sử dụng phương pháp sau (như đã đề cập trong các câu trả lời khác):

strCmdText = "'/C some command";
Process.Start("CMD.exe", strCmdText);

Khi tôi thử các phương pháp được liệt kê ở trên, tôi thấy rằng lệnh tùy chỉnh của tôi không hoạt động bằng cách sử dụng cú pháp của một số câu trả lời ở trên.

Tôi phát hiện ra các lệnh phức tạp hơn cần được gói gọn trong dấu ngoặc kép để làm việc:

string strCmdText;
strCmdText = "'/C cd " + path + " && composer update && composer install -o'";
Process.Start("CMD.exe", strCmdText);

1

bạn có thể sử dụng chỉ cần viết mã trong một .batphần mở rộng định dạng, mã của tệp bó:

c:/ copy /b Image1.jpg + Archive.rar Image2.jpg

sử dụng mã c # này:

Process.Start("file_name.bat")


nếu bạn muốn ẩn cmd trong khi chạy, bạn có thể sử dụng mã tập lệnh cơ bản trực quan đơn giản trong .vbsphần mở rộng định dạng, mã:CreateObject("Wscript.Shell").Run "filename.bat",0,True
XMMR12
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.