【解決方法】C# のシェル コマンドから実行される exe によってトリガーされるポップアップの処理

プログラミングQA


C#でコードを書いています。
私のコードには、シェル コマンドから exe を実行するコマンドがあります。

$"/C {hospitalPath} /R {bdbPath} /M {bmiPath}";

「ホスピタル」という非常に曖昧なアプリです。 bdbPath と bmiP​​ath はファイルへのパスです。

いずれかのファイルが破損している場合、ポップアップ ウィンドウが表示されます。コードがスタック状態にならないようにするには、[OK]をクリックする必要があります。 これが発生した場合、プロセスを強制終了してこれを防ぎたいと思いますが、これを行う方法がわかりません。

私が試したこと:

これが私のコードです:

System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                    startInfo.FileName = "cmd.exe";
                    startInfo.Arguments = HospitalCommand(hospitalPath, bdbPath, bmiPath);
                    process.StartInfo = startInfo;
bool processStarted = process.Start();
process.WaitForExit();

私が WaitForExit() を使用するのは、phospital.exe が正常に実行された場合、コードを続行する前に終了する必要があるためです。

キャンセルトークンを使用してプロセスを作成しようとしましたが、プロセスが実行中であることを示す出力ファイルを生成したかどうかを確認する新しいスレッドを作成しました。 これらが生成されない場合は、process.Kill() を呼び出します。
ただし、シェルコマンドを実行する時点でスタックしているため、コードをスレッド作成まで実行できません。
コマンドでさまざまなフラグも試しましたが、ポップアップが実行を停止するのを防ぐものはありません。

コマンドスレッドが実行される前に、チェックスレッドを作成しようとはしていません。 チェック スレッドを作成して遅延させ、コマンドを開始してから、プロセスを強制終了する必要があるかどうかを確認できます。 これは機能しますか? たとえそれが機能したとしても、それは素晴らしい解決策のようには思えません。

何か提案はありますか?

解決策 1

たぶん、次のようなものを使用できます。
Process.Exited イベント (System.Diagnostics) | マイクロソフト ラーン[^]

解決策 2

次のようなものを使用して、名前付きウィンドウでの[OK]のクリックを自動化しました。
ポップアップの存在をポーリングするスレッドを起動し、存在する場合はクリックします。

C#
[
    System.Runtime.InteropServices.DllImportAttribute
    (
        "User32"
    ,
        SetLastError=true
    ,
        EntryPoint="FindWindow"
    )
]
private static extern System.IntPtr
API_FindWindow
(
    string lpClassName
,
    string lpWindowName
) ;

public static System.IntPtr
FindWindow
(
    string WindowName
)
{
    return ( API_FindWindow
    (
        null
    ,
        WindowName
    ) ) ;
}
C#
public enum WindowsMessage : uint
{
    EM_GETPARAFORMAT = 61
,
    EM_SETPARAFORMAT = 71
,
    WM_LBUTTONDOWN   = 0x0201
,
    WM_LBUTTONUP     = 0x0202
} ;

[
    System.Runtime.InteropServices.DllImportAttribute
    (
        "User32"
    ,
        SetLastError=true
    ,
        EntryPoint="SendMessage"
    )
]
private static extern System.Int32
API_SendMessage
(
    System.IntPtr hWnd
,
    System.UInt32 Msg
,
    System.Int16  wParam
,
    System.Int32  lParam
) ;

public static System.Int32
SendMessage
(
    System.IntPtr  Window
,
    WindowsMessage Message
)
{
    return ( API_SendMessage
    (
        Window
    ,
        (System.UInt32) Message
    ,
        0
    ,
        0
    ) ) ;
}
C#
System.IntPtr hTemp ;

if ( ( hTemp = PIEBALD.Lib.LibApi.FindWindow ( k.Caption ) ) != System.IntPtr.Zero )
{
    PIEBALD.Lib.LibApi.SetActiveWindow ( hTemp ) ;

    System.IntPtr hok   ;

    if ( ( hok = PIEBALD.Lib.LibApi.FindWindowEx ( hTemp , k.Press ) ) != System.IntPtr.Zero )
    {
        PIEBALD.Lib.LibApi.SendMessage ( hok , PIEBALD.Lib.LibApi.WindowsMessage.WM_LBUTTONDOWN ) ;
        PIEBALD.Lib.LibApi.SendMessage ( hok , PIEBALD.Lib.LibApi.WindowsMessage.WM_LBUTTONUP   ) ;
    }
}

コメント

タイトルとURLをコピーしました