ファイル経由で外部アプリケーションを起動するコードをたくさん見てきましたが、それは問題ではありません。私が望む動作を正確に明確にするために:
- 特定のファイル名に対して、正しいプロセスを起動します。
- 関連付けられたプロセスがない場合は、適切なシェル ダイアログがユーザーに関連付けを求めるプロンプトを表示する必要があります。
- アプリケーションの起動中、このアプリケーションは Z オーダーの後ろ (または起動中のアプリのすぐ後ろ) に移動し、そこにとどまる必要があります。
ステップ3は私が正しくないものです。psd ファイルを使用して Photoshop を起動していますが、aplash 画面が表示されている間、アプリがフォーカスを求めて戦うため点滅します。ちゃんと起動すれば問題ないのですが、フラッシュ画面表示中のちらつきが気になりません。
これまでの私の最善の試みは次のとおりです。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Romy.Core
{
internal static class Example
{
public const int SW_RESTORE = 9;
private static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
private const uint SWP_NOACTIVATE = 0x0010;
private const uint SWP_NOMOVE = 0x0002;
private const uint SWP_NOSIZE = 0x0001;
public static void SendWindowBack(IntPtr handle)
{
NativeMethods.SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
public static async void ShellExecuteFile(this IWin32Window window, string filename)
{
var p = Process.Start(new ProcessStartInfo()
{
FileName = filename,
Verb = "open",
UseShellExecute = true,
ErrorDialog = true
});
SendWindowBack(window.Handle);
try
{
await Task.Run(async () =>
{
try
{
p.WaitForInputIdle();
IntPtr handle = p.MainWindowHandle;
while (handle == IntPtr.Zero)
{
await Task.Delay(TimeSpan.FromMilliseconds(250D));
handle = p.MainWindowHandle;
}
if (handle != IntPtr.Zero)
{
if (NativeMethods.IsIconic(handle))
NativeMethods.ShowWindowAsync(handle, SW_RESTORE);
if (NativeMethods.SetForegroundWindow(handle))
NativeMethods.SetActiveWindow(handle);
}
}
catch (InvalidOperationException) { }
catch (PlatformNotSupportedException) { }
catch (NotSupportedException) { }
catch (Exception ex) { ex.Log(); }
}).TimeoutAfter(TimeSpan.FromSeconds(3D));
}
catch (TimeoutException) { }
}
[SuppressUnmanagedCodeSecurity]
internal static class NativeMethods
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool IsIconic(System.IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetForegroundWindow(System.IntPtr hWnd);
[DllImport("user32.dll")]
internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ShowWindowAsync(System.IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
internal static extern System.IntPtr SetActiveWindow(System.IntPtr hWnd);
}
}
}