0

使用技術

言語: C#

スクリプト: cmd.exe とコマンド

フロントエンド:WIN UI、Xaml

フレームワーク: .Net 5

  • C# から自動化されたプロセスとして 10 個のソフトウェアをインストールしたいと考えています。
  • 現在、ソフトウェアをインストールするために、C# Process クラスを使用して cmd.exe をプロセスとして使用しています。これは管理者として実行する必要があります。そうしないと、管理者権限のためにインストールが失敗します。
  • ここでの問題は、自動化が開始されると、システムが常にすべてのソフトウェアをインストールするために UAC (ユーザー アカウント制御) ポップアップを要求することです (常に UAC ポップをスキップしたい)。

クエリ: C# プロセス クラスから cmd.exe を管理者として使用するときに、この UAC ポップを回避する方法。

他の人から提案された解決策:私のアプリケーション (WIN UI) の起動時に、cmd.exe/powershell.exe を管理者として昇格させてシングルトン プロセスを作成し、このプロセスを使用してすべてのソフトウェアをインストールします (この場合、1 回限りの 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