В представленном ниже коде в папке для временных файлов при запуске приложения создаётся Lock File , в случае неудачной попытки создания Lock File , программа считает, что уже открыт один экземпляр приложения, сообщает об этом пользователю и закрывается.
Примечание. Замените на ваш идентификатор.
#include «widget.h» #include #include #include #include int main(int argc, char *argv[]) < QApplication a(argc, argv); QLockFile lockFile(QDir::temp().absoluteFilePath(«lurity.lock»)); /* Пытаемся закрыть Lock File, если попытка безуспешна в течение 100 миллисекунд, * значит уже существует Lock File созданный другим процессом. * Следовательно, выбрасываем предупреждение и закрываем программу * */ if (!lockFile.tryLock(100)) < QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText(«Приложение уже запущено.n» «Разрешено запускать только один экземпляр приложения.»); msgBox.exec(); return 1; >Widget w; w.show(); return a.exec(); >
Single application с использованием QSystemSemaphore и QSharedMemory
В первом варианте дано простое и удобное решение задачи по ограничению количества запущенных экземпляров Qt приложения. Но решение на QLockFile имеет и недостатки в том плане, что могут быть проблемы с разрешениями для пользователя. А также, если вы желаете ограничить, запуск программы одним экземпляром на весь компьютер, не различия то, сколько пользовательских сессий может быть запущено на нём, то использование QLockFile также не обеспечит эту возможность.
😱 Как сделать ANDROID приложение за 10 минут! Сможет каждый :3
QSharedMemory же напротив является разделяемой для всех пользователей одновременно, работающих за компьютером. Поэтому, если один из пользователей запустил Вашу программу, то второй уже не сможет её запустить.
Но в данном варианте необходимо не забывать о различиях в работе с разделяемой памятью под различными платформами. В случае с Windows, разделяемая память будет освобождена как при штатном завершении программы, так и при аварийном завершении. В случае же с Linux/Unix при аварийном при аварийном завершении память освобождена не будет.
В ниже представленном коде семафор используется для разрешения проблемы гонок в случае с одновременным запуском нескольких экземпляров одного приложения. Семафор создаётся со счётчиком, максимальное число которого равно 1. При поднятии семафора, все другие экземпляры приложения уже не имеют доступа к разделяемой памяти и соответственно один экземпляр полностью владеет ресурсами. Данный экземпляр проверяет наличие запущенного другого экземпляра приложения по наличию сегмента разделяемой памяти с идентификатором, соответствующим данному приложению. Экземпляр успешно запускается и создаёт сегмент разделяемой памяти в случае, если не нашёл информации о другом экземпляре приложения. После этого семафор опускается, давая возможность другим экземплярам приложения попытаться запуститься.
Примечание. Замените и на ваши идентификатор.
#include «mainwindow.h» #include #include #include #include int main(int argc, char *argv[]) < QApplication a(argc, argv); QSystemSemaphore semaphore(«», 1); // создаём семафор semaphore.acquire(); // Поднимаем семафор, запрещая другим экземплярам работать с разделяемой памятью #ifndef Q_OS_WIN32 // в linux/unix разделяемая память не освобождается при аварийном завершении приложения, // поэтому необходимо избавиться от данного мусора QSharedMemory nix_fix_shared_memory(«»); if (nix_fix_shared_memory.attach()) < nix_fix_shared_memory.detach(); >#endif QSharedMemory sharedMemory(«»); // Создаём экземпляр разделяемой памяти bool is_running; // переменную для проверки ууже запущенного приложения if (sharedMemory.attach()) < // пытаемся присоединить экземпляр разделяемой памяти // к уже существующему сегменту is_running = true; // Если успешно, то определяем, что уже есть запущенный экземпляр >else < sharedMemory.create(1); // В противном случае выделяем 1 байт памяти is_running = false; // И определяем, что других экземпляров не запущено >semaphore.release(); // Опускаем семафор // Если уже запущен один экземпляр приложения, то сообщаем об этом пользователю // и завершаем работу текущего экземпляра приложения if (is_running) < QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText(QObject::trUtf8(«Приложение уже запущено.n» «Вы можете запустить только один экземпляр приложения.»)); msgBox.exec(); return 1; >MainWindow w; w.show(); return a.exec(); >
Видеоурок
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Рекомендуемые статьи по этой тематике
- PyQt5 — Урок 004. Использование QSettings
- Qt WinAPI — Урок 008. Добавление Qt приложения в автозапуск Windows через QSettings
- Qt/C++ — Урок 003. QSettings или Как сохранить настройки приложения?
По статье задано0 вопрос(ов)
Подписка на обсуждение 3
Подписка на раздел 336
Вам это нравится? Поделитесь в социальных сетях!
Источник: evileg.com
Создание и управление процессами и потоками
1. Создайте пустой проект С/С++ в Visual Studio ( Файл – Создать – Проект…) с названием CreateProcess . Выберите расположение проекта (кнопка Обзор…), например, C:Programs:
2. Добавьте в проект файл исходного кода с расширением CPP .
Для этого щелкните правой кнопкой мыши на папке Файлы исходного кода в Обозревателе решений, выберите Добавить, затем Создать элемент…
В открывшемся окне выберите пункт Файл C++ (. cpp ) и введите его название, например, main:
3. Откройте добавленный файл и вставьте в него следующий код (взят с сайта MSDN ):
#include #include #include void _tmain( int argc, TCHAR *argv[] ) < STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( si.cb = sizeof(si); ZeroMemory( // Запуск дочернего процесса if( !CreateProcess( NULL, «notepad.exe», // Имя образа запускаемого процесса NULL, // Дескриптор процесса не наследуется NULL, // Дескриптор потока не наследуется FALSE, // Дескрипторы не наследуются 0, // Флагов создания нет NULL, // Родительский environment block NULL, // Родительский текущий каталог pi ) // Указатель на PROCESS_INFORMATION ) < printf( «CreateProcess failed (%d).n», GetLastError() ); return; >// Ожидаем, пока созданный процесс не завершится WaitForSingleObject( pi.hProcess, INFINITE ); // Закрываем дескрипторы процесса и потока CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); >
Приведенная программа будет запускать другой процесс (в данном случае стандартное приложение Windows «Блокнот») и ждать, пока он не завершится.
4. Установите требуемые свойства проекта.
Для этого выберите конфигурацию Release на панели инструментов:
В конфигурации Release проект будет компилироваться без отладочной информации и с оптимизацией кода.
Затем щелкните правой кнопкой мыши на заголовке проекта в окне Обозреватель решений и выберите пункт Свойства (или щелкните левой кнопкой мыши на заголовке проекта и нажмите Alt+ Enter ):
В свойствах проекта найдите опцию Свойства конфигурации – C/C++ – Создание кода – Библиотека времени выполнения. Выберите параметр Многопоточная (/MT). Если этого не сделать, то приложение при запуске в Windows Server 2003, возможно, будет требовать библиотеку msvcr100.dll (для Visual Studio 2010).
5. Проверьте работоспособность созданного приложения.
Нажмите кнопку на панели инструментов или нажмите F5. При появлении окна с вопросом о выполнении построения проекта выберите Да.
Если все сделано правильно, должно запуститься созданное приложение (консольное окно), а затем приложение «Блокнот».
Закройте «Блокнот» – при этом должно завершиться ваше приложение .
Дальше >>
< Лекция 6|| Самостоятельная работа 2: 1 2 3 4 || Лекция 7 >
Вопросы и ответы
Екатерина Гастева
Добрый день. Не работают ссылки для скачивания на начальном этапе первой самостоятельной работы. Возможно и далее встречаются старые ссылки. Как быть с этим?
Может есть какой-то более новый несложный курс по устройству windows c практическими заданиями? Заранее спасибо.
«1. Скачайте и установите программу виртуализации Microsoft Virtual PC 2007 SP1, доступную по адресу:
» Microsoft Windows Server 2003 SP1 » также не находится.
Источник: intuit.ru
Запуск приложения на хосте по триггеру.
Прошу разжевать очень подробно, как реализовать удаленный запуск приложения по сработке триггера в Zabbix на рабочей станции под управлением Windows.
На рабочей станции запущен Notepad.exe
Zabbix мониторит, чтобы он был запущен
Как только пользователь закрывает блокнот, срабатывает триггер, и Zabbix удаленно запускает блокнот снова.
Если вам не лень, прошу расписать подробно: настройки агента, настройки элемента данных, настройки триггера, и настройки скриптов.
Метки темы
Записи: 837
11.10.2019 21:51
Prominent Member
Присоединился: 10 лет назад
Сомневаюсь, что кто-то захочет подробно все описывать. Пример запуска скрипта на хосте по срабатыванию триггера есть в моей статье — https://serveradmin.ru/zvonok-opoveshhenie-zabbix-cherez-asterisk-na-mobilnyiy-telefon/
1. На хосте настраиваете bat файл на запуск блокнота.
2. На zabbix server настраиваете шаблон для мониторинга работы приложения notepad с триггером.
3. Создаете действие, которое срабатывает по триггеру. В действии указываете запуск bat файла на хосте.
В принципе, ничего сложного. Думаю, если вам реально надо, разберетесь.
Присоединился: 4 года назад
New Member
14.10.2019 15:03
Ответ ради ответа?:)
Спасибо, статью давно прочитал, делал по аналогии, но не заработало. Поэтому спросил здесь в надежде на подробный ответ:)
Создатель темы
14.10.2019 16:45
New Member
Присоединился: 4 года назад
Настройка конфига агента:
EnableRemoteCommands=1
LogRemoteCommands=1
proc.num[notepad.exe]
Триггер равно TestMaschine: notepad.exe
Действие (удаленная команда):
C:1start.bat Содержимое bat файла:
«C:WINDOWSsystem32notepad.exe»
quit
На bat максимальные права, учётка — админ.
Вот, что пишет лог агента:
16792:20191014:163128.073 Executing command ‘C:1start.bat’
То есть, лог говорит «выполнение команды. «. Но по факту, ничего не происходит.
Куда копать?
Это сообщение было изменено 4 года назад от jojoMSK
Присоединился: 10 лет назад
Prominent Member
Записи: 837
14.10.2019 16:53
Zabbix-agent от какого пользователя запущен? Попробуй его запустить от пользователя, под которым ты ожидаешь запуск блокнота. А вообще опиши задачу полностью. Ты же хочешь не блокнот по факту запускать, а что-то другое.
Присоединился: 4 года назад
New Member
14.10.2019 17:10
Есть группа хостов, на которых запущена группа приложений.
Если хотя бы одно из приложений не работает на хосте, то хост не выполняет свою задачу на 100%.
В данный момент Zabbix мониторит сам факт работы приложений. Аллерты настроены, как надо.
При этом одно из приложений периодически выключается. И для того, чтобы приложение работало, нужно подключаться на каждый проблемный хост и запускать приложение вручную.
Хочу, чтобы Zabbix сам запускал проблемное приложение.
P.S.: Агент запущен от пользователя «СИСТЕМА» 😳
Присоединился: 10 лет назад
Prominent Member
Записи: 837
14.10.2019 18:27
Чтобы это нормально работало, надо приложения запускать как службы, если они это умеют. И управлять уже службами. Если это не возможно, то надо тестировать и пробовать различные варианты запуска, чтобы приложения нормально стартовали.
19.11.2019 12:53
Eminent Member
Присоединился: 4 года назад
Вот в чем проблема заббикс выполняет скрипт определенное время (смотри что у тебя в конфе прописано). Если скрипт не закрылся за это время то происходит его прерывание.
В твоем варианте скрипта идет вызов блокнота и он будет работать пока работает процесс консоли (скрипта) таймер проходит и происходит завершение приложения.
Это были причины почему так не работает. Теперь обсудим что сделать что бы работало.
Для начала создадим задачу в планировщике заданий. В нее вносим наш bat файл. Расписание не устанавливаем. Прописывает от имени кого пользователя ее запускать. Все сохраняем переходим к следующему шагу. Идем в заббикс создаем скрипт в поле команда пишем: «SCHTASKS /Run /TN test»
Где test название задачи из планировщика. Советую использовать en раскладку при именовании задачи что бы не издеваться над собой. Т.к заббикс на стороне сервера все вызывает из cmd.
Переходим на карту сети проверяем на узле работу скрипта, радуемся, переделываем действия в заббикс на такую команду и живем хорошо)
Поскольку это планировщик задач выполняет задачу от имени пользователя, а не заббикс то и ограничений по времени нет. Вообще можно на прямую приложение вызывать через планировщик, но это уже у кого какое ТЗ.
И да этот метод работает в проде уже более двух лет.
Источник: serveradmin.ru