简体   繁体   中英

Fail to execute a specific cmd batch file in C#

I'm using Process to execute a batch file which will generate certificate file.

The code works great when I execute other file (which contains openssl command). But when I execute a file which contains keytool command, it executed, but no file was generated.

I've:

  • Set UseShellExecute true.
  • Set WaitForExit(-1) and find the return was true, so it did executed.
  • I clicked that batch file manually, and the file generates right away, so the command was fine:(
  • BTW I'm using.Net Core MVC.

I can't find any error code anywhere, so I'm at my wits' end now.

Does anyone has a clue? Any help would be very appriciated!

success code(openssl):

I generate a p12 file (a certificate format) in that folder first, and it works fine.

private string Gen_P12(string domain, string pwd)
        {
            //generate folder
            string folder = @"D:\Temp\";
            if (!Directory.Exists(folder))
                Directory.CreateDirectory(folder);

            //generate bat(p12)
            string bat = "openssl.exe pkcs12 -export -inkey " + domain + ".key -in " + domain + ".cer -out " + domain + ".p12 -password pass:" + pwd +"\r\n";
            //download in folder
            var path = Path.Combine(folder, domain + "_P12.bat");
            using (FileStream fs = System.IO.File.Create(path))
            {
                byte[] content = new UTF8Encoding(true).GetBytes(bat);
                fs.Write(content, 0, content.Length);
            }

            Thread.Sleep(500);

            //execute
            ProcessStartInfo myBat = new ProcessStartInfo();
            string name = domain + "_P12.bat";
            myBat.FileName = name;
            myBat.WorkingDirectory = folder;
            myBat.UseShellExecute = true;
            //Process.Start(myBat);
            Process p = Process.Start(myBat);
            p.WaitForExit(-1);

            return folder;
        }

fail code(keytool):

Trying to use that P12 file and keytool command to generate a keystore (also a certificate format) but fail.

private string Gen_KS(string domain, string folder, string CA_domain, byte[] cer, string pwd)
        {
            //generate bat
            string bat = "keytool -importkeystore -srckeystore " + domain + ".p12 -srcstoretype PKCS12 -srcstorepass " + pwd + " -destkeystore " + domain + ".keystore -storepass " + pwd + "\r\n";
            var path = Path.Combine(folder, domain + "_KS.bat");

            using (FileStream fs = System.IO.File.Create(path))
            {
                byte[] content = new UTF8Encoding(true).GetBytes(bat);
                fs.Write(content, 0, content.Length);
            }

            Thread.Sleep(700);
     
            //execute
            ProcessStartInfo myBat = new ProcessStartInfo();
            myBat.WorkingDirectory = folder;
            string name = domain + "_KS.bat";
            myBat.FileName = name;
            myBat.UseShellExecute = true;
            Process p = Process.Start(myBat);
            var a = p.WaitForExit(-1);

            string route = folder + domain + ".keystore";
            return route;
        }

Thanks!

Thanks to @user9938, I solved the problem!

1. Brief conclusion: I need to process the bat as administrator.

(And I still don't get why only do the keytool command needs administrator rights)

2. Find the errors: (How to apply StanderError when UseShellExecute=true)

In fact we don't have to set it true to execute commands. Try this (replace execute section):

 Process process = new Process();
            try
            {
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.FileName = "cmd.exe";
                process.Start();
                process.StandardInput.WriteLine(bat); //command string, not the bat file 
                process.StandardInput.AutoFlush = true;
                process.StandardInput.WriteLine("exit");
                StreamReader reader = process.StandardError;
                string curLine = reader.ReadLine();
                reader.Close();
                process.WaitForExit();
                process.Close();
            }catch (Exception e){}

Check the value of curLine through Breakpoints, the error message was: "'keytool' is not recognized as an internal or external command, operable program or batch file".

3. How to solve it:

Just set the Verb attribute as "runas".

            //execute
            ProcessStartInfo myBat = new ProcessStartInfo();
            myBat.WorkingDirectory = folder;
            string name = domain + "_KS.bat";
            myBat.Verb = "runas";
            myBat.FileName = name;
            myBat.UseShellExecute = true;
            Process p = Process.Start(myBat);
            var a = p.WaitForExit(-1);

Done! Thank you user9938<3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM