天天看點

應用程式無法啟動 因為應用程式的并行配置不正确 debug抗争史

問題來源:一個早期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檔案的時候

應用程式無法啟動 因為應用程式的并行配置不正确 debug抗争史

就找到了,然後根據找到依賴項:

應用程式無法啟動 因為應用程式的并行配置不正确 debug抗争史

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下搜尋,找到

應用程式無法啟動 因為應用程式的并行配置不正确 debug抗争史

版本号全稱5.82.9200.20765  然後pub key 是紅框裡的一串字元

(ps:通過找幾個數字的二進制嗎來判斷在何處修改)

修改後,但是沒有作用,難道注定要安裝micsoft.windows.common-controls 6.0?

等學點windows程式設計再來回頭看看吧

繼續閱讀