Click here to Skip to main content
15,888,263 members
Please Sign up or sign in to vote.
4.00/5 (1 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?

C#
//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.
Posted
Updated 21-Apr-16 15:06pm
Comments
PIEBALDconsult 16-Apr-16 11:48am    
Or try a for command.
https://technet.microsoft.com/en-us/library/cc754900.aspx

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

[edit]I HATE MARKDOWN![/edit]
 
Share this answer
 
v3
Comments
OriginalGriff 16-Apr-16 12:00pm    
https://www.google.co.uk/search?q=markdown+syntax&oq=Markdown&aqs=chrome.3.0l6.4576j1j7&sourceid=chrome&ie=UTF-8

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.
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[^].

—SA
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900