CustomAction réussit sur un ordinateur de développement et échoue sur un ordinateur de déploiement

Je crée un programme d’installation WiX pour installer un programme qui se connecte à une firebase database. Pour aider avec ceci, j’ai créé une dll C qui vérifie si une certaine instance de SQL existe sur un serveur:

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"dbconssortingng 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, lorsque je crée cette fonction dans une dll et que je l’ajoute à mon projet WiX, ce code fonctionne sur ma machine de développement (l’installation est terminée avec succès et le fichier “dbcontestdll.txt” existe et contient les données correctes) – -mais, lorsque je l’exécute sur une machine “nouvellement installée”, l’installation échoue avec le code de sortie 2896 et le fichier “dbcontestdll.txt” n’est pas créé.

Existe-t-il des conditions préalables à l’utilisation de dll basées sur C dans un programme d’installation Windows, tel que le redissortingbuable C ++?

Pour les actions personnalisées, je recommande fortement de créer un lien statique avec le temps d’exécution C. La DLL d’aciton personnalisée finit par devenir un peu plus grande mais vous aurez une dépendance de moins sur les fichiers en dehors de l’action personnalisée.

Vous ne voulez probablement pas vous mettre dans la situation où vous devez amorcer des redists C ++ simplement pour exécuter une action personnalisée. Avez-vous essayé d’utiliser le fichier | Nouveau | C ++ Action probject personnalisée fournie avec WiX? Vous pouvez l’utiliser pour écraser votre autorité de certificateion, puis copier et coller votre code dans celle-ci. Cela devrait vous donner tous les parameters du compilateur et de l’éditeur de liens dont vous avez besoin pour éviter ce problème.

Oui, vous avez probablement besoin du runtime Visual C. Dependency Walker peut vous aider à trouver les dll nécessaires.

Regardez cet exemple comment utiliser un Bootstrapper . De cette façon, vous pouvez installer le runtime avant que le msi ne soit exécuté. J’utilise la ligne d’amorçage suivante:

  Visual C++ 2008 Runtime Libraries (x86)  

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

J’ai aussi eu ce problème. J’avais une DLL MFC qui liait dynamicment par défaut et j’ai oublié d’inclure MSVCR100.DLL dans le package. Bien sûr, cela a bien fonctionné sur la machine de développement, même sur la plupart des machines des clients, mais cela a échoué sur un ancien PC Vista. Je suis passé à un lien statique.