如何使用 C++ WinAPI 功能强制打开文件 "silently"(最小化,不活动)?

How to force open file "silently" (minimized, not active) using c++ WinAPI functional?

在我的 WinAPI C++ 应用程序中,我尝试使用 ShellExecuteEx:

使用默认系统播放器打开音频文件
int OpenFileWithDefaultProgram(const std::wstring& path, int showMode, HANDLE* hProc) {
    SHELLEXECUTEINFO shInfo;
    ::ZeroMemory(&shInfo, sizeof(SHELLEXECUTEINFO));
    shInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    shInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    shInfo.hwnd = NULL;
    shInfo.lpVerb = L"open";
    shInfo.lpFile = path.c_str();
    shInfo.nShow = showMode;
    ::ShellExecuteEx(&shInfo);
    *hProc = shInfo.hProcess;
    return (int)shInfo.hInstApp;
}

OpenFileWithDefaultProgram函数是这样调用的:

HANDLE hProc;
int error = OpenFileWithDefaultProgram(path, SW_SHOWMINNOACTIVE, &hProc);
if (error <= 32) {
    // Process error
} else {
    // Some actions
}

然而 SW_SHOWMINNOACTIVE 参数被某些播放器忽略(例如 MediaPlayerClassic HomeCinema - MPC HC),这导致打开播放器时更改前景 window 甚至显示播放器 window 在某些 PC 上未最小化。

第一个问题是:是否可以在"silent"模式下强制打开播放器(最小化且不激活)?

我也尝试过使用 GetForegroundWindowSetForegroundWindow,直到我添加 SleepOpenFileWithDefaultProgram 之后(据我了解,播放器需要一些时间来初始化,在此期间前景 window 不会改变):

HWND hWndForeground = GetForegroundWindow();
HANDLE hProc;
int error = OpenFileWithDefaultProgram(path, SW_SHOWMINNOACTIVE, &hProc);
if (error <= 32) {
    // Process error
} else {
    Sleep(100);
    SetForegroundWindow(hWndForeground);
    // Some actions
}

这段代码完美地恢复了前景window,但我不喜欢我需要用作Sleep函数参数的常量。

因此,第二个问题是:是否可以在播放器初始化的那一刻"wake up"线程?或者,我应该如何确定播放器初始化所需的时间(考虑到默认播放器可以是任何东西并且启动时间完全不同)?

注:

The first question is: is it possible to force opening player in "silent" mode (minimized and not becoming active)?

不,你能做的最好的就是请求它,请求可以被忽略。你已经发现了那个部分。

The second question: is it possible to "wake up" the thread at the exact moment when the player is initialized?

不,没有定义进程完全初始化的时刻。您已经发现 WaitForInputIdle 及其限制。但是想象一个媒体播放器在后台获取 CD 封面图像(不是那么牵强,不需要为此延迟音频)——它什么时候完成初始化?

此外,请记住 ShellExecute 甚至可能不会启动新进程。如果有一个现有的,它可能会用它来打开文件。