Лучший из известных мне подходов - проверить, экспортируется ли конкретный API из некоторой DLL. Каждая новая версия Windows добавляет новые функции, и, проверяя их наличие, можно определить, на какой ОС запущено приложение. Например, Vista экспортирует GetLocaleInfoEx из kernel32.dll, тогда как предыдущие Windowses этого не делали.
Короче говоря, вот один такой список, содержащий только экспорт из kernel32.dll.
> *function: implemented in* > GetLocaleInfoEx: Vista > GetLargePageMinimum: Vista, Server 2003 GetDLLDirectory: Vista, Server 2003, XP SP1 GetNativeSystemInfo: Vista, Server 2003, XP SP1, XP ReplaceFile: Vista, Server 2003, XP SP1, XP, 2000 OpenThread: Vista, Server 2003, XP SP1, XP, 2000, ME GetThreadPriorityBoost: Vista, Server 2003, XP SP1, XP, 2000, NT 4 IsDebuggerPresent: Vista, Server 2003, XP SP1, XP, 2000, ME, NT 4, 98 GetDiskFreeSpaceEx: Vista, Server 2003, XP SP1, XP, 2000, ME, NT 4, 98, 95 OSR2 ConnectNamedPipe: Vista, Server 2003, XP SP1, XP, 2000, NT 4, NT 3 Beep: Vista, Server 2003, XP SP1, XP, 2000, ME, 98, 95 OSR2, 95
Написание функции для определения реальной версии ОС просто; просто перейдите от самой новой ОС к самой старой и используйте GetProcAddress для проверки экспортированных API. Реализация этого на любом языке должна быть тривиальной.
Следующий код в Delphi был извлечен из бесплатной библиотеки DSiWin32 ):
TDSiWindowsVersion = (wvUnknown, wvWin31, wvWin95, wvWin95OSR2, wvWin98,
wvWin98SE, wvWinME, wvWin9x, wvWinNT3, wvWinNT4, wvWin2000, wvWinXP,
wvWinNT, wvWinServer2003, wvWinVista);
function DSiGetWindowsVersion: TDSiWindowsVersion;
var
versionInfo: TOSVersionInfo;
begin
versionInfo.dwOSVersionInfoSize := SizeOf(versionInfo);
GetVersionEx(versionInfo);
Result := wvUnknown;
case versionInfo.dwPlatformID of
VER_PLATFORM_WIN32s: Result := wvWin31;
VER_PLATFORM_WIN32_WINDOWS:
case versionInfo.dwMinorVersion of
0:
if Trim(versionInfo.szCSDVersion[1]) = 'B' then
Result := wvWin95OSR2
else
Result := wvWin95;
10:
if Trim(versionInfo.szCSDVersion[1]) = 'A' then
Result := wvWin98SE
else
Result := wvWin98;
90:
if (versionInfo.dwBuildNumber = 73010104) then
Result := wvWinME;
else
Result := wvWin9x;
end; //case versionInfo.dwMinorVersion
VER_PLATFORM_WIN32_NT:
case versionInfo.dwMajorVersion of
3: Result := wvWinNT3;
4: Result := wvWinNT4;
5:
case versionInfo.dwMinorVersion of
0: Result := wvWin2000;
1: Result := wvWinXP;
2: Result := wvWinServer2003;
else Result := wvWinNT
end; //case versionInfo.dwMinorVersion
6: Result := wvWinVista;
end; //case versionInfo.dwMajorVersion
end; //versionInfo.dwPlatformID
end; { DSiGetWindowsVersion }
function DSiGetTrueWindowsVersion: TDSiWindowsVersion;
function ExportsAPI(module: HMODULE; const apiName: string): boolean;
begin
Result := GetProcAddress(module, PChar(apiName)) <> nil;
end; { ExportsAPI }
var
hKernel32: HMODULE;
begin { DSiGetTrueWindowsVersion }
hKernel32 := GetModuleHandle('kernel32');
Win32Check(hKernel32 <> 0);
if ExportsAPI(hKernel32, 'GetLocaleInfoEx') then
Result := wvWinVista
else if ExportsAPI(hKernel32, 'GetLargePageMinimum') then
Result := wvWinServer2003
else if ExportsAPI(hKernel32, 'GetNativeSystemInfo') then
Result := wvWinXP
else if ExportsAPI(hKernel32, 'ReplaceFile') then
Result := wvWin2000
else if ExportsAPI(hKernel32, 'OpenThread') then
Result := wvWinME
else if ExportsAPI(hKernel32, 'GetThreadPriorityBoost') then
Result := wvWinNT4
else if ExportsAPI(hKernel32, 'IsDebuggerPresent') then //is also in NT4!
Result := wvWin98
else if ExportsAPI(hKernel32, 'GetDiskFreeSpaceEx') then //is also in NT4!
Result := wvWin95OSR2
else if ExportsAPI(hKernel32, 'ConnectNamedPipe') then
Result := wvWinNT3
else if ExportsAPI(hKernel32, 'Beep') then
Result := wvWin95
else // we have no idea
Result := DSiGetWindowsVersion;
end; { DSiGetTrueWindowsVersion }
--- обновлено 2009-10-09
Оказывается что очень трудно сделать «недокументированное» обнаружение ОС на Vista SP1 и выше. Анализ изменений в API показывает, что все функции Windows 2008 также реализованы в Vista SP1 и что все функции Windows 7 также реализованы в Windows 2008 R2. Очень жаль: (
--- конец обновления
FWIW, с этой проблемой я столкнулся на практике. У нас (компания, в которой я работаю) есть программа, которая на самом деле не была Vista-). готово, когда выйдет Vista (и через несколько недель после этого ...). Она также не работала в слое совместимости (некоторые проблемы с DirectX. Не спрашивайте).
Мы тоже не хотели - умные для своих собственных хороших пользователей, чтобы запускать это приложение на Vista вообще - в режиме совместимости или нет - поэтому мне пришлось искать решение (парень, умнее меня, указал мне правильное направление; вышеизложенное не мое детище) Теперь я публикую это для вашего удовольствия и для помощи всем бедным душам, которые должны будут решить эту проблему в будущем. Google, пожалуйста, проиндексируйте эту статью!
Если у вас есть лучшее решение (или обновить и / или исправить для меня), пожалуйста, напишите ответ здесь ...
I'm reposting my answer from this question, since it applies here as well:
When displaying an audio waveform, you will want to do some sort of data reduction on the original data, because there is usually more data available in an audio file than pixels on the screen. Most audio editors build a separate file (called a peak file or overview file) which stores a subset of the audio data (usually the peaks and valleys of a waveform) for use at different zoom levels. Then as you zoom in past a certain point you start referencing the raw audio data itself.
Here are some good articles on this:
Build an Audio Waveform Display
As far as source code goes, I would recommend looking through the Audacity source code. Audacity's waveform display is pretty good and mostly likely does a similar sort of data reduction when rendering the waveforms.
CorePlot - это библиотека, которую вы ищете. Он размещен в коде Google.
См. Соответствующий вопрос SO .