Created
July 19, 2016 09:12
-
-
Save lniwn/dd2cbb63d4bda9d59e4ea917517bb932 to your computer and use it in GitHub Desktop.
检测系统是否安装vc运行时库
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
// Constants used to represent the MSI product CODES for all of the runtimes | |
const LPCTSTR _vc2008x86Code = TEXT("{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}"); | |
const LPCTSTR _vc2008x64Code = TEXT("{350AA351-21FA-3270-8B7A-835434E766AD}"); | |
const LPCTSTR _vc2008SP1x86Code = TEXT("{9A25302D-30C0-39D9-BD6F-21E6EC160475}"); | |
const LPCTSTR _vc2008SP1x64Code = TEXT("{8220EEFE-38CD-377E-8595-13398D740ACE}"); | |
const LPCTSTR _vc2010x86Code = TEXT("{196BB40D-1578-3D01-B289-BEFC77A11A1E}"); | |
const LPCTSTR _vc2010x64Code = TEXT("{DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}"); | |
const LPCTSTR _vc2010SP1x86Code = TEXT("{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}"); | |
const LPCTSTR _vc2010SP1x64Code = TEXT("{1D8E6291-B0D5-35EC-8441-6616F567A0F7}"); | |
// Constants used to represent the MSI product FILE NAMES for all of the runtimes pre-VC++10 | |
const LPCTSTR _vc2008x86FolderName = TEXT("x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022*"); | |
const LPCTSTR _vc2008x64FolderName = TEXT("amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022*"); | |
const LPCTSTR _vc2008SP1x86FolderName = TEXT("x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729*"); | |
const LPCTSTR _vc2008SP1x64FolderName = TEXT("amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729*"); | |
// Constants used to represent the names of VC++ runtime binaries, when checking for local folder support | |
const LPCTSTR _vc2008FileName1 = TEXT("msvcr90.dll"); | |
const LPCTSTR _vc2008FileName2 = TEXT("msvcm90.dll"); | |
const LPCTSTR _vc2008FileName3 = TEXT("msvcp90.dll"); | |
const LPCTSTR _vc2010FileName1 = TEXT("msvcp100.dll"); | |
const LPCTSTR _vc2010FileName2 = TEXT("msvcr100.dll"); | |
// Global constants and variables used in file-lookup queries | |
const LPCTSTR _winSxSFolderName = TEXT("WinSXS"); | |
// Architecture enum - used when inspecting VC++ binaries in a local folder | |
enum Architecture { X86 = IMAGE_FILE_MACHINE_I386, X64 = IMAGE_FILE_MACHINE_AMD64, Itanium = IMAGE_FILE_MACHINE_IA64 }; | |
/****************************************************************** | |
Function Name: CheckProductUsingMsiQueryProductState | |
Description: Uses Microsoft Installer (MSI) instrumentation to check | |
for the availability of Microsoft products using its product codes. | |
Inputs: pszProductToCheck - product code to look up | |
Results: true if the requested product is installed | |
false otherwise | |
******************************************************************/ | |
bool CheckProductUsingMsiQueryProductState(const LPCTSTR pszProductToCheck){ | |
bool bFoundRequestedProduct = false; | |
INSTALLSTATE ir = INSTALLSTATE_UNKNOWN; | |
// Check input parameter | |
if (NULL == pszProductToCheck) | |
return false; | |
ir = MsiQueryProductStateW(pszProductToCheck); | |
bFoundRequestedProduct = (ir == INSTALLSTATE_DEFAULT); | |
return bFoundRequestedProduct; | |
} | |
/****************************************************************** | |
Function Name: GetWinSXSDirectory | |
Description: Gets the path of the $WINDIR/WinSxS folder. | |
Inputs: NONE | |
Results: a string containing the path to the folder if found, | |
NULL otherwise. | |
******************************************************************/ | |
LPCTSTR GetWinSXSDirectory(){ | |
LPCTSTR strDirectory = NULL; | |
//Load the Windows directory | |
TCHAR windir[MAX_PATH]; | |
GetWindowsDirectory(windir, MAX_PATH); | |
TCHAR buffer[MAX_PATH]; | |
if (PathCombine(buffer, windir, _winSxSFolderName) != NULL){ | |
//operation succeeded! | |
strDirectory = buffer; | |
} | |
return strDirectory; | |
} | |
/****************************************************************** | |
Function Name: CheckProductUsingWinSxSFolder | |
Description: Queries the $WINDIR/WinSxS folder for the appropriate | |
install path for the requested product. | |
Inputs: pszProductFolderToCheck - the product name to look up. | |
Results: true if the requested product is installed | |
false otherwise | |
******************************************************************/ | |
bool CheckProductUsingWinSxSFolder(const LPCTSTR pszProductFolderToCheck){ | |
bool bFoundRequestedProduct = false; | |
LPCTSTR strWinSxSDir = GetWinSXSDirectory(); | |
if (strWinSxSDir != NULL){ | |
TCHAR searchPath[MAX_PATH]; | |
if (PathCombine(searchPath, strWinSxSDir, pszProductFolderToCheck) != NULL){ | |
WIN32_FIND_DATA FindFileData; | |
HANDLE hFind; | |
hFind = FindFirstFile(searchPath, &FindFileData); | |
if (hFind != INVALID_HANDLE_VALUE){ //found it! | |
bFoundRequestedProduct = true; | |
FindClose(hFind); | |
} | |
} | |
} | |
return bFoundRequestedProduct; | |
} | |
/****************************************************************** | |
Function Name: CheckProductUsingCurrentDirectory | |
Description: Queries the current working directory for a given binary. | |
Inputs: pszProductFolderToCheck - the product name to look up. | |
pBinaryArchitecture - the desired processor architecture | |
of the binary (x86, x64, etc..). | |
Results: true if the requested product is installed | |
false otherwise | |
******************************************************************/ | |
bool CheckProductUsingCurrentDirectory(const LPCTSTR pszProductBinaryToCheck, Architecture pBinaryArchitecture){ | |
bool bFoundRequestedProduct = false; | |
//Get the length of the buffer first | |
TCHAR currentDirectory[MAX_PATH]; | |
DWORD currentDirectoryChars = GetCurrentDirectory(MAX_PATH, currentDirectory); | |
//exit if couldn't get current directory | |
if (currentDirectoryChars <= 0) return bFoundRequestedProduct; | |
TCHAR searchPath[MAX_PATH]; | |
//exit if we couldn't combine the path to the requested binary | |
if (PathCombine(searchPath, currentDirectory, pszProductBinaryToCheck) == NULL) return bFoundRequestedProduct; | |
WIN32_FIND_DATA FindFileData; | |
HANDLE hFind= FindFirstFile(searchPath, &FindFileData); | |
//exit if the binary was not found | |
if (hFind == INVALID_HANDLE_VALUE) return bFoundRequestedProduct; | |
HANDLE hFile = INVALID_HANDLE_VALUE; | |
HANDLE hMapping = INVALID_HANDLE_VALUE; | |
hFile = CreateFile(searchPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); | |
if (hFile == INVALID_HANDLE_VALUE) goto cleanup; | |
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, pszProductBinaryToCheck); | |
if (hMapping == INVALID_HANDLE_VALUE) goto cleanup; | |
LPVOID addrHeader = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); | |
if (addrHeader == NULL) goto cleanup; //couldn't memory map the file | |
PIMAGE_NT_HEADERS peHdr = ImageNtHeader(addrHeader); | |
if (peHdr == NULL) goto cleanup; //couldn't read the header | |
//Found the binary, AND its architecture matches. Success! | |
if (peHdr->FileHeader.Machine == pBinaryArchitecture){ | |
bFoundRequestedProduct = true; | |
} | |
cleanup: //release all of our handles | |
FindClose(hFind); | |
if (hFile != INVALID_HANDLE_VALUE) | |
CloseHandle(hFile); | |
if (hMapping != INVALID_HANDLE_VALUE) | |
CloseHandle(hMapping); | |
return bFoundRequestedProduct; | |
} | |
/****************************************************************** | |
Function Name: IsVC2008Installed_x86 | |
Description: Checks if the VC++9 runtime for x86 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++9 runtime for x86 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2008Installed_x86(){ | |
return CheckProductUsingMsiQueryProductState(_vc2008x86Code) || CheckProductUsingWinSxSFolder(_vc2008x86FolderName); | |
} | |
/****************************************************************** | |
Function Name: IsVC2008Installed_x64 | |
Description: Checks if the VC++9 runtime for x64 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++9 runtime for x64 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2008Installed_x64(){ | |
return CheckProductUsingMsiQueryProductState(_vc2008x64Code) || CheckProductUsingWinSxSFolder(_vc2008x64FolderName); | |
} | |
/****************************************************************** | |
Function Name: IsVC2008SP1Installed_x86 | |
Description: Checks if the VC++9 runtime (SP1) for x86 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++9 runtime (SP1) for x86 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2008SP1Installed_x86(){ | |
return CheckProductUsingMsiQueryProductState(_vc2008SP1x86Code) || CheckProductUsingWinSxSFolder(_vc2008SP1x86FolderName); | |
} | |
/****************************************************************** | |
Function Name: IsVC2008SP1Installed_x64 | |
Description: Checks if the VC++9 runtime (SP1) for x64 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++9 runtime (SP1) for x64 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2008SP1Installed_x64(){ | |
return CheckProductUsingMsiQueryProductState(_vc2008SP1x64Code) || CheckProductUsingWinSxSFolder(_vc2008SP1x64FolderName); | |
} | |
/****************************************************************** | |
Function Name: IsVC2010Installed_x86 | |
Description: Checks if the VC++10 runtime for x86 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++10 runtime for x86 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2010Installed_x86(){ | |
return CheckProductUsingMsiQueryProductState(_vc2010x86Code); | |
} | |
/****************************************************************** | |
Function Name: IsVC2010Installed_x64 | |
Description: Checks if the VC++10 runtime for x64 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++10 runtime for x64 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2010Installed_x64(){ | |
return CheckProductUsingMsiQueryProductState(_vc2010x64Code); | |
} | |
/****************************************************************** | |
Function Name: IsVC2010SP1Installed_x86 | |
Description: Checks if the VC++10 runtime (SP1) for x86 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++10 runtime (SP1) for x86 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2010SP1Installed_x86(){ | |
return CheckProductUsingMsiQueryProductState(_vc2010SP1x86Code); | |
} | |
/****************************************************************** | |
Function Name: IsVC2010SP1Installed_x64 | |
Description: Checks if the VC++10 runtime (SP1) for x64 is installed on this machine. | |
Inputs: NONE | |
Results: true if the VC++10 runtime (SP1) for x64 is installed | |
false otherwise | |
******************************************************************/ | |
bool IsVC2010SP1Installed_x64(){ | |
return CheckProductUsingMsiQueryProductState(_vc2010SP1x64Code); | |
} | |
/****************************************************************** | |
Function Name: IsVC2008AvailableLocally_x86 | |
Description: Checks if the VC++9 runtime for x86 is available in the current directory. | |
Inputs: NONE | |
Results: true if the VC++9 runtime for x86 is available | |
false otherwise | |
******************************************************************/ | |
bool IsVC2008AvailableLocally_x86(){ | |
return CheckProductUsingCurrentDirectory(_vc2008FileName1, X86) | |
&& CheckProductUsingCurrentDirectory(_vc2008FileName2, X86) | |
&& CheckProductUsingCurrentDirectory(_vc2008FileName3, X86); | |
} | |
/****************************************************************** | |
Function Name: IsVC2008AvailableLocally_x64 | |
Description: Checks if the VC++9 runtime for x64 is available in the current directory. | |
Inputs: NONE | |
Results: true if the VC++9 runtime for x64 is available | |
false otherwise | |
******************************************************************/ | |
bool IsVC2008AvailableLocally_x64(){ | |
return CheckProductUsingCurrentDirectory(_vc2008FileName1, X64) | |
&& CheckProductUsingCurrentDirectory(_vc2008FileName2, X64) | |
&& CheckProductUsingCurrentDirectory(_vc2008FileName3, X64); | |
} | |
/****************************************************************** | |
Function Name: IsVC2010AvailableLocally_x86 | |
Description: Checks if the VC++10 runtime for x86 is available in the current directory. | |
Inputs: NONE | |
Results: true if the VC++9 runtime for x86 is available | |
false otherwise | |
******************************************************************/ | |
bool IsVC2010AvailableLocally_x86(){ | |
return CheckProductUsingCurrentDirectory(_vc2010FileName1, X86) | |
&& CheckProductUsingCurrentDirectory(_vc2010FileName2, X86); | |
} | |
/****************************************************************** | |
Function Name: IsVC2010AvailableLocally_x64 | |
Description: Checks if the VC++10 runtime for x64 is available in the current directory. | |
Inputs: NONE | |
Results: true if the VC++10 runtime for x64 is available | |
false otherwise | |
******************************************************************/ | |
bool IsVC2010AvailableLocally_x64(){ | |
return CheckProductUsingCurrentDirectory(_vc2010FileName1, X64) | |
&& CheckProductUsingCurrentDirectory(_vc2010FileName2, X64); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment