c ++ win32 предотвращает запуск приложения на Windows XP - PullRequest
3 голосов
/ 30 сентября 2011

Я разработал приложение, которое использует API Vista (или выше), и я хотел бы добавить всплывающее сообщение, если приложение обнаружит неподдерживаемую ОС.

Я хотел бы добавить всплывающее сообщение, когда пользователь запускает мое приложение в Windows XP. В настоящее время приложение просто выдает всплывающее окно (messageBox) о том, что некоторые DLL не могут быть загружены.

Я определил версию Windows следующим образом:

 #define _WIN32_WINNT 0x0600

Что мне нужно сделать, чтобы не запускаться на версиях ниже Vista? Нужно ли проверять версию ОС при запуске приложения (и показывать сообщение пользователю)?

Ответы [ 7 ]

3 голосов
/ 30 сентября 2011

Если вы используете API, которые недоступны в XP, вам нужно разделить свое приложение на загрузчик и реальное приложение (или загрузчик и DLL, содержащую настоящее приложение). Скомпилируйте загрузчик с #define _WIN32WINNT 0x0501, чтобы убедиться, что он может работать на XP, и отобразите ваше всплывающее окно.

Проверьте версию с помощью VerifyVersionInfo или GetVersionEx

3 голосов
/ 30 сентября 2011

Чтобы показать всплывающее сообщение, вам нужно запустить исполняемый файл. Это означает, что вам нужно уменьшить версию Windows до самой низкой версии, которую вы намереваетесь «поддерживать» (поддержка здесь означает, что вы сможете запускать ее, и покажите всплывающее окно с сообщением, что она не будет работать). Это потребует от вас отсрочки, если вы дадите ссылку на соответствующие библиотеки DLL, в противном случае они не будут найдены, и вы все равно получите то же сообщение, что и вы.

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

2 голосов
/ 30 сентября 2011

Вы можете написать очень маленькое приложение-оболочку, которое определяет _WIN32_WINNT как 0x0501. Затем эта программа может выполнить проверку ОС и либо отобразить приятный пользовательский интерфейс для вашего пользователя (если это неправильная версия Windows), либо просто спокойно запустить другой исполняемый файл (если это поддерживаемая версия Windows).

В идеале, ваш канал распространения (веб-сайт и т. Д.) Должен проверить, что у пользователя есть поддерживаемая версия windows, прежде чем он сможет загрузить ее.

Если вы используете WiX (или MSI напрямую) для установки своего приложения, вы можете позволить установщику обработать неподдерживаемую проверку ОС.

1 голос
/ 30 сентября 2011

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

Вы можете поместить свое приложение в DLL и создать программу-заглушку, которая выполняет проверку ОС, как Mystical описывает в своем ответе.

Edit:

Кажется, Мистик удалил свой ответ ... Сделайте что-то вроде этого:

OSVERSIONINFO OSversion;

OSversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
::GetVersionEx(&OSversion);

switch(OSversion.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
   if(OSversion.dwMajorVersion >= 6)
   {
      // Yay, load the DLL and call entry point
   }
default:
      // Show unsupported OS message
}

Вы можете вызвать LoadLibrary(), чтобы загрузить библиотеку приложения, а затем вызвать любую точку входа в нее, которую вы определили.

Примечание этот ответ содержит классный список номеров версий ОС.

1 голос
/ 30 сентября 2011

Вы можете определить _WIN32_WINNT для более низкого значения, подходящего для 2000 или XP.Но тогда вам нужно будет использовать явные ссылки только для API Vista.Изменение _WIN32_WINNT также приведет к отсутствию объявлений типов для API только для Vista.Итак, если вы знаете, какие API вам нужны, вы можете оставить _WIN32_WINNT на 0x0600 и использовать явные ссылки для этих API.Очевидно, что вам также потребуется проверка версии, чтобы дать пользователю полезное сообщение.

Лично я бы пошел другим путем, чтобы решить эту проблему.Я бы проверил версию во время установки и заблокировал ее там.Это позволяет вам продолжать работу с _WIN32_WINNT 0x0600 и всеми удобствами, которые предоставляет.

1 голос
/ 30 сентября 2011

Вы не можете ожидать динамического поведения во время выполнения, если вы применяете статическое поведение во время компиляции.Вам нужно определить версию Windows XP, чтобы ваш exe-файл связывался с DLL-библиотеками XP, а затем во время выполнения вам нужно динамически изменить поведение, загрузить DLL-файлы Vista и найти точки входа «вручную».Это, как и следовало ожидать, болезненно и подвержено ошибкам.Удачи.

0 голосов
/ 01 октября 2011

Я не знаю, как это сделать в Visual Studio или других компиляторах, но в IDE Borland / CodeGear / Embarcadero есть опция для установки минимальной поддерживаемой версии ОС в заголовке PE скомпилированного исполняемого файла. Если загрузчик ОС попытается запустить исполняемый файл с несовместимой версией, он не запустит исполняемый файл и отобразит пользователю сообщение об ошибке о несоответствии версий. Проверьте, есть ли у вашего компилятора / IDE аналогичная опция.

В противном случае вы должны динамически загружать нужные API во время выполнения через LoadLibrary() / GetModuleHandle() и GetProcAddress() вместо статической ссылки на них во время компиляции. Затем вы можете выполнить проверку кода своей операционной системы в своем коде, прежде чем использовать новые функции API, которые могут быть недоступны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...