日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VS2017编译可在Win2000上运行的程序

發布時間:2025/3/19 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VS2017编译可在Win2000上运行的程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微軟最后一個可以原生編譯Win2000應用程序IDE是Visual Studio 2008,后續版本只能支持到WinXP。那么有什么辦法讓高版本的VS編譯出可以在Win2000上運行的程序呢?

首先我們要了解為什么編譯出的程序無法在Win2000上運行,首先一個原因是EXE可執行文件NTHEADER中的可選頭有一個操作系統版本和子系統版本,這個如果是支持XP,則值為5.1,如果是2000,則必須是5.0。

另外一個原因就是Win2000上kernel32.dll,缺失了一些關鍵的API,例如EncodePointer、DecodePointer等等。

有一個方案是安裝多個版本的VS,然后配置Daffodil.ENU.msi這個補丁來讓高版本的VS能夠使用低版本的Toolset。但是這有兩個個問題,首先如果讓高版本的VS識別VC2008的工具集就必須安裝VS2010,這樣就導致你的機器至少有3個版本的VS。其次就是雖然你可以使用VC2008的工具集了,但是你的編譯器也是VC2008,并不能享受高版本VC的特性,例如C99,VC++11等等。而且據我所知VC2013是第一個完整支持C99的版本,VC2015是第一個完整支持VC++11的版本。

此文給出老外的一個解決辦法,這里只做整理,原理很簡單,就是通過鏈接時符號替換。

首先創建一個最簡單的控制臺工程。只打印出hello world即可。

添加impapi.asm文件,內容如下

.586 .MODEL FLAT, STDCALLEXTERN STDCALL i__GetModuleHandleExW@12:PROC EXTERN STDCALL i__SetFilePointerEx@20:PROC EXTERN STDCALL i__InitializeSListHead@4:PROC EXTERN STDCALL i__EncodePointer@4:PROC EXTERN STDCALL i__DecodePointer@4:PROC EXTERN STDCALL i__HeapSetInformation@16:PROC.DATA__imp__InitializeSListHead@4 DWORD i__InitializeSListHead@4__imp__InterlockedPushEntrySList@8 DWORD RtlInterlockedPushEntrySList__imp__GetModuleHandleExW@12 DWORD i__GetModuleHandleExW@12__imp__EncodePointer@4 DWORD i__EncodePointer@4__imp__DecodePointer@4 DWORD i__DecodePointer@4__imp__HeapSetInformation@16 DWORD i__HeapSetInformation@16__imp__SetFilePointerEx@20 DWORD i__SetFilePointerEx@20EXTERNDEF STDCALL __imp__InitializeSListHead@4:DWORDEXTERNDEF STDCALL __imp__InterlockedPushEntrySList@8:DWORDEXTERNDEF STDCALL __imp__GetModuleHandleExW@12:DWORDEXTERNDEF STDCALL __imp__EncodePointer@4:DWORDEXTERNDEF STDCALL __imp__DecodePointer@4:DWORDEXTERNDEF STDCALL __imp__HeapSetInformation@16:DWORDEXTERNDEF STDCALL __imp__SetFilePointerEx@20:DWORD.CODE InterlockedPushEntrySList PROCpush ebxpush ebpmov ebp, ecxmov ebx, edxmov edx, [ebp+4]mov eax, [ebp+0]Epsh:mov [ebx], eaxlea ecx, [edx+10001h]lock cmpxchg8b qword ptr [ebp+0]jnz Epshpop ebppop ebxretn InterlockedPushEntrySList ENDPRtlInterlockedPushEntrySList PROCmov edi, edipush ebpmov ebp, espmov edx, [ebp+0Ch] ; ListEntrymov ecx, [ebp+08h] ; ListHeadcall InterlockedPushEntrySListpop ebpretn 8 RtlInterlockedPushEntrySList ENDPEND

添加extapi.c,內容如下

#include <windows.h>typedef BOOL (WINAPI *PFN_GET_MODULE_HANDLE_EX_W)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule); typedef BOOL (WINAPI *PFN_SET_FILE_POINTER_EX)(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod); typedef VOID (WINAPI *PFN_INITIALIZE_SLIST_HEAD)(PSLIST_HEADER ListHead); typedef PVOID (WINAPI *PFN_ENCODE_POINTER)(PVOID Pointer); typedef PVOID (WINAPI *PFN_DECODE_POINTER)(PVOID Pointer); typedef BOOL (WINAPI *PFN_HEAP_SET_INFORMATION)(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation, SIZE_T HeapInformationLength);PFN_GET_MODULE_HANDLE_EX_W pfnGetModuleHandleExW; PFN_SET_FILE_POINTER_EX pfnSetFilePointerEx; PFN_INITIALIZE_SLIST_HEAD pfnInitializeSListHead; PFN_ENCODE_POINTER pfnEncodePointer; PFN_DECODE_POINTER pfnDecodePointer; PFN_HEAP_SET_INFORMATION pfnHeapSetInformation; BOOL HasAlreadyTryGetFunction;static VOID TryGetFunction(VOID) {HANDLE hKernel32 = GetModuleHandleA("kernel32");if(HasAlreadyTryGetFunction)return;pfnGetModuleHandleExW = (PFN_GET_MODULE_HANDLE_EX_W)GetProcAddress(hKernel32, "GetModuleHandleExW");pfnSetFilePointerEx = (PFN_SET_FILE_POINTER_EX)GetProcAddress(hKernel32, "SetFilePointerEx");pfnInitializeSListHead = (PFN_INITIALIZE_SLIST_HEAD)GetProcAddress(hKernel32, "InitializeSListHead");pfnEncodePointer = (PFN_ENCODE_POINTER)GetProcAddress(hKernel32, "EncodePointer");pfnDecodePointer = (PFN_DECODE_POINTER)GetProcAddress(hKernel32, "DecodePointer");pfnHeapSetInformation = (PFN_HEAP_SET_INFORMATION)GetProcAddress(hKernel32, "HeapSetInformation");HasAlreadyTryGetFunction = TRUE; }BOOL WINAPI i__GetModuleHandleExW(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule) {TryGetFunction();if(pfnGetModuleHandleExW){return pfnGetModuleHandleExW(dwFlags, lpModuleName, phModule);}//NOT FULLY IMPLEMENTED//BasepGetModuleHandleExParameterValidationif( phModule == NULL ||(dwFlags & ~(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)) ||(dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN && dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT) ||(lpModuleName == NULL && dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) ){SetLastError(ERROR_INVALID_PARAMETER);return FALSE;}*phModule = NULL;//BasepGetModuleHandleExWif(dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS){MEMORY_BASIC_INFORMATION mbi;SIZE_T size;size = VirtualQuery(lpModuleName, &mbi, sizeof(mbi));if(size >= sizeof(PVOID) * 2){*phModule = (HANDLE)mbi.AllocationBase;}}else{*phModule = GetModuleHandleW(lpModuleName);}return TRUE; }BOOL WINAPI i__SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) {LARGE_INTEGER liDistanceToMoveTmp;DWORD dwRet;TryGetFunction();if(pfnSetFilePointerEx){return pfnSetFilePointerEx(hFile, liDistanceToMove, lpNewFilePointer, dwMoveMethod);}liDistanceToMoveTmp = liDistanceToMove;dwRet = SetFilePointer(hFile, liDistanceToMoveTmp.LowPart, &liDistanceToMoveTmp.HighPart, dwMoveMethod);if(dwRet != INVALID_SET_FILE_POINTER){lpNewFilePointer->LowPart = dwRet;lpNewFilePointer->HighPart = liDistanceToMoveTmp.HighPart;return TRUE;}return FALSE; }VOID WINAPI i__InitializeSListHead(PSLIST_HEADER ListHead) {ListHead->Alignment = 0; }PVOID WINAPI i__EncodePointer(PVOID Pointer) {TryGetFunction();if(pfnEncodePointer){return pfnEncodePointer(Pointer);}//NOT IMPLEMENTEDreturn Pointer; }PVOID WINAPI i__DecodePointer(PVOID Pointer) {TryGetFunction();if(pfnDecodePointer){return pfnDecodePointer(Pointer);}//NOT IMPLEMENTEDreturn Pointer; }BOOL WINAPI i__HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation, SIZE_T HeapInformationLength) {TryGetFunction();if(pfnHeapSetInformation)return pfnHeapSetInformation(HeapHandle, HeapInformationClass, HeapInformation, HeapInformationLength);//NOT IMPLEMENTEDreturn TRUE; }

解決方案資源管理器,在項目上右鍵菜單選擇生成自定義,勾選masm。

在extapi1.asm右鍵屬性,配置常規項類型為 Microsoft Macro Assembler。

編譯該項目,修改上述所說的版本號為5.0。

嘗試在win2000上運行通過。

?

另外還有一些在Win2000上的VC運行庫,包括VC2010 VC2012 VC2012 VC2015 VC2017

http://i430vx.net/files/Win2k/Extended%20kernel%20ONLY/

上述代碼參考來源

https://stackoverflow.com/questions/19516796/visual-studio-2012-win32-project-targeting-windows-2000

?

?

?

總結

以上是生活随笔為你收集整理的VS2017编译可在Win2000上运行的程序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。