2010-07-30 3 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 nd "dbcontestdll.txt" не создается.

Есть ли предпосылки для использования DLL на основе C в установщике Windows, например, на C++, распространяемом?

ответ

1

Для специальных действий я настоятельно рекомендую статически связать с временем выполнения C. Пользовательская aciton DLL заканчивается немного больше, но у вас будет меньше зависимости от файлов вне пользовательских действий.

+0

Я решил использовать это решение. Я использовал переключатель/MT вместо переключателя/MD. – Davidann

0

Да, возможно, вам понадобится визуальная среда 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++, чтобы запустить пользовательское действие. Вы пробовали использовать файл | Новые | C++ Custom Action, который поставляется с WiX? Вы можете использовать это, чтобы заглушить свой ЦС, а затем скопировать и вставить свой код в него. Это должно дать вам все параметры компилятора и компоновщика, которые вам нужны, чтобы избежать этой проблемы.

0

У меня была эта проблема тоже. У меня была DLL MFC, которая по умолчанию динамически связывалась, и я забыл включить в пакет MSVCR100.DLL. Конечно, он отлично работал на машине разработки, он даже работал на большинстве клиентских машин, но не удался на старом ПК Vista. Я переключился на статически связанную.

Смежные вопросы