問題來源:一個早期vc或者vs studio編寫的工程,在我的vs2012(win8)下更新+編譯後,運作失敗,提示:
應用程式無法啟動,因為應用程式的并行配置不正确。有關詳細資訊,請參閱應用程式事件日志,或使用指令行 sxstrace.exe 工具
百度一下sxstrace用法:
stdafx.hstdafx.h是vc建立工程時自動生成的頭檔案,裡面的内容一般是再包含其他的頭檔案
1) 管理者運作cmd ,SxsTrace Trace -logfile:SxsTrace.etl,啟動跟蹤;
2) 執行目标程式,在彈出錯誤對話框後;
3) 回到cmd指令行,按Enter鍵,然後輸入執行指令:SxsTrace Parse -logfile:SxsTrace.etl -outfile:SxsTrace.txt
先是win8下管理者運作cmd 使用win+x組合鍵,選擇指令提示符(管理者)
為了判定sxstrace.txt的位置,我決定去執行程式的目錄下,執行相應的指令
cd 指令轉換目錄不成功,解決方案如下:
例如cd F: 後還在c盤,使用如下指令: F: 回車或者 cd /d F:/
sxsTrace 确實在exe程式同一個檔案夾下,打開後主要錯誤如下:
INFO: Manifest Definition Identity is (null).
ERROR: Line 11: XML Syntax error.
如果這裡提示的是缺少什麼運作庫就好了,哎
然後帶着這兩條錯誤google,在外國的一個論壇上找到了類似的錯誤
試着去解決:
這種情況是因為manifest中儲存各種程式指定dll的入口,如果找不到這些dll,主要是CRT,就會提示上述錯誤
manifest要麼位于appname.exe.manifest檔案,要麼在二進制可執行程式中,我沒發現這個檔案
那麼就在二進制檔案中,于是用nodepad++ 打開exe
(ps:需要安裝插件HexEditor,然後view in hex)
manifest, 在二進制檔案的結尾部分,當看到xml檔案的時候
就找到了,然後根據找到依賴項:
micsoft.windows.common-controls, 在c:/windows/winsxs (winsxs 是side-by-side,并行環境的意思 )
外國友人是因為vc90_crt版本不對,下載下傳安裝就ok,教程結束,然而我這裡卻不行
目錄下搜尋micsoft.windows.common-controls 發現有很多,那大概是版本不對,然後繼續搜尋,在msdn上找到了一段代碼來測試相應的版本
#include <cstdio>
#include <windowsx.h>
#include <tchar.h>
#include <iostream>
#include "windows.h"
#include "windef.h"
#include "winbase.h"
#include "shlwapi.h"
#include <StrSafe.h>
#define PACKVERSION(major,minor) MAKELONG(minor,major)
using namespace std;
DWORD GetVersion(LPCTSTR lpszDllName)
{
HINSTANCE hinstDll;
DWORD dwVersion = 0;
// For security purposes, LoadLibrary should be provided with a fully qualified
// path to the DLL. The lpszDllName variable should be tested to ensure that it
// is a fully qualified path before it is used.
hinstDll = LoadLibrary(lpszDllName);
if(hinstDll)
{
DLLGETVERSIONPROC pDllGetVersion;
pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
// Because some DLLs might not implement this function, you must test for
// it explicitly. Depending on the particular DLL, the lack of a DllGetVersion
// function can be a useful indicator of the version.
if(pDllGetVersion)
{
DLLVERSIONINFO dvi;
HRESULT hr;
ZeroMemory(&dvi, sizeof(dvi));
// dvi.info1.cbSize = sizeof(dvi);
dvi.cbSize=sizeof(dvi);
hr = (*pDllGetVersion)(&dvi);
if(SUCCEEDED(hr))
{
//dwVersion = PACKVERSION(dvi.info1.dwMajorVersion, dvi.info1.dwMinorVersion);
dwVersion=PACKVERSION(dvi.dwMajorVersion,dvi.dwMinorVersion);
}
}
FreeLibrary(hinstDll);
}
return dwVersion;
}
int main(){
LPCTSTR lpszDllName = L"C:\\Windows\\System32\\ComCtl32.dll";
DWORD dwVer = GetVersion(lpszDllName);
DWORD dwTarget = PACKVERSION(6,0);
if(dwVer >= dwTarget)
{
cout<<"hello "<<dwTarget <<endl;
}
else
{
//cout<<"what's new "<<dwTarget <<" " <<dwVer<<endl;
cout<< ((dwTarget & 0xFFFF0000)>>16) <<" "<<(dwTarget & 0x0000FFFF)<<endl;
cout<< ((dwVer & 0xFFFF0000)>>16) <<" "<<(dwVer & 0x0000FFFF)<<endl;
// Proceed knowing that version 6.0 or later additions are not available.
// Use an alternate approach for older the DLL version.
}
return 0;
}
結果發現小于6.0,我想試試能不能通過修改二進制檔案的xml把版本改成自己的,需要解析DWORD 變量 dwVer的含義,就是明白packversion這個函數怎麼把6,0變成了一個該類型變量,百度makelong的含義,是把第二個參數16位變量左移16位加上第一個參數構成一個32位變量,于是進行一些位運算還原就是了,然後得到5 82,那麼我的版本是5.82,然後繼續在winsxs下搜尋,找到
版本号全稱5.82.9200.20765 然後pub key 是紅框裡的一串字元
(ps:通過找幾個數字的二進制嗎來判斷在何處修改)
修改後,但是沒有作用,難道注定要安裝micsoft.windows.common-controls 6.0?
等學點windows程式設計再來回頭看看吧