2010-07-30 79 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上却失败了。我切换到静态链接。

相关问题