Задача: Запуск из своей софтины прогину и если она в течении заданного таймоута не отработает принудительно завершить. Мой код
// 3апуск приблуды
HANDL hProc = ShellExegute(…);
…
// Если всё плохо пытаемся завершить процесс
TerminateProcess(hProc,0);
Ошибки при компиляции не возникает все пашет как надо кроме принудительного завершения процесса (запущеная приблуда как весит так и весела). Пишу на C++. Гугл не помог. Может кто в ошибку ткнео носом. Буду благодарен.
5 марта 2010 в 15:03
По поводу CreateProcessпри работе с её есть небольшие танци с бубном (в отличае от шела) я остановился на таком варианте:
CreateProcess(NULL,f,NULL,NULL,FALSE,NULL,NULL,MuDirName,&cif,&pi)
Где f- командная строка которая должна иметь вид: ""<путь к приблуде>"" ""<параметры запуска>"" при этом при генерации пути все символу \ должны быть заменяны на \\ иначе функция сходит с ума.
MuDirName- путь к директории которая будет для процесса дефолтной.
P.S.: Это так для тех кто с ей тоже мучался.
4 марта 2010 в 20:05
Во. =)
Ну так же гораздо красивше! =)
А для синхронизации работы нескольких процессов/потоков при работе с одним ресурсом (файлом и т.п.) существует механизм мьютексов.
CreateMutex / WaitForSingleObject / ReleaseMutex / CloseHandle.
//msdn.microsoft.com/en-us/library/ms686927.aspx
Не то, чтобы это проще, чем пытаться открывать файл, но это универсальнее, правильнее, и, в общем-то, не сильно сложнее. )
4 марта 2010 в 13:05
Вячеслав "iGrok" Барболин ещё раз спасибо. Вот что вышло в итоге:
STARTUPINFO cif;
ZeroMemory(&cif,sizeof(STARTUPINFO));
PROCESS_INFORMATION pi;
if (CreateProcess(NULL,<командная строка>,NULL,NULL,FALSE,NULL,NULL, NULL,&cif,&pi) == TRUE)
{
WaitForSingleObject(pi.hProcess,TimeOut);
TerminateProcess(pi.hProcess,0);
}
4 марта 2010 в 11:02
Как ты заметил приложение как раз висит и должно висеть по замыслу пока не отработает второе приложение. Так кк этот код отвечает за запуск консольног почтового клиента и пока свежая почта не будет полученна с сервера и не обработанна работа остальной части кода всёравно бессмысленна. Да и само основное приложение консольное и работает как демон на сервере с управлением через конфигурационные файлы с удалённой машины. Поэтому тут многопоточность нужна как сабаке пятая лапа.
4 марта 2010 в 11:02
А тот подход что описывал и использую уже очень давно часто раньше юзал когда пр работе нскольких приложений они должны использовать одни и те же файлы и чтоб небыло накладок типа одна приблуда открыла файл и началя в его писать что нить а другой в это время вздумалось его прочитать таким образом защиту от вылетов и некорректного ввода строил и пока она ни разу не подводило даже при совместной работе с одними файлами десятков софтин ожновременно. Хотя прекрасно знаю что подход далёк от совершенства но пашет какнужно и надёжен да и проц не грузит по напрасну и системе он обходиться меньше чем в десяток команд процессору.
4 марта 2010 в 10:03
Сенька. Погуглю.
4 марта 2010 в 2:02
Вообще, это делается при помощи WaitForSingleObject с нужным таймаутом в отдельном потоке.
Поскольку при твоём подходе твоё приложение всё равно "висит" во время ожидания, можно забить на отдельный поток и делать в основном.
За примерами в гугль. Наверняка их есть. =)
4 марта 2010 в 0:05
Таким способом проверки отработала прога или нет еще с начальных курсов универа по привычке пользуюсь. Хотя код при этом и индийский получаеться но пока меня не подводил и всем устраивает, а по сему искать другие способы или что то другое изобретать как то лень. Если есть готовый пример чего нить рационального и правельного, будь добр поделись. Буду весьма признательным.
4 марта 2010 в 0:05
Без слипов проц подгружается да и код работает только раз при старте софтины. ))
3 марта 2010 в 21:00
ну может не показатель, но я бы в первую очередь сверялся по мсдну, а потом по другим источникам
3 марта 2010 в 21:00
Угу, протестил. )
Не. Как первичный источник инфы – мсдн, разумеется, незаменим.
Просто нельзя ему слепо доверяться на все сто. Там хватает ошибок, причём в основном логических.
3 марта 2010 в 21:00
ну это да
особенно по винапишным функциям
3 марта 2010 в 20:05
может ты и прав
в мсдне пишут только про меньшее 32
3 марта 2010 в 20:05
Ууупс. )
Неа. Я таки не прав. )
Попробую найти с чем же я его (ShellExecute) перепутал.
Хотя МСДН это, к сожалению, не показатель. Там, как показывает практика, весьма много ошибок и неточностей.
UPD: А перепутал я его с банальным VB'шным Shell.
3 марта 2010 в 20:04
2 Артур Терменжи
Таки не только. Если возвращаемое значение меньше 32 – это код ошибки. Если больше – это ProcessID, или PID. А что с ним можно дальше делать, я написал.
Впрочем, CreateProcess тоже неплохо. Хотя итоговый код и вызывает некоторое.. Кхм.. Недоумение? )
Слипы, попытки открытия файла в цикле.. Жесть.
3 марта 2010 в 19:00
Вопрос снят. Всем спасибо за помощь. Вот полный код части проги которая интересовала, может кому пригодиться.:
STARTUPINFO cif;
ZeroMemory(&cif,sizeof(STARTUPINFO));
PROCESS_INFORMATION pi;
if (CreateProcess("<путь к нашей приблуде для запуска>",NULL,
NULL,NULL,FALSE,NULL,NULL,NULL,&cif,&pi)==TRUE)
{
Sleep(100);// Немного поспим
// Начинаем ждать пока приблуда отработает
while (mark)
{
// Пытаемся открыть файл нашей приблуды для дозаписи
frm = fopen("<путь к нашей приблуде для запуска>", "a");
// Если ось дала открыть значит файл не занят а посему он отработал своё
if (frm !=0)
{
// Закрываем файл
fclose(frm);
// Опускаем флаг сигнализируя что пора выйти из цикла
mark = FALSE;
}
// Увеличиваем счётчик тиков
to++;
// Проверяем не превышен ли таймоут (10сек)
if (to == 100)
{
// Опускаем флаг сигнализируя что пора выйти из цикла
mark = FALSE;
TerminateProcess(pi.hProcess,0); // Грохаем процесс
}
else Sleep(100);
}
}
// Живём своей жизнью
…
P.S.: Код лучился немного индийский но пашет как надо. )))) Ещё раз всем спасибо.
3 марта 2010 в 16:03
да лушче в мсдне вначале глядеть
3 марта 2010 в 15:05
Вячеслав "iGrok" Барболин просто набрал ShellExecute и на первых же ркусских форумах кто то ляпнул что хендл вернает вот я на радостях и давай пробовать. Щас ошибка понятна.
3 марта 2010 в 15:05
//delphicode.ru/procedures/shellexecute.htm
ФУНКЦИЯ ShellExecute
Функция ShellExecute используется как для запуска какого-либо приложения, так и для открытия, либо печати документа. К примеру при выполнении открытия документа с расширением .xls Microsoft Excel будет запущен автоматически. Обратите внимание, что для использования функции в раздел Uses необходимо включить модуль ShellAPI.
function ShellExecute(Wnd: HWnd; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): THandle;
…
и вот эта небольшая статейка с толку сбила вот и всё. А так как раньше с этим не сталкивался поэтому поверил и дальше копать не стал.
3 марта 2010 в 15:05
//articles.org.ru/cn/showdetail.php?cid=5938 вот тут всё расжованно жаль сразу до её руки не дошли
3 марта 2010 в 15:04
Артур Терменжи спасибо. Ошибку понял. Буду исправлять. Раньше часто этой функцией пользовался но с вертаемыми значениями от её дел приходить не имелось. Как грица век живи век учись.
3 марта 2010 в 15:03
>> Кто хорошо программирует В Visual Basic 6.0
я хорошо программирую в Visual Basic for Applications. по сути то же самое.
>> но этот хэндл может быть использован только для получения кода ошибки
а для получения идентификатора процесса использован быть не может? о_О
3 марта 2010 в 14:05
ShellExecute возвращает HINSTANCE
но этот хэндл может быть использован только для получения кода ошибки
3 марта 2010 в 13:01
Так я открывал наверное, раз пишу. )
Примеров того, о чём просит ТС, там нет, вот я и не понимаю, зачем ты дал эту ссылку.
Ну или у нас МСДН разный.
З.Ы. Нет, конечно если ты имел в виду, что нужно пройти "чуть дальше", найти там Ex-вариант, который отдаёт хэндл процесса, тогда, конечно, да… Но это что ж должно упасть человеку на голову, чтобы такое "просветление" наступило, если он сам этого в гугле не нашёл?
3 марта 2010 в 10:01
Кто хорошо программирует В Visual Basic 6.0
3 марта 2010 в 10:01
Вячеслав "iGrok" Барболин, а ты открой и наступит просветление.
3 марта 2010 в 9:01
Алексей Орлов, //www.ozhegov.org/words/25372.shtml
3 марта 2010 в 3:02
Ну-ка покажи, где это в гугле такая чушь написана?
#3, пример чего? Использования ShellExecute, или завершения процесса, запущенного при помощи ShellExecute?
<Тут была моя ошибка>
3 марта 2010 в 2:03
//msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx
Там пример.
3 марта 2010 в 2:03
Гугл сказал
3 марта 2010 в 2:03
Сенька. Завтра затещу.
3 марта 2010 в 2:01
А с чего ты вообще взял, что ShellExecute возвращает хэндл процесса?