Автор | Сообщение |
|
| постоянный участник
|
Пост N: 2121
Зарегистрирован: 12.09.06
|
|
Отправлено: 21.03.12 13:20. Заголовок: Как предотвратить второй запуск программы в МиниГуи ?
Делаю программу на МиниГуи, типа меню запуска других программ. Хочу вызывать свои доп. ЕХЕ-ники (терминалки на хХарборе) из главного меню программы на МиниГуи. Вызовом ShellExecute(). Как сделать, чтоб повторно нельзя было запускать уже запущенную программу ? Я пока знаю 2 варианте: 1) Можно было бы писать файл-семафора что запущена программа, а при завершении терминалки удалять этот файл. Но это как-то не солидно... И при случайном сбое, нельзя будет запустить программу. 2) Поискать в памяти запущенный процесс (окно с именем). Но это ТОРМОЗА - я уже наталкивался на эти грабли. По России уже наблюдал 3 случая "тормозов" при проверке повторного запуска программы (я писал об этом в другой ветке, здесь на форуме). Какие еще варианты можно использовать ?
|
|
|
Ответов - 27
, стр:
1
2
All
[только новые]
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 21.03.12 13:56. Заголовок: Как предотвратить второй запуск программы
Вариант с монопольно открытым файлом - достаточно прост и надежен. При запуске - создаете в рабочей папке, где запускаете приложение - дополнительный файл -вроде [имя exe].run Каждая следующая попытка запуска приложения "имя exe" предварительно проверяет - отсутствие файла [имя exe].run или возможность его удаления. Если файл есть и его не удалось удалить - нельзя делать запуск.
|
|
|
|
| постоянный участник
|
Пост N: 2123
Зарегистрирован: 12.09.06
|
|
Отправлено: 21.03.12 14:14. Заголовок: petr707 пишет: Если..
petr707 пишет: цитата: | Если файл есть и его не удалось удалить - нельзя делать запуск. |
| Это не факт. Натыкался на случаи (и не раз) сбоя на ХР, при вылете программы по ошибке, файл-семафора остается блокированным и запустить заново терминалку НЕЛЬЗЯ ! Помогает только перезагрузка компа ! ! ! Но это же не дело...
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 21.03.12 14:37. Заголовок: Натыкался на случаи...
На практике - непонятую (непонятную) блокировку файла наблюдал только на компах, где установлен Google Desktop или работает Window Search на NTFS, который проводит индексацию файлов в фоновом режиме. При конфигурации(инсталляции) прикладного ПО - снимите в свойствах папки, где exe, "Индексировать папку для быстрого поиска"
|
|
|
|
| |
Пост N: 115
Зарегистрирован: 17.06.10
|
|
Отправлено: 21.03.12 16:36. Заголовок: можно через FindWind..
можно через FindWindow(), можно чнрез TaskBar
|
|
|
|
| постоянный участник
|
Пост N: 2124
Зарегистрирован: 12.09.06
|
|
Отправлено: 21.03.12 18:15. Заголовок: petr707 пишет: При ..
petr707 пишет: цитата: | При конфигурации(инсталляции) прикладного ПО - снимите в свойствах папки, где exe, "Индексировать папку для быстрого поиска" |
| Не подключены компы к Инету. И службу индексации - всегда выключаю. Все равно эпизодически были такие ошибки. fil пишет: цитата: | можно через FindWindow(), можно чнрез TaskBar |
| А чуть подробней можно ? Как код будет выглядеть ?
|
|
|
|
| |
Пост N: 116
Зарегистрирован: 17.06.10
|
|
Отправлено: 21.03.12 18:34. Заголовок: FindWindow(Заголовок..
FindWindow(Заголовок главного окна приложения) - на форуме мелькало. Если нет в Минигуи, API прицепи TaskBar - Наверняка в Минигуи есть возможность получить список задач
|
|
|
|
| постоянный участник
|
Пост N: 752
Зарегистрирован: 27.01.07
|
|
Отправлено: 21.03.12 20:42. Заголовок: Существует механизм ..
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 21.03.12 22:55. Заголовок: А что такое - "повторный" ?
Мьютекс отработает при запуске из одной операционной среды - локальный комп или терминал-сервер. При выполнении задачи в одной сетевой папке - но с разных компов, с мьютексом не получится, isn'it ? Неплохо бы уточнить, что такое "повторный запуск". Миллионы( а может и больше) юзеров "повторно" запускают IE ( не реклама)
|
|
|
|
| постоянный участник
|
Пост N: 2125
Зарегистрирован: 12.09.06
|
|
Отправлено: 22.03.12 00:49. Заголовок: petr707 пишет: Непл..
petr707 пишет: цитата: | Неплохо бы уточнить, что такое "повторный запуск". |
| Подразумевалось локальный комп (папка программы) или терминал-сервер.
|
|
|
|
| постоянный участник
|
Пост N: 2126
Зарегистрирован: 12.09.06
|
|
Отправлено: 22.03.12 00:51. Заголовок: PSP пишет: Существу..
PSP пишет: А примеры есть ? Кто нибудь работал с этим на Харборе ?
|
|
|
|
| постоянный участник
|
Пост N: 83
Зарегистрирован: 29.05.10
|
|
Отправлено: 22.03.12 08:57. Заголовок: Andrey пишет: А при..
Andrey пишет: цитата: | А примеры есть ? Кто нибудь работал с этим на Харборе ? |
| Ну например можно сделать что-то типа : if IsExeRunning( cFileName( "mors" ) ) MsgStop( "Программа уже работает ! ", "Внимание ..." ) return( NIL ) endif Вместо возврата можно активировать окно. А сама IsExeRunning может быть , к примеру ,такой- #ifdef __FLAT__ HB_FUNC( ISEXERUNNING ) // ( cExeNameCaseSensitive ) --> lResult { HANDLE hMutex = CreateMutex( NULL, TRUE, ( LPTSTR ) hb_parc( 1 ) ); hb_retl( GetLastError() == ERROR_ALREADY_EXISTS ); ReleaseMutex( hMutex ); } #endif Это FWH :)
|
|
|
|
|
| moderator
|
Пост N: 354
Зарегистрирован: 11.02.10
|
|
Отправлено: 22.03.12 11:26. Заголовок: ММК пишет: Ну напри..
ММК пишет: цитата: | Ну например можно сделать что-то типа ... Вместо возврата можно активировать окно. |
| Andrey Посмотри штатный пример из поставки Минигуи: цитата: | /* * MINIGUI - Harbour Win32 GUI library Demo * * Copyright 2002-05 Roberto Lopez <harbourminigui@gmail.com> * http://harbourminigui.googlepages.com/ * * Copyright 2006 Grigory Filatov <gfilatov@inbox.ru> */ #include "minigui.ch" #define APP_TITLE 'Main Window' #define MsgAlert( c ) MsgEXCLAMATION( c, "Warning", , .f. ) FUNCTION Main() Local hWnd IF IsExeRunning( cFileNoPath( HB_ArgV( 0 ) ) ) MsgAlert( "The " + APP_TITLE + " is already running!" ) hWnd := FindWindow( APP_TITLE ) IF hWnd > 0 IF IsIconic( hWnd ) Restore( hWnd ) ELSE SetForeGroundWindow( hWnd ) ENDIF ELSE MsgStop( "Cannot find application window!", "Error", , .f. ) ENDIF ELSE DEFINE WINDOW Form_Main ; AT 0,0 ; WIDTH 640 HEIGHT 480 ; TITLE APP_TITLE ; MAIN END WINDOW CENTER WINDOW Form_Main ACTIVATE WINDOW Form_Main ENDIF RETURN NIL #pragma BEGINDUMP #define HB_OS_WIN_USED #define _WIN32_WINNT 0x0400 #include <windows.h> #include "hbapi.h" #include "hbapiitm.h" HB_FUNC( ISICONIC ) { hb_retl( IsIconic( ( HWND ) hb_parnl( 1 ) ) ); } HB_FUNC ( FINDWINDOW ) { hb_retnl( ( LONG ) FindWindow( 0, hb_parc( 1 ) ) ); } #pragma ENDDUMP |
| У меня работает нормально
|
|
|
|
| постоянный участник
|
Пост N: 11
Зарегистрирован: 17.02.12
|
|
Отправлено: 22.03.12 16:09. Заголовок: Andrey пишет: Делаю ..
Andrey пишет: цитата: | Делаю программу на МиниГуи, типа меню запуска других программ. Хочу вызывать свои доп. ЕХЕ-ники (терминалки на хХарборе) из главного меню программы на МиниГуи. |
| Вот и у тебя появилось много ЕХЕ-ников, а значит и окон. Значит перед тобой встанет задача управлять ими (из терминалки на хХарборе воздействовать на программу МиниГуи и наоборот, переключать фокус окон и т.д. и т.п.). Меня выручил AutoIt3 скриптовый язык (можно получать ЕХЕ). В нем много отлаженных функций по управлению поведением окон, нажатию на пункты меню, кнопки и др. полезных штук. Прост в использовании. Есть русский help. Это не реклама. Сам наступал на такие грабли. Если интересно могу кинуть русский help для начала.
|
|
|
|
| постоянный участник
|
Пост N: 2129
Зарегистрирован: 12.09.06
|
|
Отправлено: 22.03.12 17:41. Заголовок: gfilatov2002 пишет: ..
gfilatov2002 пишет: цитата: | Посмотри штатный пример из поставки Минигуи: |
| Да он и у меня работает нормально. Вопрос в другом - как сделать в программе на МиниГуи что бы внешняя программа (терминалка на хХарборе) запускалась ТОЛЬКО ОДИН раз ?
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 22.03.12 19:23. Заголовок: как сделать..
То есть непонятно, что для каждой запускаемой внешней проги нужно сделать свой мьютекс и потом проверять его присутствие? Функция ISEXERUNNING позволяет задавать параметр [имя мьютекса=имя проги(внешний exe) + еще что угодно] и использовать эту функцию не только для проверки повторного запуска программы на Минигуи, а для проверки запуска других программ, и вообще - для любого события, к которому привяжете и оставите в системе мьютекс. Например , запускает свою прогу , запускаете некий Ваш отчет и если получите результат = 4, то создаете мьютекс с именем - Was_report_4 далее - пока не выключите комп, можете проверять следующий факт - был ли сегодня на этом компе от последнего включения создан отчет с результатом 4 ( а реально - был ли создан мьютекс) (хотя проверку именно такого событие можно и проще реализовать) При обнаружении мьютекса запущенного внешнего exe - не обязательно искать окно приложения и переключать на него фокус, достаточно сообщить юзеру о невозможности повторного запуска внешнего exe
|
|
|
|
| постоянный участник
|
Пост N: 13
Зарегистрирован: 17.02.12
|
|
Отправлено: 22.03.12 19:36. Заголовок: Для Andrey.
Вот примеры на AutoIt: Скрытый текст ; AutoIt3 Примеры: ;--------------------------------------- 1 ; Проверка наличия указанного процесса и запуск если нет #NoTrayIcon If ProcessExists("notepad.exe") Then MsgBox(0, "Привет !", "Notepad is running.") Else Run("Notepad.exe") EndIf ;--------------------------------------- 2 ; Проверка наличия указанного окна по части заголовка и запуск если нет #NoTrayIcon If WinExists("Untitled -") Then MsgBox(0, "Привет !", "Notepad is running.") Else Run("Notepad.exe") EndIf ;--------------------------------------- 3 ; Нажать пункт меню окна notepad #NoTrayIcon If WinExists("Untitled -") Then WinMenuSelectItem("Untitled - ", "", "&File", "Page Set&up..." ) EndIf ;--------------------------------------- 4 ; Активизировать окно, то есть отобразить его на переднем плане экрана #NoTrayIcon If WinExists("Untitled -") Then WinActivate("Untitled - Notepad", "") EndIf ;----------------------------------------- Из программы на МиниГуи запускаешь AutoIt3.exe <имя скрипта>
|
|
|
|
|
| постоянный участник
|
Пост N: 2132
Зарегистрирован: 12.09.06
|
|
Отправлено: 25.03.12 20:41. Заголовок: Спасибо SergKis за п..
Спасибо SergKis за примеры. Но честное слово не хочется связываться с внешними программами. Если я сопровождал бы одну свою систему, то можно было бы. gfilatov2002 пишет: цитата: | Посмотри штатный пример из поставки Минигуи: |
| Посмотрел. Я на базе нкго для хХарбора делал проверку запуска второй копии программы. Здесь на форуме писал об этом. Вопрос по функциям этого примера: 1) Функция cFileNoPath() - понятно что делает, а где описание по ней ? В каком руководстве искать такие функции ? 2) Функция Restore() - аналогично ? 3) Функция SetForeGroundWindow() - аналогично ? 4) FindWindow() - понятно что делает. Может в ней описание из 2-х строчек дать ? 5) IsIconic() - не понял что эта функция делает ?
|
|
|
|
| moderator
|
Пост N: 357
Зарегистрирован: 11.02.10
|
|
Отправлено: 26.03.12 10:02. Заголовок: Andrey пишет: Вопро..
Andrey пишет: цитата: | Вопрос по функциям этого примера |
| 1) главное руководство для программиста - это исходники библиотеки (см. файл h_controlmisc.prg) 2) см. файл c_windows.c 3) Это харбор-переходник для стандартной winapi-функции (см. MSDN) - выводит заданное окно на передний план 4) аналогично п.4 5) аналогично п.4 - эта функция определяет, минимизировано ли заданное окно (см. MSDN снова) Понимаю, что это сложно (все знать ), но недаром этот пример находится в папке Advanced
|
|
|
|
| постоянный участник
|
Пост N: 2133
Зарегистрирован: 12.09.06
|
|
Отправлено: 26.03.12 11:17. Заголовок: gfilatov2002 пишет: ..
gfilatov2002 пишет: цитата: | Понимаю, что это сложно (все знать ), но недаром этот пример находится в папке Advanced |
| Спасибо большое за разъяснения ! Сделай пожалуйста к этому примеру комментарии в этих функциях... Очень было бы полезно и для других тоже. Типа: харбор-переходник для стандартной winapi-функции (см. MSDN) - выводит заданное окно на передний план !
|
|
|
|
| moderator
|
Пост N: 358
Зарегистрирован: 11.02.10
|
|
Отправлено: 26.03.12 11:55. Заголовок: Andrey пишет: Сдела..
Andrey пишет: цитата: | Сделай пожалуйста к этому примеру комментарии в этих функциях |
| По типу такого цитата: | Функция SetForegroundWindow переводит поток, который создал определяемое окно в приоритетный режим и активизирует окно. Ввод с клавиатуры направлен в окно, а различные визуальные ориентиры изменяются для пользователя. Синтаксис BOOL SetForegroundWindow ( HWND hWnd // дескриптор окна, которое переводится в приоритетный режим ); Параметры hWnd Идентифицирует окно, которое должно быть активизировано и переведено в приоритетный режим. Возвращаемые значения Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError. Замечания Приоритетное окно - окно наверху Z-последовательности. Это - окно, с которым пользователь работает. В среде приоритетной многозадачности, Вы должны вообще дать возможность управления пользователю, окно которого является приоритетным окном. Однако прикладная программа может вызывать SetForegroundWindow, если требуется перевести себя в активный режим, чтобы отобразить критическую ошибку или информацию, которая требует непосредственного внимания пользователя. Хороший пример - это отладчик, когда он обнаруживает контрольную точку останова программы. Система назначает немного более высокий приоритет потоку, который создал приоритетное окно, чем она делает это по отношению к другим потокам. |
| Но тогда скоро потребуется повторить весь MSDN
|
|
|
Ответов - 27
, стр:
1
2
All
[только новые]
|
|