0

インストール中にボタンを使用して呼び出される、C++で記述されたカスタムアクションdllがあります。カスタムアクションの目的は、クリップボードの内容をキャプチャし、その内容が有効なプロダクトキーの形式であるかどうかを評価することです。そうである場合は、'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。

デバッグ:エラー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
}

プロパティが正しく設定されているため、カスタムアクションが実行されているように見えるため、問題が何であるかはわかりません。

4

1 に答える 1

0

この質問に追加するコードを整理して再構築した後、クリップボードにプロダクトキー形式として評価されていない文字列がある場合にのみエラーが発生することがわかりました。したがって、カスタムアクションは1を返していました。これが私のインストールが失敗した理由であると思います。戻り値1は、明らかにインストールエラーを引き起こします。

私が間違っている場合は訂正してください。ただし、これで問題は解決しました。

于 2012-10-05T14:00:39.157 に答える