singlepost

Нужна помощ в коде << На главную или назад  

Задача: Запуск из своей софтины прогину и если она в течении заданного таймоута не отработает принудительно завершить. Мой код
// 3апуск приблуды
HANDL hProc = ShellExegute(…);

// Если всё плохо пытаемся завершить процесс
TerminateProcess(hProc,0);

Ошибки при компиляции не возникает все пашет как надо кроме принудительного завершения процесса (запущеная приблуда как весит так и весела). Пишу на C++. Гугл не помог. Может кто в ошибку ткнео носом. Буду благодарен.

75 ответов в теме “Нужна помощ в коде”

  1. 32
    Алексей Орлов ответил:

    По поводу CreateProcessпри работе с её есть небольшие танци с бубном (в отличае от шела) я остановился на таком варианте:

    CreateProcess(NULL,f,NULL,NULL,FALSE,NULL,NULL,MuDirName,&cif,&pi)

    Где f- командная строка которая должна иметь вид: ""<путь к приблуде>"" ""<параметры запуска>"" при этом при генерации пути все символу \ должны быть заменяны на \\ иначе функция сходит с ума.
    MuDirName- путь к директории которая будет для процесса дефолтной.

    P.S.: Это так для тех кто с ей тоже мучался.

  2. 31
    Вячеслав Барболин ответил:

    Во. =)
    Ну так же гораздо красивше! =)

    А для синхронизации работы нескольких процессов/потоков при работе с одним ресурсом (файлом и т.п.) существует механизм мьютексов.
    CreateMutex / WaitForSingleObject / ReleaseMutex / CloseHandle.

    //msdn.microsoft.com/en-us/library/ms686927.aspx

    Не то, чтобы это проще, чем пытаться открывать файл, но это универсальнее, правильнее, и, в общем-то, не сильно сложнее. )

  3. 30
    Алексей Орлов ответил:

    Вячеслав "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. 29
    Алексей Орлов ответил:

    Как ты заметил приложение как раз висит и должно висеть по замыслу пока не отработает второе приложение. Так кк этот код отвечает за запуск консольног почтового клиента и пока свежая почта не будет полученна с сервера и не обработанна работа остальной части кода всёравно бессмысленна. Да и само основное приложение консольное и работает как демон на сервере с управлением через конфигурационные файлы с удалённой машины. Поэтому тут многопоточность нужна как сабаке пятая лапа.

  5. 28
    Алексей Орлов ответил:

    А тот подход что описывал и использую уже очень давно часто раньше юзал когда пр работе нскольких приложений они должны использовать одни и те же файлы и чтоб небыло накладок типа одна приблуда открыла файл и началя в его писать что нить а другой в это время вздумалось его прочитать таким образом защиту от вылетов и некорректного ввода строил и пока она ни разу не подводило даже при совместной работе с одними файлами десятков софтин ожновременно. Хотя прекрасно знаю что подход далёк от совершенства но пашет какнужно и надёжен да и проц не грузит по напрасну и системе он обходиться меньше чем в десяток команд процессору.

  6. 27
    Алексей Орлов ответил:

    Сенька. Погуглю.

  7. 26
    Вячеслав Барболин ответил:

    Вообще, это делается при помощи WaitForSingleObject с нужным таймаутом в отдельном потоке.
    Поскольку при твоём подходе твоё приложение всё равно "висит" во время ожидания, можно забить на отдельный поток и делать в основном.

    За примерами в гугль. Наверняка их есть. =)

  8. 25
    Алексей Орлов ответил:

    Таким способом проверки отработала прога или нет еще с начальных курсов универа по привычке пользуюсь. Хотя код при этом и индийский получаеться но пока меня не подводил и всем устраивает, а по сему искать другие способы или что то другое изобретать как то лень. Если есть готовый пример чего нить рационального и правельного, будь добр поделись. Буду весьма признательным.

  9. 24
    Алексей Орлов ответил:

    Без слипов проц подгружается да и код работает только раз при старте софтины. :) ))

  10. 23
    Артур Терменжи ответил:

    ну может не показатель, но я бы в первую очередь сверялся по мсдну, а потом по другим источникам

  11. 22
    Вячеслав Барболин ответил:

    Угу, протестил. )

    Не. Как первичный источник инфы – мсдн, разумеется, незаменим.
    Просто нельзя ему слепо доверяться на все сто. Там хватает ошибок, причём в основном логических.

  12. 21
    Артур Терменжи ответил:

    ну это да
    особенно по винапишным функциям

  13. 20
    Артур Терменжи ответил:

    может ты и прав
    в мсдне пишут только про меньшее 32

  14. 19
    Вячеслав Барболин ответил:

    Ууупс. )
    Неа. Я таки не прав. )
    Попробую найти с чем же я его (ShellExecute) перепутал.

    Хотя МСДН это, к сожалению, не показатель. Там, как показывает практика, весьма много ошибок и неточностей.

    UPD: А перепутал я его с банальным VB'шным Shell.

  15. 18
    Вячеслав Барболин ответил:

    2 Артур Терменжи
    Таки не только. Если возвращаемое значение меньше 32 – это код ошибки. Если больше – это ProcessID, или PID. А что с ним можно дальше делать, я написал.

    Впрочем, CreateProcess тоже неплохо. Хотя итоговый код и вызывает некоторое.. Кхм.. Недоумение? )
    Слипы, попытки открытия файла в цикле.. Жесть.

  16. 17
    Алексей Орлов ответил:

    Вопрос снят. Всем спасибо за помощь. Вот полный код части проги которая интересовала, может кому пригодиться.:

    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.: Код лучился немного индийский но пашет как надо. :) )))) Ещё раз всем спасибо.

  17. 16
    Артур Терменжи ответил:

    да лушче в мсдне вначале глядеть

  18. 15
    Алексей Орлов ответил:

    Вячеслав "iGrok" Барболин просто набрал ShellExecute и на первых же ркусских форумах кто то ляпнул что хендл вернает вот я на радостях и давай пробовать. Щас ошибка понятна.

  19. 14
    Алексей Орлов ответил:

    //delphicode.ru/procedures/shellexecute.htm

    ФУНКЦИЯ ShellExecute

    Функция ShellExecute используется как для запуска какого-либо приложения, так и для открытия, либо печати документа. К примеру при выполнении открытия документа с расширением .xls Microsoft Excel будет запущен автоматически. Обратите внимание, что для использования функции в раздел Uses необходимо включить модуль ShellAPI.

    function ShellExecute(Wnd: HWnd; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): THandle;


    и вот эта небольшая статейка с толку сбила вот и всё. А так как раньше с этим не сталкивался поэтому поверил и дальше копать не стал.

  20. 13
    Алексей Орлов ответил:

    //articles.org.ru/cn/showdetail.php?cid=5938 вот тут всё расжованно жаль сразу до её руки не дошли

  21. 12
    Алексей Орлов ответил:

    Артур Терменжи спасибо. Ошибку понял. Буду исправлять. Раньше часто этой функцией пользовался но с вертаемыми значениями от её дел приходить не имелось. Как грица век живи век учись.

  22. 11
    Леонид Максимов ответил:

    >> Кто хорошо программирует В Visual Basic 6.0

    я хорошо программирую в Visual Basic for Applications. по сути то же самое.

    >> но этот хэндл может быть использован только для получения кода ошибки

    а для получения идентификатора процесса использован быть не может? о_О

  23. 10
    Артур Терменжи ответил:

    ShellExecute возвращает HINSTANCE
    но этот хэндл может быть использован только для получения кода ошибки

  24. 9
    Вячеслав Барболин ответил:

    Так я открывал наверное, раз пишу. )
    Примеров того, о чём просит ТС, там нет, вот я и не понимаю, зачем ты дал эту ссылку.

    Ну или у нас МСДН разный.

    З.Ы. Нет, конечно если ты имел в виду, что нужно пройти "чуть дальше", найти там Ex-вариант, который отдаёт хэндл процесса, тогда, конечно, да… Но это что ж должно упасть человеку на голову, чтобы такое "просветление" наступило, если он сам этого в гугле не нашёл?

  25. 8
    Данияр Ходжабеков ответил:

    Кто хорошо программирует В Visual Basic 6.0

  26. 7
    Евгений Гаврин ответил:

    Вячеслав "iGrok" Барболин, а ты открой и наступит просветление.

  27. 6
    Валера Марсель ответил:

    Алексей Орлов, //www.ozhegov.org/words/25372.shtml

  28. 5
    Вячеслав Барболин ответил:

    Ну-ка покажи, где это в гугле такая чушь написана?

    #3, пример чего? Использования ShellExecute, или завершения процесса, запущенного при помощи ShellExecute?

    <Тут была моя ошибка>

  29. 4
    Евгений Гаврин ответил:

    //msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx
    Там пример.

  30. 3
    Алексей Орлов ответил:

    Гугл сказал

  31. 2
    Алексей Орлов ответил:

    Сенька. Завтра затещу.

  32. 1
    Вячеслав Барболин ответил:

    А с чего ты вообще взял, что ShellExecute возвращает хэндл процесса?

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.