Execute several elevated commands in shell (or sim

2019-09-02 04:31发布

问题:

I have a requirement to execute several commands with elevated rights, something like:

  1. call program that modifies a .config file of a service (needs admin rights)
  2. net stop myservice (needs admin rights)
  3. net start myservice (needs admin rights)

All of this dynamic, e. g. the first line could contain proxy settings, including user name and password, or any other modification to the settings file. (Settings file is in program folder, program to modify the settings file is externally provided. The actual info would be user entered through a GUI.)

I thought to create a very flexible solution, using a cmd.exe process with redirected stdin and stdout. But.. it looks like "runas" (needs ShellExecute) and redirected in-/output are exclusive.

(Also, I noticed that redirection and cmd.exe are quite hard to handle.. I had to write my own functions e. g. as a replacement for ReadLine, since the ReadLine expects a NewLine at the end and waits e. g. if there is a command prompt (meaning you have text in the line like c:\bla> but no NewLine. Still, not knowing what one gets as a result makes writing something generic difficult.)

There are 3 alternatives I can think of:

  1. get the UAC prompt for every single command (I would not like that)
  2. start a process that is elevated, this can then call whatever it wants -> needs an additional project (.exe) which I would like to avoid, also makes deployment more difficult (additional file)
  3. create a batch file on the fly, run it elevated. This I also want to avoid, since there could be password information in plain text in that file (e. g. user/password for proxy). I would at least have to make sure to always overwrite its contents and then delete it.

How to handle this?

回答1:

I think you've already diagnosed the issue, and enumerated your available options. To my mind the best option is to use runas to create a new elevated process, and get that process to do the work.

The other process need not be a different executable it could be your existing executable started with particular command line arguments. Once you have another process running elevated, you can certainly use cmd with redirected stdin/stdout to do the work. However, why use net stop/start rather than the service API? And can you do the .config file modification without starting a separate process?