Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

17.01.2017

Google
WWW CITForum.ru
С Новым годом!

Книги: [Классика] [Базы данных] [Internet/WWW] [Сети] [Программирование] [UNIX] [Windows] [Безопасность] [Графика] [Software Engineering] [ERP-системы] [Hardware]
     

Секреты поваров компьютерной кухни или ПК: решение проблем

Касперски К.

Издано: 2003, BHV
Твердый переплет, 560 стр..

Аннотация
Статьи из книги

[Заказать книгу в магазине "Мистраль"]

Способы обнаружения копии уже загруженной программы

(статья была опубликована в журнале "Программист")

В третьем номере журнала "Программист" за 2002 год была опубликована статья Андрея Нефедова "Запрет запуска копии приложения под Windows". Перечисленные в ней способы обнаружения уже запущенной копии программы сводились к одному - созданию какого-либо глобального именного объекта и последующей проверки его наличия. Основной недостаток такого подхода - отсутствие гарантий уникальности глобальных имен. Одно и то же имя могут использовать две различные программы, что приведет к очевидному конфликту - вторая не станет запускаться, если активная первая.

С другой стороны, к запрету на одновременное использование двух копий приложения, следует подходить чрезвычайно осторожно, - не создаст ли это ограничение неудобств для пользователя? По крайней мере, следует предусмотреть возможность совместной работы различных версий одного и того же приложения.

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

Но при ближайшем рассмотрении такой недостаток оборачивается достоинством - пользователь получает возможность одновременной работы с различными версиями одного и того же приложениями, установленными в "свои" каталоги!

Получить список процессов легче всего средствами TOOLHELP32. Для этого сначала необходимо вызовом CreateTollhelp32snapshot снять "слепок" состояния процессоров, а затем передать возращенный ею дескриптор функциям Process32First и Process32Next. Каждый процесс, в свою очередь, ассоциирован с одним или несколькими модулями, список которых можно получить с помощью функций Module32First и Module32Next, предварительно сделав "слепок" состояния владеющего ими процесса вызовом CreateTollhelp32snapshot.

Ниже приведен исходный текст программы, выводящий на экран полные имена файлов, загруженных или исполняющихся в данный момент. Имя же самой программы передается ей в нулевом аргументе командной строки. Программа прекрасно работает как под Windows 9x, так и под Windows NT\2000.

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
  // заголовочный файл библиотеки TOOLHELP32


// функция выводит список модулей, ассоцированных
// с данным процессом
void GetModuleList(DWORD th32ProcessID)
{
  HANDLE h;
  MODULEENTRY32 mdl;

  // создание "слепка" состояния всех
  // модулей процесса th32ProcessID
  h=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
          th32ProcessID);

  // для инициализации структуры MODULEENTRY32
  // необходимо указать ее размер
  mdl.dwSize=sizeof(MODULEENTRY32);

  // получение сведений о первом модуле в списке
  Module32First(h,&mdl);

  while(1)
  {
    // в поле szExePath содержится полное имя
    // файла-модуля
    printf("\tszExePath\t-\t%s\n",mdl.szExePath);

    // получение сведений о всех остальных модулях
    // или выход, если конец
    if (!Module32Next(h,&mdl)) break;
  }

  // уничтожение "слепка"
  CloseHandle(h);
}


main()
{
  HANDLE h;
  PROCESSENTRY32 pe;

  // создание "слепка" состояния всех процессов
  // второй аргумент при "слепке" состояния процессов
  // игнорируется и может принимать какие угодно
  // значения
  h=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);

  // для инициализации структуры PROCESSENTRY32
  // необходимо указать ее размер
  pe.dwSize=sizeof(PROCESSENTRY32);

  // получение сведений о первом процессе в списке
  Process32First(h,&pe);

  while(1)
  {
    // в поле szExePath содержится имя исполняемого
    // файла, ассоциированного с процессом, без пути
    printf("szExeFile\t-\t%s\n",pe.szExeFile);

    // в поле th32ProcessID содержится идентификатор
    // процесса, с помощью которого можно получить 
    // список модулей данного процесса.
    // Это необходимо для выяснения полного имени 
    // исполняемого файла
    GetModuleList(pe.th32ProcessID);

    // получение сведений о следующем процессе
    // или выход, если конец
    if (!Process32Next(h,&pe)) break;
  }
  return 0;
}

Листинг 8 Демонстрация отслеживания уже запущенной копии программы путем просмотра списка процессов средствами TOOLHELP

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

Демонстрационный пример реализации приведен ниже.


#include <stdio.h>
#include <windows.h>
#include <winbase.h>

main()
{
  char buff[2];
  HANDLE h;

  // Создание временного файла
  h=CreateFile("my",GENERIC_WRITE,
    NULL,NULL,CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL 
    | FILE_FLAG_DELETE_ON_CLOSE,
    NULL);

  // если открытие прошло успешно – нормальная работа
  if (h!=INVALID_HANDLE_VALUE)
    printf("Hello, Sailor!\n");
    else
  // если возникла ошибка совместного доступа,
  // следовательно, приложение уже было запущено
  if (GetLastError()==ERROR_SHARING_VIOLATION)
  {
    printf("Нельзя запускать более"
           "одной копии приложения!\n");
    return;
  }

  // ожидание нажатие на <enter>
  fgets(&buff[0],2,stdin);
}

Листинг 9 Демонстрация отслеживания уже запущенной копии программы путем блокирования совместного доступа к дисковому файлу

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

Выяснить это поможет широковещательная рассылка сообщений. Передав функции SendMessage в качестве первого аргумента константу HWND_BROADCAST, можно заставить ее посылать сообщения всем top-level окнам. В сообщении следует указать уникальный код, позволяющий безошибочно идентифицировать данное приложение (см. врезку "пути достижения уникальности").

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

Готовая реализация по причине экономии места здесь не приводится (как и все оконные Windows-приложения она слишком громоздка). Достаточно лишь отметить, что перед посылкой широковещательного сообщения, необходимо предварительно зарегистрировать это сообщение вызовом RegisterWindowMessage. Сам же отправитель широковещательного сообщения не получает.

Если требуется ограничить количество одновременно работающих копий одного и того же приложения, можно воспользоваться динамической ветвью реестра HKEY_DYN_DATA, создав в "своем" разделе специальную переменную увеличивающуюся на единицу при очередном запуске и уменьшающуюся при выходе из приложения. Почему необходимо использовать именно динамическую ветвь? Дело в том, что если работа программы будет аварийно завершена (например, погаснет свет или произойдет критическая ошибка), счетчик запущенных приложений, расположенный в статичной ветке реестра, окажется не обнулен! Напротив, HLEY_DUN_DATA хранится в оперативной памяти и очищается при каждой перезагрузке операционной системы. По этой же причине, никогда не следует хранить счетчик запущенных приложений во временном файле! (Разве, на виртуальном диске)

Способов обнаружения ранее запушенных копий программ существует очень много - всех не перечислишь! Поэтому, не следует "зацикливаться" на одном FindWindow – подходите к решению каждой задачи творчески. Экспериментируйте, ищите собственные методы! Уверяю, они есть. На последок еще один довольно неожиданный способ, основанный на буфере обмена.

Если приложение регистрирует свой собственный формат данных (как часто и бывает), передавая его название функции RegisterClipboardFormat, это может служить отличным индикатором наличия уже запущенной копии приложения!

Причем, после выхода из приложения зарегистрированный формат не удаляется и не существует функций API, удаляющих его "в ручную". Это обстоятельство можно использовать для создания программ, рассчитанных всего лишь на один запуск на каждый сеанс работы с Windows. Использование динамической ветви реестра дает не худший результат за одним небольшим исключением - манипуляции с реестром элементарно отслеживают даже неопытные пользователи, вооруженные мониторами реестра, и при желании они смогут легко заставить приложение запуститься повторно, удалив из реестра соответствующую запись.

Замечание: кстати, ограничение "однократный запуск на весь сеанс работы с Windows" очень хорошо подходит для Shareware-программ. Такая защита чрезвычайно проста в реализации и, в то же время, не может быть обманута рядовым пользователем. Конечно, профессиональных взломщиков она не остановит, но в большинстве случаев этого и не требуется!

Пути достижения уникальности: прежде чем использовать способы, предложенные Нефедовым в его статье, необходимо научиться формировать уникальные имена, гарантированно не используемые никакими другими приложениями.

Первое, что приходит на ум, - преобразовывать полное имя запускаемого файла к строке символов, не содержащей недопустимых в глобальных именах знаков обратной наклонной черты и двоеточия. Например, можно заменить их символом прочерка. Полученное имя гарантированно не станет конфликтовать ни с какими другими приложениями, но, однако, не сможет распознать переименование или перенос запускаемого файла приложения.

Второй способ заключается в использовании генератора случайных чисел, с помощью которого формируется уникальное имя до компиляции приложения. В среду разработки Microsoft Visual Studio входит удобная и компактная утилита UUIDGEN, генерирующая 128 битный уникальный идентификатор. Вообще-то она предназначается для создания неконфликтных идентификаторов интерфейсов OLE и ActiveX объектов, но ничуть не хуже подходит и для нашего случая.

Аннотация
Статьи из книги

[Заказать книгу в магазине "Мистраль"]

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

24 декабря

CITKIT.ru:

  • Новогодние поздравления
  • Сергей Кузнецов. Цикл Операционные системы: Ностальгия по будущему:

  • Алексей Федорчук. OpenSolaris 2008.11 Release

  • Сергей Голубев:

  • Евгений Чайкин aka StraNNik (Блогометки):

    17 декабря

  • С.Д.Кузнецов. Базы данных. Вводный курс

    10 декабря

    CITKIT.ru:

  • OpenSolaris 2008.11 Release

  • Альтернативные ОС: две грустные истории (С.Кузнецов)
  • Nokia N810 — доведение до ума
  • CitCity:

  • Платформа 2009: заоблачные перспективы Microsoft

    4 декабря

  • Лекция С.Д.Кузнецова Понятие модели данных. Обзор разновидностей моделей данных

    CITKIT.ru:

  • OpenSolaris 2008.11 Release. Первые впечатления

  • Linux vs FreeBSD: продолжим "Священные войны"?

  • Nokia N810 as is

  • Индульгенция для FOSS

  • Друзья СПО'2008

    26 ноября

  • Нечеткое сравнение коллекций: семантический и алгоритмический аспекты

    CitCity:

    CITKIT.ru:

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • 19 ноября

  • Проблемы экономики производства крупных программных продуктов

  • Язык модификации данных формата XML функциональными методами

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Заметки к книге:

  • FreeBSD: монтирование сменных устройств и механизм HAL
  • Текстовый редактор ee

    12 ноября

  • Правило пяти минут двадцать лет спустя, и как флэш-память изменяет правила (Гоц Грейф, перевод: Сергей Кузнецов)

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:
  • OSS в России: взгляд правоведа (В.Житомирский)

  • Новая статья из цикла С.Голубева "Железный марш":

    29 октября

  • О некоторых задачах обратной инженерии

  • Веб-сервисы и Ruby

  • Тестирование web-приложений с помощью Ruby

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

  • PuppyRus Linux - беседа с разработчиком (С.Голубев)

  • Сергей Кузнецов. Заметка не про Linux

    22 октября

  • Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки

    CITKIT.ru:

  • Сергей Кузнецов. Почему я равнодушен к Linux

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • Что надо иметь
    3. Базовые познания

    CitCity:

  • Управление IT-инфраструктурой на основе продуктов Microsoft

    15 октября

  • Методы бикластеризации для анализа интернет-данных

    CitCity:

  • Разъемы на ноутбуках: что они дают и зачем их так много?
  • AMD Puma и Intel Centrino 2: кто лучше?

    CITKIT.ru:

  • Новый цикл статей С.Голубева
    Железный марш:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    8 октября

  • Автоматизация тестирования web-приложений, основанных на скриптовых языках
  • Опыт применения технологии Azov для тестирования библиотеки Qt3

    Обзоры журнала Computer:

  • SOA с гарантией качества
  • Пикоджоуль ватт бережет
  • ICT и всемирное развитие

    CitCity:

  • Пиррова победа корпорации Microsoft

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Статья из архива:

  • Я живу в FreeBSD (Вадим Колонцов)

    Новые Блогометки:

  • Перекройка шаблона Blogger или N шагов к настоящему
  • Blogger. Comment style
  • Screenie или глянцевый снимок экрана

    2 октября

    CITKIT.ru:

  • Сага о FreeBSD (А. Федорчук)

    Zenwalk: пакет недели

  • Банинг — интеллектуальное развлечение (С.Голубев)

    CitCity:

    25 сентября

  • Клермонтский отчет об исследованиях в области баз данных

    CITKIT.ru:

  • Пользователям просьба не беспокоиться... (В.Попов)

  • Снова про ZFS: диск хорошо, а два лучше
  • Командная оболочка tcsh (А.Федорчук)

    Zenwalk: пакет недели

    17 сентября

  • T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов
  • Технология Azov автоматизации массового создания тестов работоспособности

    CITKIT.ru:

  • FreeBSD: ZFS vs UFS, и обе-две — против всех (А.Федорчук)

    Zenwalk: пакет недели

  • Дачнет — практика без теории (С.Голубев)

    10 сентября

  • За чем следить и чем управлять при работе приложений с Oracle
  • Планировщик заданий в Oracle
    (В.Пржиялковский)

    CITKIT.ru:

  • Microsoft: ответный "боян" (С.Голубев)

  • Причуды симбиоза, или снова "сделай сам" (В.Попов)

  • Файловые системы современного Linux'а: последнее тестирование
  • Zsh. Введение и обзор возможностей
    (А.Федорчук)

    Описания пакетов Zenwalk: Zsh, Thunar, Thunar-bulk-rename, Xfce4-places-plugin, Xfce4-fsguard-plugin

    Блогометки:

  • Google Chrome
  • Лончер для ASUS Eee PC 701

    3 сентября

    CITKIT.ru:

  • Заметки о ядре (А.Федорчук):

    Добавлены описания пакетов Zenwalk: Galculator, Screenshot, Gnumeric, Pidgin

    В дискуссинном клубе:

  • И еще о Википедии и Google Knol

  • Лекция для начинающего линуксоида (С.Голубев)

    26 августа

  • Транзакционная память (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Открыт новый проект Zenwalk: пакет недели

  • Статья Текстовые процессоры и их быстродействие: конец еще одной легенды?

    21 августа

    CITKIT.ru:

  • Почему школам следует использовать только свободные программы (Ричард Столлман)
  • Беседа Сергея Голубева с учителем В.В.Михайловым

  • Википедия или Гуглезнание? Приглашение к обсуждению (Алексей Федорчук)
  • Народная энциклопедия от Google (StraNNik)

  • Обзор Mandriva 2009.0 Beta 1 Thornicrofti
  • Новичок в Линукс: Оптимизируем Mandriva 2008.1

  • Книга Zenwalk. Приобщение к Linux:

    13 августа

    CitCity:

  • Мирный Atom на службе человеку. Обзор платы Intel D945GCLF с интегрированным процессором
  • Обзор процессоров Intel Atom 230 на ядре Diamondville

  • iPhone - год спустя. Скоро и в России?

    CITKIT.ru:

  • Интермедия 3.4. GRUB: установка и настройка (из книги Zenwalk. Приобщение к Linux)

    6 августа

  • СУБД с хранением данных по столбцами и по строкам: насколько они отличаются в действительности? (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Интермедия 2.2. Что неплохо знать для начала (из книги Zenwalk. Приобщение к Linux)

  • И снова про шрифты в Иксах (А.Федорчук)

  • 20 самых быстрых и простых оконных менеджеров для Linux

  • Дело о трех миллиардах (С.Голубев)

    30 июля

  • OLTP в Зазеркалье (Пересказ: С. Кузнецов)

    CitCity:

  • Будущее BI в облаках?
  • Тиражные приложения и заказная разработка. Преимущества для заказчика
  • Дискуссия со сторонниками заказной разработки

    CITKIT.ru:

  • Новые главы книги Zenwalk. Приобщение к Linux:
  • Глава 8. Пакеты: средства установки, системы управления, системы построения
  • Глава 9. Zenwalk: репозитории, пакеты, методы установки

    23 июля

    CITKIT.ru:

  • Все против всех. 64 vs 32, Intel vs AMD, tmpfs vs ext3
  • Две головы от Intel

  • Zenwalk: обзор штатных приложений (глава из книги "Zenwalk. Приобщение к Linux")

  • Нормально, Григорий...

    16 июля

    Обзоры журнала Computer:

  • Перспективы и проблемы программной инженерии в XXI веке
  • Большие хлопоты с большими объемами данных
  • Перспективы наноэлектроники

    CITKIT.ru:

  • Интермедия о лицензиях (А.Федорчук. "Zenwalk. Приобщение к Linux")

  • Есть ли будущее у KDE?

  • Linux в школе: альтернативный вариант в задачах

  • Шифр (приключения агента Никодима)

    10 июля

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия вступительная. Linux или GNU/Linux? Как вас теперь называть?
  • Глава 5. Среда Xfce
  • Глава 6. Xfce: приложения и плагины

  • ZUR (Zenwalk User Repository) FAQ

    2 июля

  • Персистентность данных в объектно-ориентированных приложениях (С. Кузнецов)

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия 1.2. Дорога к Zenwalk'у. Период бури и натиска
  • Интермедия 3.3. Немного о Linux'е и "железе"
  • Глава 4. Настройка: инструментами и руками
  • Интермедия 4.1. Zenpanel и конфиги: поиски корреляции

  • Интервью с Жан-Филиппом Гийоменом, создателем дистрибутива Zenwalk

  • Linux в школе: первые итоги (С. Голубев)

    25 июня

    CITKIT.ru:

  • Zenwalk. Приобщение к Linux (А. Федорчук)

  • Логика и риторика (С.Голубев)

  • Технология Tru64 AdvFS

  • Ханс Райзер предлагает отвести полицейских к телу Нины

    18 июня

  • Проекты по управлению данными в Google (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • ОС и поддержка "железа": мифы и реальность (А. Федорчук)

  • Linux в школе: другие дистрибутивы

  • Пинок (С. Голубев)

    4 июня

  • Ландшафт области управления данными: аналитический обзор (С. Кузнецов)

    CITKIT.ru:

  • Linux в школе: слово заинтересованным лицам

  • SlackBuild: пакеты своими руками

  • Linux от компании Novell. Установка и обзор openSUSE Linux

    Все публикации >>>




  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 This Web server launched on February 24, 1997
    Copyright © 1997-2017 CIT, © 2001-2017 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...