2010-07-30 11 views
1

Je crée un programme d'installation WiX pour installer un programme qui se connecte à une base de données. Pour aider à cela, je l'ai créé un dll C qui vérifie si une instance de SQL existe sur un serveur:CustomAction réussit sur l'ordinateur de développement, échoue sur l'ordinateur de déploiement

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; 

}

Maintenant, quand Je construis cette fonction dans une DLL et l'ajoute à mon projet WiX, ce code fonctionne sur ma machine de développement (en particulier, l'installation se termine avec succès et le fichier "dbcontestdll.txt" existe et contient les données correctes) - mais, quand je l'exécute sur une machine "fresh install", l'installation échoue avec le code de sortie 2896 a Le "dbcontestdll.txt" n'est pas créé.

Existe-t-il des conditions préalables à l'utilisation de DLL basées sur C dans un Windows Installer, telles que le redistribuable C++?

Répondre

1

Pour les actions personnalisées, je recommande fortement la liaison statique à la durée d'exécution C. La DLL d'aciton personnalisée finit un peu plus grande mais vous aurez une dépendance de moins sur les fichiers en dehors de l'action personnalisée.

+0

J'ai fini par utiliser cette solution. J'ai utilisé le commutateur/MT au lieu du commutateur/MD. – Davidann

0

Oui, vous avez probablement besoin du Visual C Runtime. Dependency Walker pourrait aider à trouver les DLLs requises.

Regardez cet exemple comment use a Bootstrapper. De cette façon, vous pouvez installer le runtime avant que le msi ne soit exécuté. J'utilise la ligne suivante bootstrapper:

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

Ce paquet est normalement stocké dans le répertoire C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\vcredist_x86.

2

Vous ne voulez probablement pas vous mettre dans la situation où vous devez amorcer des redistances C++ juste pour exécuter une action personnalisée. Avez-vous essayé d'utiliser le fichier | Nouveau | C++ Custom Action probject fourni avec WiX? Vous pouvez l'utiliser pour remplacer votre autorité de certification, puis copier et coller votre code dans celui-ci. Cela devrait vous donner tous les paramètres du compilateur et de l'éditeur de liens dont vous avez besoin pour éviter ce problème.

0

J'ai eu ce problème aussi. J'avais une DLL MFC qui était dynamiquement liée par défaut, et j'ai oublié d'inclure MSVCR100.DLL dans le paquet. Bien sûr, cela a bien fonctionné sur la machine de développement, il a même fonctionné sur les machines de la plupart des clients, mais il a échoué sur un vieux PC Vista. Je suis passé à lié statiquement.