Tim
Tim

Reputation: 177

Running commands in CMD as administrator

Rules that i need to hold on to are the following:

  1. run command prompt command as administrator
  2. change directory (path is always the same)
  3. run command net start something

Any thoughts on how can i do this programatically using C# ?

Just for the record i am running console application built in .net 4.0

I am using this function

        private static void commandtorun(string commandexecuted)
    {
        string currentstatus;
        ProcessStartInfo startInfo = new ProcessStartInfo();
        Process myprocess = new Process();
        try
        {
            startInfo.FileName = "cmd"; //
            startInfo.RedirectStandardInput = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.UseShellExecute = false; //'required to redirect
            //startInfo.CreateNoWindow = true; // '<---- creates no window, obviously
            myprocess.StartInfo = startInfo; //
            myprocess.Start(); //
            System.IO.StreamReader SR;
            System.IO.StreamWriter SW;
            Thread.Sleep(200);
            SR = myprocess.StandardOutput;
            SW = myprocess.StandardInput;
            SW.WriteLine(commandexecuted); // 'the command you wish to run.....
            SW.WriteLine("exit"); // 'exits command prompt window
            Thread.Sleep(200);
            currentstatus = SR.ReadToEnd();
            SW.Close();
            SR.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
            Console.ReadLine();
        }
        // throw new NotImplementedException();
    }

and i get access is denied when i call the function using this command:

commandtorun(@"cd c:\Program Files (x86)\folder1\folder2"); // change the folder because cmd always runs on different path
commandtorun("net start something"); run the COMMAND

I tried to run both commands in one statement but got the same error.

Upvotes: 0

Views: 1761

Answers (1)

David Heffernan
David Heffernan

Reputation: 612834

There are lots of problems here.

You want to run the other process elevated, but your code does not take steps to make that happen. In order to do that you need to invoke your process with the runas verb, and UseShellExecute set to true. But you also want to re-direct which is why you set UseShellExecute to false.

I see no compelling reason to redirect, so I think you can use true for UseShellExecute. You are pumping an exit command into cmd.exe to terminate the process. You don't need to do that. Simply pass cmd.exe the /c argument and the process will close when it is done.

These changes will allow you to remove those calls to Sleep(). Any time you call Sleep() you should ask yourself why you are doing it and if it can be avoided. Very few problems have Sleep() as the optimum solution.

You are trying to specify the working directory by executing cd. That again is the wrong way to do it. You can specify the working directory in the ProcessStartInfo object. That's how you should do it.

Your design has you executing each command in a separate process. That's a really poor way to go. You want to execute all the commands one after the other in a single instance of cmd.exe. Put the commands into a .bat or .cmd file and get cmd.exe to process that.

Imagine if you carried on processing each command as a separate process. How would the second process remember the working directory change that you made? Would you really want your user to see a UAC dialog for each separate command?

Having said all of that though, you are going about this the wrong way. You are just trying to start a service. Yes, you do that with net start when you are working in the command line. But from a program you use the service API to start a service. In other words I believe that you should throw away all of this code and call the service API.

Upvotes: 1

Related Questions