Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

Создаваемые через ProgID COM-объекты, обычно являются Proxy-компонентами. Реально они не содержат никакой функциональности, но имеют доступ к приложению и его внутренним, не доступным извне, функциям. Хотя можно организовать все таким образом, чтобы всегда создавался только один COM-объект, а все остальные вызовы на создание возвращали указатели на него.

Метод интерфейса CCmdTarget GetIDispatch, позволяет получить указатель на реализованный интерфейс IDispatch. В параметрах можно указать, нужно ли увеличивать счетчик ссылок или нет.

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

ВОПРОС-ОТВЕТ 

Q. Как сделать так, чтобы программа сама себя могла стереть, т.е. свой *.exe файл?

LowFeaR 

A1 Удалить программу в тот момент, когда она запущена, не представляется возможным (во всяком случае такая возможность мне не знакома), остается удаление после завершения ее выполнения. Идея следующая: при выходе из программы создать BAT-файл, который ждет до тех пор, пока файл можно будет удалить (программа завершит работу), удаляет файл программы и себя, и запустить его:

void MyDlg::OnDestroy {

 CDialog::OnDestroy;

 const char *AppName=AfxGetApp->m_pszExeName;

 FILE *f=fopen("selfdel.bat","w+");

 fprintf(f, ":dc\n"

"del %s.exe\n"

"if exist %s.exe goto dc\n"

"del selfdel.bat", AppName, AppName);

 fclose(f);

 WinExec("selfdel.bat",FALSE);

}

Преимущества:

– файл удаляется сразу в тот момент, когда это становится возможно

Недостатки:

– если запустить два экземпляра приложения, то после завершения работы первого мы получаем цикл активного ожидания до тех пор пока не завершится второй экземпляр (это незаметно в W95/98, но в NT в окне Task Manager можно заметить полную загрузку процессора). Также пользователь все это время будет удивляться наличию невесть откуда взявшегося файла sefdel.bat. 

Майкрософт же предлагает свой способ решения проблемы, причем его реализация отличается для WinNT и Win95/98. Удаление (переименование, замещение, и т.д.) файла происходит во время следующей перезагрузки системы. 

Win95/98: В процессе перезагрузки системы запускается утилита wininit.exe, которая осуществляет заданные действия над файлами, указанные в секции [rename] файла wininit.ini. При этом т.к. wininit.exe запускается еще до того как запущена система поддержки длинных имен файлов, все имена должны быть указаны в формате DOS (8.3). 

Последовательность действий для удаления или переименования файла:

1. Проверить наличие файла WININIT.INI в директории Windows

2. Если WININIT.INI существует, открываем его и добавляем новые строки в секцию [rename]. Если файла нет, создаем его и секцию [rename] в нем. 3.Добавляем строки следующего формата в секцию [rename]:

DestinationFileName=SourceFileName

Оба пути DestinationFileName и SourceFileName не должны содержать длинных имен. Приемник и источник должны находится на одном диске. Для удаления файла вместо DestinationFileName использовать NUL.

WinNT:

Здесь все сделано по-человечески. Для удаления файла следует использовать функцию MoveFileEx:

MoveFileEx(szSrcFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

где szSrcFile – имя файла или директории

Преимущества:

– "Лицензированный" метод Майкрософт

Недостатки:

– Чрезмерно утяжеленная процедура редактирования wininit.ini, проблемы при работе с длинными именами Win95/98,

– Удаление происходит только в момент перезагрузки.

Bad Sector 

A2 Программа не может удалить свой exe-файл, пока она работает. Это фундаментальное правило при работе под Windows. Поэтому всё, что остаётся – это поручить удаление другому процессу перед тем как завершить свой. 

Самый простой вариант – создать на лету и запустить bat-файл, который дождётся завершения нашего процесса, а затем удалит его exe-файл. Более сложные варианты подразумевают создание в чужом процессе (например, в Task Manager) рабочего потока, который опять же дождётся завершения нашего процесса и убьёт файл. 

Вот пример функции, которая создаёт bat-файл и запускает его, чтобы убить наш exe-файл. Лучше всего вызывать её непосредственно перед завершением нашего процесса. 

void DelSelf {

 // Получаем свой путь

 char szExePath[MAX_PATH];

 GetModuleFileName(NULL, szExePath, MAX_PATH);

 // Создаём bat-файл

 static char szBat[] = ":Loop\r\n"

"del %1\r\n"

"if exist %1 goto Loop\r\n"

"del %0";

 HANDLE hFile = CreateFile("__delself.bat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);

 DWORD temp;

 WriteFile(hFile, (LPVOID)szBat, strlen(szBat), &temp, NULL);

 CloseHandle(hFile);

 // Запускаем его

 STARTUPINFO si;

 ZeroMemory(&si, sizeof(si));

 si.cb = sizeof(si);

 si.wShowWindow = SW_HIDE;

 si.dwFlags = STARTF_USESHOWWINDOW;

 PROCESS_INFORMATION pi;

 char szCommand[MAX_PATH+15] = "__delself.bat ";

 strcat(szCommand, szExePath);

 CreateProcess(NULL, szCommand, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi);

 return;

}

 Замечу, что это только пример, который можно улучшать в различных направлениях. Можно, скажем, получать имя bat-файла через GetTempFileName, чтобы гарантировать его уникальность. Или понизить приоритет создаваемого из bat-файла процесса до минимума, чтобы он кушал поменьше ресурсов в процессе циклической проверки существования exe-файла.

Александр Шаргин (rudankort@mail.ru) 
В ПОИСКАХ ИСТИНЫ 

Q. Есть у меня файлы с расширением .pdb (Microsoft C/C++ program database 2.00) (их MS VC++ делает, в папке Debug проекта создаются), можно ли с их помощью восстановить исходники программы (размер у них такой, что туда не только прога влезет, но и комментарии к ней в HTML (FrontPage Style) формате :)

 Andrey Shtukaturov 

Пока все. До скорого! 

Алекс Jenter jenter@mail.ru Красноярск, 2001.

Программирование на Visual C++

Выпуск №33 от 18 февраля 2001 г.

Приветствую!

Сегодня хочу предложить вашему вниманию заключительную часть статьи про ODBC нашего постоянного автора Александра Шаргина, которая, если вы помните, открывает цикл статей о технологиях доступа к данным.

СТАТЬЯ

Доступ к БД с использованием ODBC

Часть 2

Автор: Александр Шаргин 

В предыдущей части статьи мы с вами рассмотрели основы использования ODBC для доступа к базам данных. Но в процессе знакомства с этой технологией у каждого естественным образом возникает целый ряд вопросов. Ответам на самые распространённые из них и будет посвящена вторая часть статьи. 

Перемещение на другие компьютеры

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

Необходимые компоненты

Сразу замечу, что некоторые приложения изначально разрабатываются для работы с произвольными БД. К таким приложениям относятся пакеты статистической обработки данных или электронные таблицы, способные импортировать данные из выбранной пользователем БД. Другой характерный пример – среда Visual C++. Если вы разрабатываете подобное приложение, можете смело пропустить этот раздел. Установка компонентов, необходимых для работы с конкретной базой данных – не ваша забота. Любому приложения, использующему ODBC, необходимы основные компоненты ODBC (core components) и ODBC-драйвер. К основным компонентам относятся менеджер драйверов (ODBC32.DLL), библиотека инсталлятора (ODBCCP32.DLL), библиотека курсоров (ODBCCR32.DLL) и администратор источников данных (ODBCAD32.EXE), а также несколько вспомогательных файлов. Драйвер состоит из двух DLL: библиотеки драйвера (driver DLL) и библиотеки настройки (setup DLL). Библиотека драйвера экспортирует все необходимые функции ODBC API, а библиотека настройки – функции ConfigDriver и ConfigDSN, используемые для конфигурирования самого драйвера и связанных с ним источников данных. Иногда обе библиотеки объединяют в одной DLL. Основные компоненты сейчас установлены практически на каждом компьютере, поэтому об их инсталляции я рассказывать не буду. Тем, кого интересует этот вопрос, советую обратиться к описанию функции SQLInstallDriverManager. Драйвер для каждой конкретной СУБД обычно распространяется со своей программой инсталляции. В этом случае вам нужно просто включить её в комплект поставки. Но предположим, что такая программа недоступна. Тогда можно воспользоваться функцией SQLInstallDriverEx, входящей в библиотеку инсталляции. Эта функция вызывается дважды: первый раз, чтобы определить целевую папку для драйвера, а второй раз, чтобы добавить необходимые записи в реестр. Копирование осуществляет вызывающая программа. Предположим, что драйвер "My Driver" состоит из файлов MYDRV.DLL и MYSETUP.DLL. Установку этого драйвера выполнит следующий код. 

#include <windows.h>

#include <odbcinst.h>

#include <stdio.h> :

char szPathIn[301];

char szPathOut[301];

DWORD dwUsageCount;

int i, j;

char szDriver[300] = "My Driver\0Driver=MYDRV.DLL\0Setup=MYSETUP.DLL\0";

SQLInstallDriverEx(szDriver, NULL, szPathIn, 300, NULL, ODBC_INSTALL_INQUIRY, &dwUsageCount);

  • Читать дальше
  • 1
  • ...
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: