Click here to Skip to main content
13,830,334 members
Rate this:
Please Sign up or sign in to vote.
See more:
I have a multiline dos command to execute with C# and the command must be elevated additionally. So I need to solve it, how I would need only one Process.start construct to call multiple line dos commands at once without writing a batch file to disk?

The reason for the question is: C# does not ask once for an elevation but a hundred times if I call 100 x Process.Start to execute 100 elevated commands line of dos. this I would like to avoid. I seek a special solution which does not include the following scenarios:

a) no whole application elevation:
I do not want to elevate my whole application or use a manifest for it, because the application shall be able to be tested in the development environment without big troubles and it contains a lot of other commands which does not need elevation

b) no use of batch files:
I do not want to write something to disk and batch files, scripts etc. are turned off on the system for security reasons. So I can't execute a batch file.

c) Process.Start may be used only once for the sake of one elevation prompt only
the elevation prompt shall be displayed only once, no matter how much commands are being executed, therefor Process.Start may be called only once, even if the command has multiple lines in it!

Is there any solution for this?

What I have tried:

I only know, that I can start 100 processes elevated for 100 dos commands and I have then 100x times to manually confirm each Process.Start command to be elevated.

How do I avoid this? How do I call a multiline DOS command with one Process.Start() statement?

//this is just an example - there are a variety of repeative commandslines to //either turn of or turn on services, disable or enable services or user accounts.
Process.Start("net", "start ServiceName1"); //elevated Prompt1
Process.Start("net", "start ServiceName2"); //elevated Prompt2
Process.Start("net", "start ServiceName100"); //elevated Prompt100

How to get all this in one "Process.Start" construct to be asked only once for elevation, not a 100 times? The application itself shall stay unelevated.
Updated 21-Apr-16 16:06pm
PIEBALDconsult 16-Apr-16 11:48am
Or try a for command.
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Assuming you elevate your CMD prompt, then separating them with '&' should work:
System.Diagnostics.Process.Start("CMD.EXE", "/C D:&cd \\temp&dir& pause");

[edit]I HATE MARKDOWN![/edit]
OriginalGriff 16-Apr-16 12:00pm

CP uses a Markdown processor which doesn't turn off properly and messes up some - but not all - code blocks.
For example, in the one line of code above, markdown swallowed one of the backslashes which means it wouldn't compile. And you can't see that until you have posted the answer.
To get it back I have to edit the answer, add a space between the two backslashes, save the answer, edit it again and remove the space I just added... :mad:
It also treats stars as italics, and such like. Stupid peice of cr@p! :laugh:

CMD.exe has a limit of 8192 characters, so provided you are below 80 chars per command you should be OK.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

This time, this is a pretty interesting question; I up-voted it.

I can offer much better solution. Here is the thing: in all techniques using System.Diagnostics.Process, there is nothing more pointless than using "CMD.EXE". I see no cases when it really needs to be started programmatically. It's purpose is just to provide interactive shell. And the worst feature is "/C" command-line argument: it works, but is useless, only provoke naive users to use it.

Now, at first glance, it looks like your interesting question justifies the use of "CMD.EXE /C …" But this is nothing by illusion. Why? Because '&' trick is nothing but a trick. Some other application would do it much better. It can transparently pass command line parameters, any number, to a set of separate Process.Start calls, solving the problem completely.

But I understand you major problem: this application should be elevated, but your main application should not. You provided good motivation for that requirement. Besides, one extra application is always a hassle. I'm going to address both problems, too.

You cannot elevate the current process. But it does not mean that you cannot elevate the same application in a different process. In other words, develop your main application in the following way: normally, it is not elevated and does not provide the "elevation required" manifest. But this main application can start another process using the same application assembly as elevated one. For short period of time, you will have two processes started from the same application: parent one is not elevated, and child one elevated. I think you know how to elevated the process using System.Diagnostic.Process: start it with System.Diagnostics.ProcessStartInfo with Verb "RunAs":
ProcessStartInfo.Verb Property (System.Diagnostics)[^],
ProcessStartInfo.Verbs Property (System.Diagnostics)[^],
Process.Start Method (ProcessStartInfo) (System.Diagnostics)[^].

On the use of "runas", see, for example, c# - Elevating process privilege programatically? — Stack Overflow[^].

So, essentially, you can use the same .NET application assembly as two functionally different applications: one used as the main one, another to be elevated and start other processes. How to distinguish the two during process's runtime: the "elevated one" can use "special" command-line parameters.

For work with command-line parameters, I can offer my easy-to-use library: Enumeration-based Command Line Utility[^].


This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Cookies | Terms of Service
Web06 | 2.8.190114.1 | Last Updated 21 Apr 2016
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100