0

J'ai une application C++ dans Visual Studio 2010 et j'ai un Windows Installer (projet d'installation) pour l'installer. Je veux être en mesure d'invoquer le programme d'installation comme ceci:Windows Installer, accéder à une propriété personnalisée dans une action personnalisée en C++

Setup1.msi MYPROPERTY=MyValue 

Et puis être en mesure d'extraire la valeur « MyValue » de la propriété à partir de mon action personnalisée. J'ai essayé de le faire fonctionner en suivant this tutorial (C++ actions personnalisées) et this tutorial (passer des arguments à des actions personnalisées, mais en C#) combiné avec certains MSDN recherches pour obtenir ce code:

#define WINDOWS_LEAN_AND_MEAN 
#include <Windows.h> 
#include <msi.h> 
#include <msiquery.h> 
#include <stdio.h> 

BOOL APIENTRY DllMain(HANDLE, DWORD, LPVOID) { 
    return TRUE; 
} 

UINT APIENTRY InstallCustomAction(MSIHANDLE install_handle) { 
    static const wchar_t* kPropertyName = L"MYPROPERTY"; 

    //auto msi_handle = MsiGetActiveDatabase(install_handle); 

    DWORD n = 0; 
    //auto result = MsiGetProperty(msi_handle, kPropertyName, L"", &n); 
    auto result = MsiGetProperty(install_handle, kPropertyName, L"", &n); 
    wchar_t* value = nullptr; 
    if (result == ERROR_MORE_DATA) { 
     ++n; 
     value = new wchar_t[n]; 
     //result = MsiGetProperty(msi_handle, kPropertyName, value, &n); 
     result = MsiGetProperty(install_handle, kPropertyName, value, &n); 
    } 

    if (result == ERROR_SUCCESS) { 
     wchar_t buffer[128]; 
     swprintf_s(buffer, L"n = %d, value = %s", n, value); 
     MessageBox(nullptr, buffer, L"CustomAction", MB_OK); 

    } else { 
     MessageBox(nullptr, L"Error reading property", L"Error", MB_OK); 
    } 
    delete value; 
    //MsiCloseHandle(msi_handle); 
    return ERROR_SUCCESS; 
} 

que je suis la C# tutoriel exactement en termes de l'IDE (j'ai Entry Point mis à InstallCustomAction et Custom Action Données définies à /MYPROPERTY=[MYPROPERTY]) L'action personnalisée se déclenche correctement mais je ne reçois pas le paramètre.

Avec le code tel quel, j'obtiens n = 0. Si j'utilise le msi_handle de MsiGetActiveDatabase, j'obtiens une erreur (par exemple, MsiGetProperty renvoie autre chose que ErrorSuccess).

Comment puis-je obtenir la propriété que l'utilisateur passe sur la ligne de commande à partir de mon action personnalisée?

Répondre

1

Il n'est pas nécessaire d'appeler MsiGetActiveDatabase. D'après ce que vous avez écrit, il semble que votre action personnalisée soit programmée pour une exécution différée. Dans ce scénario, vous devriez essayer d'obtenir la propriété nommée "CustomActionData".

+0

Je ne pense pas que cela soit différé. J'ai l'action personnalisée définie sur «Installer» (parmi les choix d'installation, de validation, de restauration et de désinstallation) et la boîte de message s'affiche avant la fin de l'installation. Aussi je ne sais pas où j'obtiendrais une propriété "CustomActionData" à l'intérieur de mon code, je place cette propriété dans l'IDE (je la mets à/MYPROPERTY = [MYPROPERTY]) –

+0

Il est différé. Les projets d'installation n'ont pas la possibilité de planifier des actions personnalisées d'une autre manière. –

+0

Donc, je suppose que je ne sais pas ce que signifie différé dans ce contexte. Quoi qu'il en soit, comment j'accède à la propriété CustomActionData, serait-il à travers la fonction MsiGetProperty? J'ai fait tout cela au travail et je suis à la maison maintenant, mais je suppose que je peux reproduire le projet et l'essayer. –