_beginthread中的ShellExecute

时间:2017-01-18 15:17:59

标签: c++ winapi shellexecute beginthread

我需要运行例如:

ShellExecute(NULL, "open", "program.exe", NULL, NULL, SW_HIDE);

作为新线程,但我不知道如何。 我试过这个:

HANDLE hThread = (HANDLE) _beginthread(ShellExecute(NULL, "open", "program.exe", NULL, NULL, SW_HIDE), 0, NULL);
WaitForSingleObject( hThread, INFINITE );

但显然这是错误的,无法编译。我该怎么做?

1 个答案:

答案 0 :(得分:3)

你所尝试的确实显然是错的,但问题是你是否理解它的错误。 _beginthread指向函数的指针(使用特定的原型和调用约定)作为其第一个参数。

写作时

HANDLE hThread = (HANDLE) _beginthread(ShellExecute(NULL, "open", "program.exe", NULL, NULL, SW_HIDE), 0, NULL);

您正试图通过_beginthread调用ShellExecute结果(在当前主题中)HINSTANCE,而_beginthread我们需要一个void( __cdecl *)( void * )(指向__cdecl函数的指针,其中包含一个void*参数并返回void。)

不仅你的代码不起作用,因为你试图传递一个函数到指针的HINSTANCE,它没有任何意义。你读过_beginthread documentation了吗?那里有例子。复数。

你打算写的是:

HANDLE hThread = (HANDLE) _beginthread(ThreadFunc, 0, NULL);

下式给出:

void __cdecl ThreadFunc(void*) {
    ShellExecute(NULL, "open", "program.exe", NULL, NULL, SW_HIDE);
}

或者,以更紧凑和易于阅读的形式:

HANDLE hThread = (HANDLE)
                 _beginthread([](void*) {
                     ShellExecute(NULL, "open", "program.exe", NULL, NULL, SW_HIDE);
                 },
                 0, NULL);

除非你正在做我们在这里看到的事情,否则David的评论可能是对的,你应该使用std::threadstd::async

另请注意,将_beginthread(与_beginthreadexCreateThread的结果形成对比)的结果不安全,因为它可能无效,如文档中所述。不仅如此,_beginthread的返回值实际上不是HANDLE(它是句柄的痛,但不是HANDLE!),所以你不能{ {1}}:

  

WaitForSingleObject函数让您可以更好地控制创建线程的方式,而不是_beginthreadex_beginthread功能也更灵活。例如,使用_endthreadex,您可以使用安全信息,设置线程的初始状态(运行或挂起),并获取新创建的线程的线程标识符。 您还可以使用_beginthreadex返回的带有同步API的线程句柄,而_beginthreadex 则无法做到这一点。

     

使用_beginthread_beginthreadex更安全。如果_beginthread生成的线程快速退出,则返回给_beginthread调用者的句柄可能无效或指向另一个线程。但是,_beginthread返回的句柄必须由_beginthreadex的调用者关闭,因此如果_beginthreadex未返回错误,则保证它是有效的句柄。

由于此线程只调用一个函数并退出,因此几乎可以最大化此句柄无效的可能性。即使是这样,你仍然无法将它用于_beginthreadex