如何在 C# 中执行 cmd,然后在同一窗口中执行后面的另一个命令?

发布于 2024-08-27 11:11:24 字数 406 浏览 5 评论 0原文

我想要完成的是一个基本上一键设置活动分区的程序,节省了使用 cmd 提示符等的时间和技巧。

我已经研究了 System.Management 名称空间,但不知道如何使用它:(

所以我求助于使用CMD,我有一个用C#编写的模块应用程序,基本上我想运行“DISKPART”,然后在cmd窗口中启动diskpart,然后我想要求它“选择磁盘0” ”,然后是“选择分区 1”,最后是“活动”。

自己在 CMD 中执行此操作效果很好,但对于应用程序来说,事实证明它很尴尬:( 我设法让它做的是在一个窗口中使用 Process 很好地运行 DiskPart .启动,然后让它打开一个新窗口并运行下一段代码,但是因为新窗口没有运行diskpart cmd,所以它不起作用>:(

有什么建议吗?

谢谢!

Ash

Right what im trying to accomplish is a program that basically sets the active partition in 1 click, saving the effort time and skill of using cmd prompt etc.

I have looked into the System.Management name space but couldn't work out how to use it :(

So i have resorted to using CMD, i have got a module application written in C# and basically i want to run "DISKPART" which then starts the diskpart in the cmd window, then i want to ask it to "Select disk 0" followed by "select partition 1" finally followed by "active".

Doing this in CMD yourself works fine but with an application its proved to be awkward :( What ive managed to get it to do is run DiskPart fine in one window with Process.Start, then get it to open a new window and run the next piece of code but because the new window hasnt ran the diskpart cmd it doesnt work >:(

Any suggestions?

Thanks!

Ash

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

染柒℉ 2024-09-03 11:11:24

只要您不对输出做出决定,您就可以在 C# 应用程序中构建一个批处理文件,并通过 Process.Start(...) 启动该文件。

您需要生成两个文件。

第一个 runDiskPart.bat

diskpart /s myScript.dp

第二个 myScript.dp

...some commands...
exit

显然,名称完全是任意的,但 /s 指令需要引用第二个的名称文件。

As long as you aren't making decisions on the output, you could build a batch file in your C# app and start that via Process.Start(...).

You'll need to generate two files.

First runDiskPart.bat:

diskpart /s myScript.dp

Second myScript.dp:

...some commands...
exit

Obviously the names are completely arbitrary but the /s directive needs to reference the name of your second file.

淡写薰衣草的香 2024-09-03 11:11:24

经过一番搜索,我认为你可以用脚本文件做你想做的事。请阅读此内容

因此,在使用必要的命令创建 script.txt 文件后,您可以使用 Process.Start 运行 diskpart /s script.txt

After some searching, I think you can do what you want with a script file. Read this.

You can therefore run diskpart /s script.txt with Process.Start after creating a script.txt file with your necessary commands.

白昼 2024-09-03 11:11:24

这可能有点读起来很抱歉。这是我经过尝试和测试的方法,可能有一种更简单的方法,但这是我将代码扔到墙上,看看是什么卡住了

这个问题的 TLDR 代码,特别

是好吧,抱歉,这个实际上没有经过测试。从理论上讲,

public static void ChangeMe()
 {

 string docPath =
  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

 string path1 = docPath + "\\Test.txt";
 string path2 = docPath + "\\Test.bat";

 string[] lines =
 {
     "select disk 0",
     "clean",
     "convert gpt",
     "create partition primary size=300",
     "format quick fs=ntfs label=Windows RE tools",
     "assign letter=T"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.txt")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 string[] lines =
 {
     "diskpart /s test.txt"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 System.Diagnostics.Process.Start(path2);
 }

如果您想要做的事情可以在批处理文件中完成,那么可能过于复杂的解决方法是让 c# 编写一个 .bat 文件并运行它。如果您需要用户输入,您可以将输入放入变量中,然后让 c# 将其写入文件中。这种方式需要反复试验,因为这就像用另一个木偶控制一个木偶。对于 Diskpart,它有点复杂,因为您必须创建 2 个文件,一个是 .bat,另一个是 txt。

这是一个批处理文件的示例,在本例中,该功能是 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);

    }

像我说的那样工作。它可能有点过于复杂,但除非我写错了批处理命令,否则它永远不会失败。

这是diskpart 的代码。您必须了解命令提示符才能使它们发挥作用。使用 diskpart,您不能只编写这样的脚本,

diskpart
select disk 0
clean
convert gpt
create partition primary size=300
format quick fs=ntfs label=Windows RE tools
assign letter=T

这是因为 diskpart 打开自己的窗口,其余命令只会在命令提示符窗口中抛出错误
所以你必须让 c# 首先用命令编写一个文本文件。然后使用 diskpart 命令创建一个批处理文件来调用您刚刚编写的文本文件。

正如我一开始所说的,这个实际上没有经过测试。这个理论上是有效的

public static void ChangeMe()
 {

 string docPath =
  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

 string path1 = docPath + "\\Test.txt";
 string path2 = docPath + "\\Test.bat";

 string[] lines =
 {
     "select disk 0",
     "clean",
     "convert gpt",
     "create partition primary size=300",
     "format quick fs=ntfs label=Windows RE tools",
     "assign letter=T"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.txt")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 string[] lines =
 {
     "diskpart /s test.txt"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 System.Diagnostics.Process.Start(path2);
 }

This may be a bit of a read so im sorry in advance. And this is my tried and tested way of doing this, there may be a simpler way but this is from me throwing code at a wall and seeing what stuck

TLDR code for this question in particular

Ok sorry This one is actually not tested. this one IN THEORY works

public static void ChangeMe()
 {

 string docPath =
  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

 string path1 = docPath + "\\Test.txt";
 string path2 = docPath + "\\Test.bat";

 string[] lines =
 {
     "select disk 0",
     "clean",
     "convert gpt",
     "create partition primary size=300",
     "format quick fs=ntfs label=Windows RE tools",
     "assign letter=T"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.txt")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 string[] lines =
 {
     "diskpart /s test.txt"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 System.Diagnostics.Process.Start(path2);
 }

If what you want to do be can be done in batch file, then the maybe over complicated work around is have c# write a .bat file and run it. If you want user input you could place the input into a variable and have c# write it into the file. it will take trial and error with this way because its like controlling a puppet with another puppet. And with Diskpart its a little more complicated because you have to make 2 files one that is a .bat and one that is a txt.

here is an example for just a batch file, In this case the function is for a push button in windows forum app that clears the print queue.

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

    }

IF you want user input then you could try something like this.

This is for setting the computer IP as static but asking the user what the IP, gateway, and dns server is.

you will need this for it to work

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

    }

Like I said. It may be a little overcomplicated but it never fails unless I write the batch commands wrong.

This is the code for diskpart. You have to understand the command prompt in order to get these to work. With diskpart you cannot just write a script like

diskpart
select disk 0
clean
convert gpt
create partition primary size=300
format quick fs=ntfs label=Windows RE tools
assign letter=T

This is because diskpart opens its own window and the rest of the commands just throw errors in the command prompt window
so you have to get c# to first write a text file with the commands. Then a batch file with the diskpart command to call the text file that you just wrote.

As I said at first This one is actually not tested. this one IN THEORY works

public static void ChangeMe()
 {

 string docPath =
  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

 string path1 = docPath + "\\Test.txt";
 string path2 = docPath + "\\Test.bat";

 string[] lines =
 {
     "select disk 0",
     "clean",
     "convert gpt",
     "create partition primary size=300",
     "format quick fs=ntfs label=Windows RE tools",
     "assign letter=T"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.txt")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 string[] lines =
 {
     "diskpart /s test.txt"
 };
 using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
 {

     foreach (string line in lines)
         outputFile.WriteLine(line);
 }
 System.Diagnostics.Process.Start(path2);
 }
舂唻埖巳落 2024-09-03 11:11:24

引入延迟(例如 Thread.Sleep(1000))怎么样,以便其他进程有时间完成第一个命令?

What about introducing a delay, such as Thread.Sleep(1000), so that the other process has time to complete the first command?

a√萤火虫的光℡ 2024-09-03 11:11:24

您真正想做的是等待程序退出,然后进入下一个调用。看看这个问题

What you really want to do is wait for the program to exit and then move onto the next invocation. Take a look at this question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文