我正在创建一个 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 安装程序中使用基于 C 的 dll 是否有先决条件,例如 C++ 可再发行组件?
您可能不希望自己陷入必须引导 C++ redists 才能运行自定义操作的境地。您是否尝试过使用 File |新 | WiX 附带的 C++ 自定义操作项目?您可以使用它来 stub 您的 CA,然后将您的代码复制并粘贴到其中。这应该为您提供避免此问题所需的所有编译器和链接器设置。
我是一名优秀的程序员,十分优秀!