0

使用的技术

语言:C#

脚本:cmd.exe 和命令

前端:WIN UI、Xaml

框架:.Net 5

  • 我想从 c# 安装 10 个软件作为自动化过程。
  • 目前要安装软件,我使用 cmd.exe 作为使用 C# Process 类的进程,这应该以管理员身份运行,否则我的安装将由于管理员权限而失败。
  • 这里的问题是当我的自动化启动时,系统总是要求我弹出 UAC(用户帐户控制)来安装每个软件(我想总是跳过 UAC 弹出)。

查询:当我使用 cmd.exe 作为 C# 进程类的管理员时,如何避免此 UAC 弹出。

其他人提出的解决方案:在我的应用程序(WIN UI)启动时,创建一个单例进程,将 cmd.exe/powershell.exe 提升为管理员并使用此进程安装所有软件。(在这种情况下,我们将获得一次 UAC弹出,这没关系)。所以我可以调用这个进程/服务来执行我的所有命令,以避免 UAC 弹出,因为这个进程以管理员身份运行

为提议的解决方案尝试的方法:

  1. 关注这篇文章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();
      }
  }
} 
  • 在这种方法中,由于 useShellExecute 设置为 false,cmd.exe 进程没有以管理员身份运行。
  • 如果将 useShellExecute 设置为 false 进程在非管理员模式下运行,那么我的软件安装失败。

查询:在这种情况下如何以管理员身份运行 cmd.exe

  1. 方法 2:通过设置 useShellExecute = true; 创建一个以管理员身份打开 cmd.exe 的进程;

         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();
    
    

问题:在这种方法中,由于 UseShellExecute 属性为 true,我无法通过标准输入执行命令。由于如果使用 UseShellExecute 为 true 存在限制,我们无法将标准输入/输出重定向到进程。

查询:当 UseShellExecute 为 true 时,我如何向 cmd.exe 提供输入命令

注意:由于 WIN UI ( https://github.com/microsoft/microsoft-ui-xaml/issues/3046 )中的问题,我无法以管理员身份运行我的 WIN UI 应用程序。

4

0 回答 0