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 ответ
То, что вы пробовали, действительно, очевидно, неправильно, но вопрос в том, понимаете ли вы, что с ним не так. _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
документация? Там есть примеры. Множественное число.
То, что вы хотели написать, это:
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);
Если вы не делаете что-то помимо того, что мы видим здесь, комментарий Дэвида, вероятно, прав, и вы должны использовать std::thread
или же std::async
,
Также обратите внимание, что принимая результат _beginthread
(в отличие от результата _beginthreadex
или же CreateThread
) небезопасно, поскольку может быть недействительным, как указано в документации. Не только это, но _beginthread
возвращаемое значение на самом деле не HANDLE
(это какая-то рана ручки, но не HANDLE
!), так что вы не можете WaitForSingleObject
в теме:
_beginthreadex
Функция дает вам больше контроля над тем, как создается поток, чем_beginthread
делает._endthreadex
функция также более гибкая. Например, с_beginthreadex
Вы можете использовать информацию о безопасности, установить начальное состояние потока (запущено или приостановлено) и получить идентификатор потока вновь созданного потока. Вы также можете использовать дескриптор потока, который возвращается_beginthreadex
с API синхронизации, которые вы не можете сделать с_beginthread
,Безопаснее использовать
_beginthreadex
чем_beginthread
, Если поток, который генерируется_beginthread
быстро выходит, дескриптор, который возвращается вызывающему_beginthread
может быть недействительным или указывать на другой поток. Тем не менее, ручка, которая возвращается_beginthreadex
должен быть закрыт вызывающим_beginthreadex
так что он гарантированно будет действительным дескриптором, если_beginthreadex
не вернул ошибку.
Поскольку этот поток вызывает только одну функцию и завершает работу, он практически максимизирует вероятность того, что этот дескриптор не будет действительным. И даже если бы это было, вы все равно не могли бы использовать его для WaitForSingleObject
,