Windows Installer,成功执行后自定义操作的错误2896

时间:2012-10-05 11:19:37

标签: c++ dll wix windows-installer custom-action

我有一个自定义动作dll,用C ++编写,在安装过程中使用按钮调用。自定义操作的目的是捕获剪贴板内容并评估内容是否采用有效产品密钥的格式。如果是,则更新'PRODUCTKEY'属性,另一个属性让我知道我们已成功。

<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>

不幸的是,在调用此自定义操作后,安装失败。但是,通过查看安装日志,我的属性已更改,这往往表明我的自定义操作代码已成功运行。

  

MSI(c)(20:4C)[12:04:55:281]:调用远程自定义操作。 DLL:   C:\ Users \ xxxxx \ AppData \ Local \ Temp \ MSI5652.tmp,入口点:   msiCheckClipboardForKey

     

MSI(c)(20!C4)[12:04:57:746]:物业变更:修改   ClipboardSuccess属性。其当前值为“0”。它的新价值:   '1'。

     

MSI(c)(20!C4)[12:04:57:746]:物业变更:添加PRODUCTKEY   属性。它的值是'xxxxx-xxxxx-xxxxx-xxxxx-xxxxx'。

     

动作结束12:04:57:MsiCheckClipboardForKey。返回值3。

     

DEBUG:错误2896:执行操作MsiCheckClipboardForKey失败。

这是自定义操作代码:

#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
}

不确定问题是什么,甚至更多,因为自定义操作似乎在正确设置属性时执行。

1 个答案:

答案 0 :(得分:0)

在整理代码以添加到此问题并重建之后,我发现当我在剪贴板上有一个未被评估为产品密钥格式的字符串时,我只得到了错误。因此自定义操作返回1.我相信这是我的安装失败的原因。返回值1显然导致安装错误。

如果我错了,请纠正我,但这解决了问题。