CustomAction在开发计算机上成功,在部署计算机上失败

我正在创建一个WiX安装程序来安装连接到数据库的程序。 为了解决这个问题,我创建了一个C dll来检查服务器上是否存在某个SQL实例:

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,并且未创建“dbcontestdll.txt”。

是否有在Windows Installer中使用基于C的dll的先决条件,例如C ++可再发行组件?

对于自定义操作,我强烈建议静态链接到C运行时。 自定义aciton DLL最终会变大一点,但您对自定义操作之外的文件的依赖性会降低一些。

您可能不希望自己陷入必须引导C ++ redists运行自定义操作的情况。 您是否尝试过使用File | 新的| WiX附带的C ++ Custom Action probject? 您可以使用它来存根CA,然后将代码复制并粘贴到其中。 这应该为您提供避免此问题所需的所有编译器和链接器设置。

是的,您可能需要visual c运行时。 Dependency Walker可能有助于找到所需的dll。

看看这个例子如何使用Bootstrapper 。 这样您就可以在运行msi之前安装运行时。 我使用以下bootstrapper行:

  Visual C++ 2008 Runtime Libraries (x86)  

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

我也有这个问题。 我有一个默认动态链接的MFC DLL,我忘了在包中包含MSVCR100.DLL。 当然它在开发机器上运行良好,它甚至可以在大多数客户的机器上运行,但它在旧的Vista PC上失败了。 我切换到静态链接。