2010-07-30 78 views
1

我創建了一個WiX安裝程序來安裝連接到數據庫的程序。爲了解決這個問題,我創建了一個C DLL進行檢查,看是否有服務器上存在SQL的某些實例:CustomAction在開發計算機上成功,在部署計算機上失敗

extern "C" UINT __stdcall DBConTest(MSIHANDLE hInstaller) 

{

FILE *fp; 
fp = fopen("dbcontestdll.txt", "w"); 
_ConnectionPtr pCon; 
int iErrCode; 
HRESULT hr; 
UINT rc; 
//init COM 

fwprintf(fp, L"entering dbcontest\n"); 
if(FAILED(hr = CoInitializeEx(NULL,tagCOINIT::COINIT_APARTMENTTHREADED))) 
    return ERROR_INVALID_DATA; 

fwprintf(fp,L"did coinit\n"); 
if(FAILED(hr = pCon.CreateInstance(__uuidof(Connection)))) 
    return ERROR_INVALID_DATA; 

fwprintf(fp,L"created instance of connection\n"); 
TCHAR constr[1024]; 
DWORD constrlen = sizeof(constr); 
rc=MsiGetProperty(hInstaller,TEXT("DBCONNECTIONSTRING"), constr, &constrlen); 

fwprintf(fp, L"dbconstring is: %s\n", constr); 
TCHAR serverstr[1024]; 
DWORD serverstrlen = sizeof(serverstr); 
rc = MsiGetProperty(hInstaller,TEXT("SQLINSTANCE"),serverstr,&serverstrlen); 

fwprintf(fp, L"SQLINSTANCE is: %sl\n",serverstr); 
TCHAR finalconstr[2048]; 
swprintf(finalconstr,L"%s; Data Source=%s;",constr,serverstr); 
try{ 
    hr = pCon->Open(finalconstr,TEXT(""),TEXT(""),adConnectUnspecified); 
} 
catch(_com_error ce){ 

    fwprintf(fp, L"%s\n", msg); 
    ::MessageBox(NULL,msg,NULL,NULL); 
    CoUninitialize(); 
    MsiSetProperty(hInstaller,TEXT("DBCONNECTIONVALID"),TEXT("0")); 
    return ERROR_SUCCESS; 

} 
if(FAILED(hr)){ 
    MsiSetProperty(hInstaller,TEXT("DBCONNECTIONVALID"),TEXT("0")); 
    return ERROR_SUCCESS; 

} 
pCon->Close(); 
CoUninitialize(); 
MsiSetProperty(hInstaller,TEXT("DBCONNECTIONVALID"),TEXT("1")); 
::MessageBox(NULL,TEXT("Successfully connected to the database!"),NULL,NULL); 
fwprintf(fp, L"leaving...\n"); 
fclose(fp); 
return ERROR_SUCCESS; 

}

現在,當我將這個函數構建到一個dll中,並將其添加到我的WiX項目中,此代碼在我的開發計算機上工作(具體來說,安裝已成功完成,並且文件「dbcontestdll.txt」存在且其中包含正確的數據) - 但是,當我在「全新安裝」計算機上運行它時,安裝失敗,退出代碼爲2896 a不創建「dbcontestdll.txt」。

在Windows安裝程序(如C++可再發行組件)中使用基於C的dll是否有先決條件?

回答

1

對於自定義操作,我強烈建議靜態鏈接到C運行時。自定義aciton DLL的結果稍微大一些,但對自定義操作之外的文件的依賴性要少一點。

+0

我最終使用這種解決方案。我使用/ MT開關而不是/ MD開關。 – Davidann 2010-08-02 16:42:43

0

是的,你可能需要visual c運行時。 Dependency Walker可能有助於找到所需的dll。

看這個例子如何use a Bootstrapper。這樣您就可以在運行msi之前安裝運行時。我使用以下引導程序行:

<BootstrapperFile Include="Microsoft.Visual.C++.9.0.x86"> 
    <ProductName>Visual C++ 2008 Runtime Libraries (x86)</ProductName> 
</BootstrapperFile> 

此包通常存儲在C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\vcredist_x86目錄中。

2

您可能不想讓自己陷入必須引導C++ redists來運行自定義操作的情況。你有沒有嘗試過使用File |新增| WiX附帶的C++自定義操作問題?您可以使用它來挖出您的CA,然後複製並粘貼您的代碼。這應該給你所有的編譯器和鏈接器設置,你需要避免這個問題。

0

我也有這個問題。我有一個默認動態鏈接的MFC DLL,並且我忘了在包中包含MSVCR100.DLL。當然,它在開發機器上工作得很好,它甚至可以在大多數客戶的機器上工作,但在舊的Vista PC上卻失敗了。我切換到靜態鏈接。

相關問題