投稿者 とくま  (社会人) 投稿日時 2024/1/4 14:48:58
エピ さん
解決して良かったです。


★有識者の方へ
>x64,AnyCPU 32ビットを優先のチェックを外す
この設定、64ビットしかコマンドが通らないって解釈してますが、合ってますでしょうか?

この質問で思い出したことがありまして、
プラットホームターゲット:AnyCPU
ビルド環境・実行環境:Windows 10 Pro(64 ビット オペレーティング システム)
Process.Start
で実行すると
>指定されたファイルが見つかりません。

process.StandardError
で取ると
>'C:\windows\system32\ie4uinit.exe' は、内部コマンドまたは外部コマンド、
>操作可能なプログラムまたはバッチ ファイルとして認識されていません。
とのエラーが出るコマンドがありまして

私は、他にも実行しているコマンドが沢山あったので、影響範囲が最小になるように本体EXEは変更せず
本体EXE(AnyCPU、32ビットを優先のチェックあり)呼び出し→別EXE(AnyCPU、32ビットを優先のチェック★無し)呼び出し→"ie4uinit.exe"
の形で逃げたのですが、どうするのが良い形なのかご意見を伺えたらと思いました。


using System;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;

static void DesktopRedrawFunc()
{
    string strCommand;
    string strStandard;
    string strError;
    int intExitCode;

    string strSystemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
    string strCommandPath = Path.Combine(strSystemPath, "ie4uinit.exe");

    //プロジェクトのプロパティで「32bitを優先」のチェックを外さないと実行できない⇒終了コード 1 となる

    // Windowsアイコンキャッシュ再構築(Win7)
    //strCommand = @"""" + strSystemPath + @"\ie4uinit.exe"" -ClearIconCache"; //Process.Startの時は引数付けた時点でエラーになるかも↓引数なしコマンドで通る
    ////strCommand = @"""C:\WINDOWS\system32\ie4uinit.exe""";
    ////strCommand = @"""C:\Program Files (x86)\Microsoft Office\Office16\EXCEL.EXE""";
    ////strCommand = @"ipconfig /all >> c:\ipconfigAllTest.txt";
    strCommand = @"""" + strCommandPath + @""" -ClearIconCache";
    //Process.Start(strCommand);
    ExecBatProcess(strCommand, out strStandard, out strError, out intExitCode);

    if (strStandard != string.Empty)
    { MessageBox.Show("標準出力      :" + strStandard); Console.WriteLine("標準出力      :" + strStandard); }
    if (strError != string.Empty)
    { MessageBox.Show("標準エラー出力:" + strError); Console.WriteLine("標準エラー出力:" + strError); }
    MessageBox.Show("終了コード    :" + intExitCode.ToString());

    // Windowsアイコンキャッシュ再構築(Win10)
    //strCommand = @"""" + strSystemPath + @"\ie4uinit.exe"" -show";
    strCommand = @"""" + strCommandPath + @""" -show";
    //Process.Start(strCommand);
    ExecBatProcess(strCommand, out strStandard, out strError, out intExitCode);

    if (strStandard != string.Empty)
    { MessageBox.Show("標準出力      :" + strStandard); Console.WriteLine("標準出力      :" + strStandard); }
    if (strError != string.Empty)
    { MessageBox.Show("標準エラー出力:" + strError); Console.WriteLine("標準エラー出力:" + strError); }
    MessageBox.Show("終了コード    :" + intExitCode.ToString());

}

/// <summary>
/// バッチコマンドを実行する
/// </summary>
/// <param name="executeCommand">コマンド文字列</param>
/// <param name="stdOut">標準出力</param>
/// <param name="stdErr">標準エラー出力</param>
/// <param name="exitCode">終了コード</param>
/// <returns>リターンコード</returns>
public static void ExecBatProcess(string executeCommand, out string stdOut, out string stdErr, out int exitCode)
{
    stdOut = string.Empty;
    stdErr = string.Empty;
    exitCode = 0;

    Process process = new Process();
    //ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe", "/c " + executeCommand);
    ProcessStartInfo processStartInfo = new ProcessStartInfo(Environment.GetEnvironmentVariable("ComSpec"), "/c " + executeCommand);
    processStartInfo.CreateNoWindow = true;
    processStartInfo.UseShellExecute = false;

    processStartInfo.RedirectStandardOutput = true;
    processStartInfo.RedirectStandardError = true;

    process = Process.Start(processStartInfo);

    stdOut = process.StandardOutput.ReadToEnd().Trim();
    stdErr = process.StandardError.ReadToEnd().Trim();
    exitCode = process.ExitCode;

    // WaitForExitをReadToEndの後にしないと、親プロセスと子プロセスの両方でブロック処理が発生し、デッドロックの原因となる
    process.WaitForExit();
    process.Close();
    process.Dispose();

    //return 0;
}