Форум » [x]Harbour » Как "заморозить" выполнение программы ? » Ответить

Как "заморозить" выполнение программы ?

Andrey: Всем привет. Подскажите как можно остановить (заморозить) выполнение программы до выполнения определенного события в другой программе ? Т.е. я из своей программы на хХарборе (терминалка) запускаю допустим программу "Скачивания из инета" на МиниГуи. Терминалку на хХарборе нужно "заморозить" до конца скачивания ! Иначе ЮЗВЕР будет тыкать мышкой раньше времени.... После того как скачался файл нужно вернуться обратно в терминалку на хХарборе ! Можно конечно сделать "семафорный файл" после получения файла из инета, а в хХарборе проверять каждую минуту есть такой файл или нет. Но это можно было делать и на Клипере (проверку файла). А что нам может предложить хХарбор ?

Ответов - 44, стр: 1 2 3 All

SergejKis: Andrey пишет: А что нам может предложить хХарбор ? Я использую для таких вещей скриптовый язык AutoIt3. Запускаем прогу на МиниГуи (из нее запуск AutoIt3) и делаем терминальное окно hide: WinSetState("myprogram.exe", "", @SW_HIDE). При завершению проги на МиниГуи (из нее запуск AutoIt3) и делаем: WinSetState("myprogram.exe", "", @SW_SHOW) На Harbor не знаю как это сделать, возможно гуру подскажут.

SADSTAR2: WAITRUN

Andrey: SADSTAR2 пишет: WAITRUN Нет такой функции в хХарборе !


Sergey Spirin: Andrey пишет: Всем привет. Подскажите как можно остановить (заморозить) выполнение программы до выполнения определенного события в другой программе ? Вообще-то была такая тема http://clipper.b.qip.ru/?1-4-0-00000327-000-20-0 Там WaitForSingleObject() ждал окончания другого процесса, но WaitForSingleObject()/WaitForMultipleObjects() могут "ждать" много разных событий и т.д Единственное, чтобы всем этим манипулировать, надо знать в некоторой степени С... Как сделать тоже самое только Харбором - не знаю.

SADSTAR2: Andrey пишет: Нет такой функции в хХарборе ! может это поможет http://lists.harbour-project.org/pipermail/harbour-users/2008-December/000051.html

gfilatov2002: Andrey пишет: Нет такой функции в хХарборе Зато такая функция есть в библиотеке минигуи HB_FUNC( WAITRUN ) { DWORD dwExitCode; STARTUPINFO stInfo; PROCESS_INFORMATION prInfo; BOOL bResult; ZeroMemory( &stInfo, sizeof(stInfo) ); stInfo.cb = sizeof(stInfo); stInfo.dwFlags=STARTF_USESHOWWINDOW; stInfo.wShowWindow=hb_parni(2); bResult = CreateProcess(NULL, hb_parc(1) , NULL, NULL, TRUE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &stInfo, &prInfo); if (!bResult) { hb_retl(-1); } WaitForSingleObject(prInfo.hProcess,INFINITE); GetExitCodeProcess( prInfo.hProcess, &dwExitCode ); hb_retnl( dwExitCode ); }

Andrey: gfilatov2002 пишет: Зато такая функция есть в библиотеке минигуи А как прикрутить ? В смысле, какие include в заголовках включить ? #pragma BEGINDUMP #include <???.h> #pragma ENDDUMP

Andrey: Возвращаюсь к текущему вопросу, только для ShellExecute . Urri пишет: Подскажите, а можно ли затормозить выполнение программы до того момента, пока то, что вызывалось ShellExecute, завершит свою работу? Мне тоже нужно подождать пока ShellExecute выполнит работу, ну и выключить комп потом или продолжит что-то делать.

PSP: Вот в этой теме было: http://clipper.borda.ru/?1-4-0-00000327-000-10001-0-1250159714

Andrey: PSP пишет: Вот в этой теме было: http://clipper.borda.ru/?1-4-0-00000327-000-10001-0-1250159714 Да читал я там до этого. Только там конечного результата не было ! Что конкретно использовать ? WAITRUN( cRun ) EXECANDWAIT() - какие параметры передавать ?

Andrey: Разобрался. Сделал тестовую программу. Обе функции работают. Кому интересно - выкладываю: http://files.mail.ru/B95OVE

Andrey: Хорошую вещь сделал Pasha - функцию EXECANDWAIT в http://clipper.borda.ru/?1-4-0-00000327-000-10001-0-1250159714 Только сейчас оценил. Можно вызвать через батник Notepad или WinWord и пока не завершишь работу в них, программа "заморожена" !!! Спасибо БОЛЬШОЕ Pasha ! Пример здесь: http://files.mail.ru/MYGRX9

Pasha: Andrey пишет: Хорошую вещь сделал Pasha - функцию EXECANDWAIT Только я ее не делал, а механически перевел с паскаля на С

Andrey: Pasha пишет: Только я ее не делал, а механически перевел с паскаля на С Все равно БОЛЬШОЕ СПАСИБО ! Никто другой же не сделал !!!

Andrey: Столкнулся с проблемой. При использовании терминала GTWVT - нет вывода на экран запущенного батника через функцию EXECANDWAIT() На GTWIN - все команды батника отображаются в окне задачи. Пример тут: http://files.mail.ru/TAU7FT Там в батнике идет разархивация архива 7z, с обработкой ошибки. Нужно подправить пути и добавить любой архив 7z. Вопрос к знатокам: можно ли сделать еще доп.параметр "показа/скрытия" вывода на экран для GTWVT ? Или вывод в другом окне ?

Andrey: Нужно сделать теперь другую задачу. Из МиниГуи вызывать с ожиданием терминалку на хХарборе ! Очень хотелось сделать попроще. WAITRUN() не подошел. Вообще не показывает запущенную терминалку (gtwin или gtwvt) ! В процессах сидит, на экране нет ! Такая же беда как на хХарборе ! Описания в ХЕЛПЕ по МиниГуи нет, искал WAITRUN() по исходникам.... И о чудо - нашел WAITRUNTERM() для терминалки ! Работает !!! Пишу, может кому пригодиться, чтоб не искали в ДОКЕ !

Avf: Пришлось изменять старые программы, не переписаннные в GUI. xHarbour Compiler build 1.2.1 + GTWVT-terminal После вызова WAITRUNTERM( не восстанавливается экран после выхода из внешней программы). Например, вызов nRc := WaitRunTerm("Wordpad.exe") WAITRUNTERM /* WaitRunTerm contributed by Kevin Carmody (i@kevincarmody.com) 2007.11.16 */ HB_FUNC( WAITRUNTERM ) { PHB_ITEM pWaitProc = hb_param( 4, HB_IT_BLOCK ); ULONG ulWaitMsec = ( ISNIL( 5 ) ? 2000 : hb_parnl( 5 ) ); BOOL bTerm = FALSE; BOOL bWait; ULONG ulNoSignal; DWORD dwExitCode; STARTUPINFO stInfo; PROCESS_INFORMATION prInfo; BOOL bResult; ZeroMemory( &stInfo, sizeof( stInfo ) ); stInfo.cb = sizeof( stInfo ); stInfo.dwFlags = STARTF_USESHOWWINDOW; stInfo.wShowWindow = ( WORD ) ( ISNIL( 3 ) ? 5 : hb_parni( 3 ) ); bResult = CreateProcess ( NULL, ( char * ) hb_parc( 1 ), NULL, NULL, TRUE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, ISNIL( 2 ) ? NULL : hb_parc( 2 ), &stInfo, &prInfo ); if( ! bResult ) hb_retnl( -2 ); if( pWaitProc ) { do { ulNoSignal = WaitForSingleObject( prInfo.hProcess, ulWaitMsec ); if( ulNoSignal ) { hb_evalBlock0( pWaitProc ); bWait = hb_parl( -1 ); if( ! bWait ) { if( TerminateProcess( prInfo.hProcess, 0 ) != 0 ) bTerm = TRUE; else bWait = TRUE; } } else bWait = FALSE; } while( bWait ); } else WaitForSingleObject( prInfo.hProcess, INFINITE ); if( bTerm ) dwExitCode = -1; else GetExitCodeProcess( prInfo.hProcess, &dwExitCode ); CloseHandle( prInfo.hThread ); CloseHandle( prInfo.hProcess ); hb_retnl( dwExitCode ); } #pragma ENDDUMP Либо подскажите, пожалуйста, где что не так в EXECANDWAIT для такой связки( не вызывается внешняя программа) : пример вызов nRc := EXECANDWAIT ("Wordpad.exe") EXECANDWAIT HB_FUNC( EXECANDWAIT ) { char * szProg = hb_parc(1); int iShow = hb_parni(2); DWORD dResult = 0xFFFFFFFF; LONG lResult; STARTUPINFO si; PROCESS_INFORMATION proc; memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = iShow; if( CreateProcess(NULL, szProg, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &proc ) ) { WaitForInputIdle(proc.hProcess, INFINITE ); if( WaitForSingleObject( proc.hProcess, INFINITE ) == WAIT_OBJECT_0 ) { if( ! GetExitCodeProcess(proc.hProcess, (LPDWORD) &dResult ) ) dResult = 0xFFFFFFFF; } CloseHandle( proc.hThread ); CloseHandle( proc.hProcess ); } lResult = (LONG) dResult; hb_retnl( lResult ); }

Dima: Avf пишет: EXECANDWAIT ("Wordpad.exe") а если путь указать к Wordpad.exe

Avf: Wordpad в той же директории что и программа ( это просто пример )

Dima: Avf Harbour 3.2 проверил работает нормально Исходник [pre2] proc main EXECANDWAIT("notepad.exe") return #pragma BEGINDUMP #include <windows.h> #include "hbapi.h" #include "hbvm.h" #include "hbwinuni.h" HB_FUNC( EXECANDWAIT ) { void * hProg; HB_SIZE nLen; LPCTSTR lpProg = HB_PARSTR( 1, &hProg, &nLen ); DWORD dwResult = 0xFFFFFFFF; STARTUPINFO si; PROCESS_INFORMATION proc; memset( &si, 0, sizeof(si) ); si.cb = sizeof( si ); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = (WORD) hb_parnldef( 2, SW_SHOWDEFAULT ); if( CreateProcess( NULL, HB_STRUNSHARE( &hProg, lpProg, nLen ), /* Command line (Unicode version needs an non-const buffer) */ NULL, NULL, FALSE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &proc ) ) { hb_vmUnlock(); WaitForInputIdle( proc.hProcess, INFINITE ); if( WaitForSingleObject( proc.hProcess, INFINITE ) == WAIT_OBJECT_0 ) { if( ! GetExitCodeProcess( proc.hProcess, &dwResult ) ) dwResult = 0xFFFFFFFF; } CloseHandle( proc.hThread ); CloseHandle( proc.hProcess ); hb_vmLock(); } hb_retnint( dwResult ); hb_strfree( hProg ); } #pragma ENDDUMP [/pre2]

Andrey: Avf пишет: Пришлось изменять старые программы, не переписаннные в GUI. xHarbour Compiler build 1.2.1 Попробуй 1.2.3 - в предыдущем ошибок много... Avf пишет: Либо подскажите, пожалуйста, где что не так в EXECANDWAIT для такой связки( не вызывается внешняя программа) : Она вызывается, просто на экране не отображается. Читай выше - я столкнулся с этим. Avf пишет: После вызова WAITRUNTERM( не восстанавливается экран после выхода из внешней программы). Сделай проще: SAVE SCREEN WAITRUNTERM(cFile) RESTORE SCREEN

Avf: Вариант с WAITRUNTERM работает на XHarbour EXECANDWAIT, приведенный выше для Harbour, для ХHarbour должен выглядеть как-то иначе.

Andrey: Andrey пишет: Хорошую вещь сделал Pasha - функцию EXECANDWAIT в http://clipper.borda.ru/?1-4-0-00000327-000-10001-0-1250159714 Только сейчас оценил. Можно вызвать через батник Notepad или WinWord и пока не завершишь работу в них, программа "заморожена" !!! Программа на терминалке хХарбора 1.2.3 Делаю показ надписи и вызываю программу на МиниГуи: [pre2]@ 10,10 SAY "Загружаю модуль ХХХ !" EXECANDWAIT(CurDrive()+":"+DirName()+"\XXX-MiniGui.exe")[/pre2] Как можно сделать замену надписи в терминалке через 10-15 сек на другую ? [pre2]@ 10,10 SAY "Ожидаю закрытия модуля ХХХ !"[/pre2]

Dima: На вскидку... 1. Поток 2. FT_OnTick 3. HB_IdleAdd

Andrey: Dima пишет: 2. FT_OnTick 3. HB_IdleAdd Не работал с этим. Подскажи пожалуйста как это работает ?

PSP: Может просто написать: "Запущено внешнее приложение XXX. Чтобы продолжить, закройте его", а?))

Andrey: PSP пишет: Может просто написать: "Запущено внешнее приложение XXX. Чтобы продолжить, закройте его", а?)) Пока прога на МиниГуи загрузится... Антивирусник его постоянно проверяет, проходит секунд 10. Пользователь тупо пытается нажать ещё раз и раз на кнопку. Из-за этого и вывесил сообщение. Твоя надпись будет нервировать неподготовленного пользователя. Конечно в МиниГуи приложение можно после запуска отправить терминалке сообщение как в примере: * Передача сообщений между приложениями/процессами при помощи сообщения WM_COPYDATA. Но для простой вещи это перебор... Нужно просто через 10-15 секунд изменить надпись.

fil: а таймер незя ?

Andrey: fil пишет: а таймер незя ? А как в хХарборе делать таймер ? Я уже не помню как делать. В Клипере что-то в СТ было, а как сейчас делать не знаю.

Dima: Andrey пишет: А как в хХарборе делать таймер ? http://clipper.borda.ru/?1-4-0-00001192-000-0-0-1498420920 Пост 1539 По Ft_ontick FT_OnTick({|| Mytest() },200) @ 10,10 SAY "Загружаю модуль ХХХ !" EXECANDWAIT(CurDrive()+":"+DirName()+"\XXX-MiniGui.exe") FT_OnTick() Func Mytest() @ 10,10 SAY "Ожидаю закрытия модуля ХХХ !" return nil

Haz: Andrey пишет: Пользователь тупо пытается нажать ещё раз и раз на кнопку. Из-за этого и вывесил сообщение Проще кнопку задисаблить после нажатия, и сообщение что запущено внешнее приложение Х... А при завешении этой Х.. - раздисаблить и убрать сообщение

SergKis: Haz сохранил экран\сделал новый с крупным письмом типа "Ж Д И Т Е ...", потом все воссстановил. Все время так делаю. Пользователь не такой тупой, все понимает, пусть и не с первого раза.

Dima: Можно еще "вертушку" повесить , пока работает внешнее приложение Х , что бы юзер не подумал что прога висит

Andrey: Haz пишет: Проще кнопку задисаблить после нажатия, и сообщение что запущено внешнее приложение Х... А при завешении этой Х.. - раздисаблить и убрать сообщение Нет у меня такого на хХарборе. Dima Спасибо !

Haz: Andrey пишет: Нет у меня такого на хХарборе Не верю (с). Но раз нет, так нет и искать не будем среди множества вариантов.

Dima: Haz пишет: Не верю (с). +1

Dima: Hbnf для иксов Libnf

Dima: чего ж нет если есть в xharbour\contrib\libnf\ontick.c

Dima: Попробуй портировать из Harbour Сырец [pre2] THREAD STATIC t_bOnTick THREAD STATIC t_nTickInterval := 0 THREAD STATIC t_nLastCheck := 0 THREAD STATIC t_hIdle STATIC PROCEDURE __ft_OnTick() IF hb_MilliSeconds() >= ( t_nLastCheck + t_nTickInterval ) t_nLastCheck := hb_MilliSeconds() Eval( t_bOnTick ) ENDIF RETURN PROCEDURE ft_OnTick( bOnTick, nTickInterval ) /* Harbour extension: Harbour will also accept function pointers */ IF HB_ISEVALITEM( bOnTick ) t_bOnTick := bOnTick IF HB_ISNUMERIC( nTickInterval ) t_nTickInterval := ( 1 / 18.20648 ) * nTickInterval * 1000 ENDIF t_nLastCheck := hb_MilliSeconds() IF Empty( t_hIdle ) t_hIdle := hb_idleAdd( {|| __ft_OnTick() } ) ENDIF ELSE t_bOnTick := NIL t_nTickInterval := 0 IF ! Empty( t_hIdle ) hb_idleDel( t_hIdle ) t_hIdle := NIL ENDIF ENDIF RETURN [/pre2]

Dima: Andrey пишет: Я думаю, что не пойдёт из за: убери THREAD , думаю не смертельно

Dima: Andrey пишет: А то мусорница начинается, потом форум читать трудно будет. Не мусори

Andrey: SergKis пишет: сохранил экран\сделал новый с крупным письмом типа "Ж Д И Т Е ...", потом все воссстановил. Все время так делаю. Пользователь не такой тупой, все понимает, пусть и не с первого раза. Сделал для юзера "Ж Д И Т Е ..." cRunExe := M->SetPath + "MiniGui-module.exe " + cParam EXECANDWAIT(cRunExe) После старта модуля на МиниГуи терминалка висит и сообщение Программа (не отвечает) ! Как это убрать ? Может можно как то повесить показ таймера через каждую секунду или две ? Пробовал сделать как в Пост N: 3833 http://clipper.borda.ru/?1-4-0-00000954-000-0-0-1392306838 Все равно прога висит... Юзер по не знанию может прогу на терминалке крестиком закрыть...

SergKis: Andrey ты запускаешь execandwait, т.е. терминалка должна висеть до завершения минигуи. Определись чего хочешь ? Хочешь, что то делать, делай с idle, пример есть в TEST каталоге, посканируй.

SergKis: Andrey пишет Юзер по не знанию может прогу на терминалке крестиком закрыть... У себя крестик закрываю наглухо (что бы не было желания нажимать). Выход только по меню или кнопкап, т.е. где разрешено.



полная версия страницы