Technologies Used
Langauage : C#
Scripting : cmd.exe and commands
Front End : WIN UI, Xaml
Framework : .Net 5
- I want to install bunch of 10 software's as a automated process from c#.
- Currently To install software I am using cmd.exe as a Process using C# Process class and this should be run as admin or else my installation will get failed due to the admin privilege's.
- Problem here is When my automation starts, system is always asking me UAC(User Account Control) pop up to install the every software(I want skip UAC pop always).
Query : How to avoid this UAC pop when I use cmd.exe as admin from C# process classes.
Proposed solution from others: On my application(WIN UI) launch, create a singleton process with elevate the cmd.exe/powershell.exe as admin and use this process to install all the software's.(in this case we will get one time UAC pop up and this is ok). So I can call this process/service to execute all my commands to avoid the UAC pop up as this process is running as admin
Approaches Tried for the Proposed solution :
- Followed this article https://code-ai.mk/execute-command-prompt-commands-from-c/ .
public class CmdService : IDisposable
{
private Process _cmdProcess;
private StreamWriter _streamWriter;
private AutoResetEvent _outputWaitHandle;
private string _cmdOutput;
public CmdService(string cmdPath)
{
_cmdProcess = new Process();
_outputWaitHandle = new AutoResetEvent(false);
_cmdOutput = String.Empty;
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.FileName = cmdPath;
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.Verb = "runas";
processStartInfo.CreateNoWindow = true;
_cmdProcess.OutputDataReceived += _cmdProcess_OutputDataReceived;
_cmdProcess.StartInfo = processStartInfo;
_cmdProcess.Start();
_streamWriter = _cmdProcess.StandardInput;
_cmdProcess.BeginOutputReadLine();
}
public string ExecuteCommand(string command)
{
_cmdOutput = String.Empty;
_streamWriter.WriteLine(command);
_streamWriter.WriteLine("echo end");
_outputWaitHandle.WaitOne();
return _cmdOutput;
}
private void _cmdProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data == null || e.Data == "end")
_outputWaitHandle.Set();
else
_cmdOutput += e.Data + Environment.NewLine;
}
public void Dispose()
{
_cmdProcess.Close();
_cmdProcess.Dispose();
_streamWriter.Close();
_streamWriter.Dispose();
}
}
}
- In this approach cmd.exe process is not running as admin due to the useShellExecute set to false.
- If you set useShellExecute to false Process is running under non admin mode , so my software installation is failed.
Query : how I can run cmd.exe as admin in this case
Approach 2 : Created a process to open cmd.exe as an admin by setting the useShellExecute = true;
startInfo.FileName = "cmd.exe"; startInfo.Verb = "runas"; startInfo.UseShellExecute = true; startInfo.RedirectStandardInput = false; startInfo.Arguments = @"msiexec.exe /qn /norestart /i C:\Temp\somesoftware.msi INSTALLDIR=c:\tep\somesoftware ALLUSERS=1 REBOOT=ReallySupress /log C:\Logs\somesoftwarelog.txt"; var pro = new Process(); pro.StartInfo = startInfo; pro.Start();
Issues : In this approach I am not able to execute the commands via standardinputs due to the UseShellExecute property to true. As there is restriction if you use UseShellExecute to true we cannot redirect the standard input/output to the process.
Query : How I can provide inputs commands to cmd.exe when UseShellExecute to true
Note : I cannot run my WIN UI application as admin due to the issues in WIN UI(https://github.com/microsoft/microsoft-ui-xaml/issues/3046).