Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Register a 64bit DLL from 32 bit MSI


4 replies to this topic

fady.development@gmail.com

fady.development@gmail.com
  • Full Members
  • 4 posts

Posted 21 February 2014 - 06:03

Hello All, 

I'm using Installshield 2011, Basic MSI, building a 32 bit MSI. 

 

In the product we build 2 DLLs one to be used on the 32 bit machines, I self register this one with no problems and another DLL built for 64 bit machines that I'm trying to conditionally register if I detect a 64 bit system.

 

The problem is how could I register this DLL only on 64 bit machines.

I found a solution on this forum at http://community.fle...or-64-bit/page2 However, my problem with this solution is where to hook up these 2 functions in InstallShield 2011, as I can't find the events the solutions talks about ( for the registration after 'InstallExecute' ), I'm also trying to reference the INSTALLDIR from within the function but it comes up as empty string???

 

I created a dummy functions to test with, and both functions are called during the first install, Modify, and uninstall. How I make sure that each function is only called during the install or uninstall respectively.  

 

1- Can someone tell me after what sequence should I hook up these functions, 

2- If you have a different solution that works that would be great.

 

Thank you so much in advance



deramor

deramor
  • Full Members
  • 187 posts

Posted 21 February 2014 - 17:23

Normally, to register things for 64-bit, you should create a 64-bit installer.  I assume that you are trying to avoid this.

To answer some of your questions, the InstallExecute action can be found in your Custom Actions and Sequences view.  It combined with InstallInitialize that comes wayyyy before it make up the sequence of events that commit changes to a pc. Your function should be called via a Custom Action that is placed between these 2 events.  It must be a deferred action which is one of the options when you create a CA.

 

Each CA can not access properties directly.  There is a very short list of things they can see on their own.  I forget the whole list but the important one is called CustomActionData.

This property acts like a mailbox for your custom actions.  You must save variables and their values to it outside of the InstallInitialize <-> InstallExecute sequence.  You may then access these values from within each of your CAs.  I did a quick search for how to do this and it is not immediately found so below you can find my getter and setter.

 

////////////////////////////////////////////////////////////////////////////////////////
//
//  Function: CA_GetProperty
//    Returns 0 for success; 1 for error.
//
//    This function returns a requested property value after parsing CustomActionData property
//    and retriving all property name/value pairs. The function reports error if it occurs.
//  
////////////////////////////////////////////////////////////////////////////////////////
function CA_GetProperty(hMSI, sPropName, sPropValue)
    STRING sCAData, sPropPair, sName, sValue;
    NUMBER nResult, nLength;
    INT nMode;
    LIST listProps, listPropPair;
    LIST listPropNames;
    LIST listPropValues;
begin
    nLength = MAX_PATH;
    nResult = MsiGetProperty(hMSI, "CustomActionData", sCAData, nLength);
    if (nResult < 0) then
        //ReportError(hMSI, "The CustomActionData property does not exist.");
        return -1;
    else
        listProps = ListCreate (STRINGLIST);
        listPropNames = ListCreate (STRINGLIST);
        listPropValues = ListCreate (STRINGLIST);
        // Get each path from the search path into the list.
        if (StrGetTokens (listProps, sCAData, "|") < 0) then
            // Report the error.
            //ReportError(hMSI, "StrGetTokens on listProps failed.");
            return -1;
        else
            // Display the individual paths from the list.
            nResult = ListGetFirstString (listProps, sPropPair);
            // Loop while list items continue to be retrieved.
            while (nResult != END_OF_LIST)
                // Display the current element.
                listPropPair = ListCreate (STRINGLIST);
                if (StrGetTokens (listPropPair, sPropPair, "=") > 0) then
                    // Report the error.
                    //ReportError(hMSI, "StrGetTokens on ListPropPair failed.");
                    return -1;
                else
                    if (ListGetFirstString(listPropPair, sName) != END_OF_LIST) then
                        ListAddString(listPropNames, sName, AFTER);
                        if (ListGetNextString (listPropPair, sValue) == END_OF_LIST) then
                            sValue = "";
                        endif;
                            ListAddString(listPropValues, sValue, AFTER);
                        endif;
                endif;      
                ListDestroy(listPropPair);
                // Get the next string in the list.
                nResult = ListGetNextString (listProps, sPropPair);
            endwhile;
            endif;
        endif;
        // Remove the list from memory.
        ListDestroy (listProps);
    if (ListFindKeyValueString(listPropNames, listPropValues, sPropName, sPropValue) != 0) then
        return -1;
    endif;
    return 0;                         
end;



////////////////////////////////////////////////////////////////////////////////////////
//
//  Function: CA_UseProperty
//
//    This function adds a property name/value pair into the property of a custom action name
//    so that it can be retrived by the custom action in the deferred action.
//  
////////////////////////////////////////////////////////////////////////////////////////

function CA_SetProperty(hMSI, sCustomActioName, sPropName)
    STRING sCAData, sPropValue;
    NUMBER nLength;
begin
    nLength = MAX_PATH;
    MsiGetProperty(hMSI, sPropName, sPropValue, nLength);
    
    nLength = MAX_PATH;
    MsiGetProperty(hMSI, sCustomActioName, sCAData, nLength);
    
    if (StrLength(sCAData) > 0) then
        sCAData = sCAData + "|";    
    endif;
    
    sCAData = sCAData + sPropName + "=" + sPropValue;
    MsiSetProperty(hMSI, sCustomActioName, sCAData);
    
end;

 

To use these functions you must call another CA with the setter in it.  It looks like this:

 

CA_SetProperty(hMSI, "CreateStartShortcut", "INSTALLDIR");

 

Note you need a handle which is passed into the CA this function call is in. 

Next is the CA name you want to assign the value to.  This will allow you you get the data you want later.

And lastly is the property you want.  The Setter above will look up the property value for you.

 

In your CA where you will use this value, you will do the following:

CA_GetProperty(hMSI, "INSTALLDIR", svInstallDir);

 

Pretty simple in application.



fady.development@gmail.com

fady.development@gmail.com
  • Full Members
  • 4 posts

Posted 21 February 2014 - 17:38

Thank you so much deramor for your answer and the information, 

 

One more thing, 

How can I force one my functions / CA to run only during the installation or modification, and run the other function / CA only during the uninstall.



deramor

deramor
  • Full Members
  • 187 posts

Posted 21 February 2014 - 17:45

Not Installed will do the only during install time.

REMOVE="ALL" is uninstall time

 

Not sure about modification.  Maybe Not Installed OR REMOVE!="ALL".  That may be the wrong syntax however.

There is likely a property that denotes maintenance mode.



tnand53

tnand53
  • Full Members
  • 23 posts

Posted 21 February 2014 - 19:33

If your project is basic MSI ; you can use feature conditions; Below link explain you.

 

http://msdn.microsof...1(v=vs.85).aspx