0
votes

I have a custom action dll, written in C++, which is invoked using a button during install. The purpose of the custom action is to capture the clipboard contents and evaluate whether or not the contents is in the format of a valid product key. If it is, then the 'PRODUCTKEY' property is updated, as is another property which lets me know that we have been successful.

<Control Id="PasteButton" Type="PushButton" X="25" Y="176" Width="25" Height="16" Default="yes" Text="Paste" >
    <Publish Event="DoAction" Value="MsiCheckClipboardForKey" Order="1">1</Publish>
    <Publish Property="PRODUCTKEY" Value="[PRODUCTKEY]" Order="2">ClipboardSuccess = 1</Publish>
</Control>

Unfortunately, the install is failing after this custom action has been called. However, from looking at the install log my properties have been changed which tends to suggest that my custom action code is running successfully.

MSI (c) (20:4C) [12:04:55:281]: Invoking remote custom action. DLL: C:\Users\xxxxx\AppData\Local\Temp\MSI5652.tmp, Entrypoint: msiCheckClipboardForKey

MSI (c) (20!C4) [12:04:57:746]: PROPERTY CHANGE: Modifying ClipboardSuccess property. Its current value is '0'. Its new value: '1'.

MSI (c) (20!C4) [12:04:57:746]: PROPERTY CHANGE: Adding PRODUCTKEY property. Its value is 'xxxxx-xxxxx-xxxxx-xxxxx-xxxxx'.

Action ended 12:04:57: MsiCheckClipboardForKey. Return value 3.

DEBUG: Error 2896: Executing action MsiCheckClipboardForKey failed.

This is the custom action code:

#include "StdAfx.h"
#include "Debug.h"

#pragma comment(linker, "/EXPORT:msiCheckClipboardForKey=_msiCheckClipboardForKey@4")

BOOL GetClipboardText ( IN OUT CString& strClipBoardText)
{
    strClipBoardText = _T("");
    BOOL bOK = FALSE;
    UINT uFormat = 0;
    // We need to explicitly query the clipboard for UNICODE text 
    // if we have a UNICODE application
#ifdef _UNICODE
     uFormat = CF_UNICODETEXT;
#else
     uFormat = CF_TEXT;
#endif
    if ( ::IsClipboardFormatAvailable ( uFormat ) )
    {
        if ( ::OpenClipboard ( NULL ) )
        {
            HANDLE hClipBrdData = NULL;
            if ( HANDLE hClipBrdData = ::GetClipboardData ( uFormat ) )
            {
                if ( LPTSTR lpClipBrdText = ( LPTSTR ) ::GlobalLock ( hClipBrdData ) )
                {
                     MessageBox("Clipboard Text",lpClipBrdText,NULL,NULL);
                     strClipBoardText = lpClipBrdText;
                    ::GlobalUnlock ( hClipBrdData );
                    bOK = TRUE;
                }
            }
            ::CloseClipboard();
        }
    }
    return bOK;
 }

extern "C" UINT __stdcall msiCheckClipboardForKey(MSIHANDLE hMSI)
{
    CString strClipboardText ( _T("") );
    if ( GetClipboardText ( strClipboardText ) ) 
    {
        DebugMsg ( hMSI, _T("Found clipboard text") );

        strClipboardText.Trim();
        // Look at the length.  Is it 25 (wih no dashes/slashes) or 29 (with dashes/slashes)?
        BOOL bValidLength = strClipboardText.Find ( '-' ) != -1 || strClipboardText.Find ( '/' ) != -1 ? strClipboardText.GetLength() == 29 : strClipboardText.GetLength() == 25;

        DebugMsg ( hMSI, _T("Is it a product key? %b",bValidLength) );

        if ( bValidLength )
        {
            //strClipboardText.Remove ( '-' );
            //strClipboardText.Remove ( '/' );

            MessageBox("Formatted Clipboard Text",strClipboardText,NULL,NULL);

            MsiSetProperty(hMSI, "ClipboardSuccess", "1");
            MsiSetProperty(hMSI, "PRODUCTKEY", strClipboardText);

            return 0;
        }
    }
    return 1;   // None-zero is error state
}

Not sure what the problem could be, even more so as the custom action does seem to be executed as the properties are set correctly.

1

1 Answers

0
votes

After tidying the code to add to this question and rebuilding I found that I was only getting the error when I had a string on the clipboard which wasn't evaluated as a product key format. Therefore the custom action was returning 1. I believe this to be the reason that my install failed. A return value of 1 obviously causing the install error.

Please correct me if I am wrong but this has fixed the issue.