インストール中にボタンを使用して呼び出される、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
}
プロパティが正しく設定されているため、カスタムアクションが実行されているように見えるため、問題が何であるかはわかりません。