\
MAKEMSI Installs...
Samples Installed by MAKEMSI
Samples - Build New MSI/MSM
TryMeAddVersionKeywordAndLaunchCondition.MM
TryMeAddVersionKeywordAndLaunchCondition.MM |
This is one of the MAKEMSI samples which build a new MSI/MSM.
This MSI makes use of these "TryMe.MM" files:
- TryMe.ver
- TryMe.rtf
Please see the "Version File Based Launch Conditions"
section for more information.
;----------------------------------------------------------------------------
; MODULE NAME: TryMeAddVersionKeywordAndLaunchCondition.MM
;
; $Author: USER "Dennis" $
; $Revision: 1.8 $
; $Date: 07 Nov 2008 18:48:00 $
; $Logfile: C:/DBAREIS/Projects.PVCS/Win32/MakeMsi/TryMeAddVersionKeywordAndLaunchCondition.MM.pvcs $
;
; DESCRIPTION
; ~~~~~~~~~~~
; Adds the "ONLY" on keyword to the version file which allows keyword
; specification of launch conditions.
;
; The MAKEMSI documentation "sucks" up some of this code to display the
; following logical (marked) sections of code:
; * 4MakeMsiDocumentation-OnlyOn-CONFIGURATION
; * 4MakeMsiDocumentation-OnlyOn-ADDONLYONKEYWORDTOVERANDHTML
; * 4MakeMsiDocumentation-OnlyOn-CODE
;
; For the purposes of this sample everything is in this file, in "real life"
; nearly all of the following would be placed in a centralised location such
; as my "Dennis.mmh" file.
;----------------------------------------------------------------------------
;--- For this sample configuration -------------------
#define ONLYON_ALWAYS_OK_CONDITION ;;Never ignore the "OnlyOn" conditions
#define ProdInfo.Default.OnlyOn WORKSTATION WIN2000+ ;;I wish to reuse "TRYME.VER" so "simulate" use of the "OnlyOn" keyword!
;---[4MakeMsiDocumentation-OnlyOn-CONFIGURATION]----
;----------------------------------------------------------------------------
;--- Macro to get box type from Windows Registry ----------------------------
;----------------------------------------------------------------------------
#define? ComputerTypeProperty REGISTRY.PRODUCTTYPE
#(
#define? ComputerTypeGet ;;Useful macro (but also see the "MsiNTProductType" property)
;--- Only need to generate this code the first time! --------------------
#ifndef @@ComputerTypeGet.CodeGenerated
;--- Get the value form the Windows Registry ------------------------
<$RegistryRead
Property="<$ComputerTypeProperty>"
HKEY="LOCAL_MACHINE"
KEY="SYSTEM\CurrentControlSet\Control\ProductOptions"
NAME="ProductType"
>
;--- Flag code generated --------------------------------------------
#define @@ComputerTypeGet.CodeGenerated
#endif
#)
;----------------------------------------------------------------------------
;--- Define ONLYON=WORKSTATION ----------------------------------------------
;----------------------------------------------------------------------------
#define ONLYON.WORKSTATION.Desc Windows Workstation
#define ONLYON.WORKSTATION.Code <$ComputerTypeGet>
#define ONLYON.WORKSTATION.Condition <$ComputerTypeProperty> ~= "WinNT"
#define ONLYON.WORKSTATION.ErrInfo <$WindowsTypeErrInfo>
#define? WindowsTypeErrInfo ComputerType="[<$ComputerTypeProperty>]"
;----------------------------------------------------------------------------
;--- Define ONLYON=SERVER (of any type) -------------------------------------
;----------------------------------------------------------------------------
#define ONLYON.SERVER.Desc Windows Server
#define ONLYON.SERVER.Code <$ComputerTypeGet>
#define ONLYON.SERVER.Condition "ServerNT, LanmanNT" ~>< <$ComputerTypeProperty>
#define ONLYON.SERVER.ErrInfo <$WindowsTypeErrInfo>
;----------------------------------------------------------------------------
;--- Define ONLYON=WIN2000+ -------------------------------------------------
;----------------------------------------------------------------------------
#define ONLYON.WIN2000+.Desc Version WIN2000 or newer
#define ONLYON.WIN2000+.Code
#define ONLYON.WIN2000+.Condition VersionNT and (VersionNT >= 500)
#( '{NL}'
#define ONLYON.WIN2000+.ErrInfo
VersionNT=[VersionNT] ;;Display version (blank if box on Win9x)
Version9X=[Version9X] ;;Display version (blank if box on WinNT+)
#)
;---[4MakeMsiDocumentation-OnlyOn-CONFIGURATION]----
;---[4MakeMsiDocumentation-OnlyOn-ADDONLYONKEYWORDTOVERANDHTML]----
;----------------------------------------------------------------------------
;--- Add "OnlyOn" keyword to list of valid ".VER" file keywords -------------
;----------------------------------------------------------------------------
#( ""
#define COMPANY_PRODINFO_VALID_KEYWORD_LIST_EXTRA
,OnlyOn ;;New keyword starts with and keywords separated with ","
#)
#define? ProdInfo.Default.OnlyOn ;;Set the keywords default (make it optional)
;----------------------------------------------------------------------------
;--- Add "OnlyOn" info to report's summary ----------------------------------
;----------------------------------------------------------------------------
#( ''
#define? HTMLSUMM_AFTER_BUILT_AT
<TR>
<TD align="center"<$HTMLSUMM_SUPPORTED_PLATFORMS_TT>>
Supported<BR>Platforms
</TD>
<TD>
<span<$HTMLSUMM_SUPPORTED_PLATFORMS_TT>>
<$PLATFORM_MsiSupportedWhereHtml>
</span>
<$ONLYON_SUMMARY_TEXT>
</TD>
</TR>
<$COMPANY_HTMLSUMM_AFTER_SUPPORTED_PLATFORMS>
#)
;---[4MakeMsiDocumentation-OnlyOn-ADDONLYONKEYWORDTOVERANDHTML]----
;--- Include MAKEMSI support (with my customisations and MSI branding) ------
#define VER_FILENAME.VER TryMe.Ver ;;I only want one VER file for all samples!
#include "ME.MMH"
;---[4MakeMsiDocumentation-OnlyOn-CODE]----
;----------------------------------------------------------------------------
;--- Support Developer box ignoring of any "OnlyOn" checking ----------------
;----------------------------------------------------------------------------
#define? ONLYON_ALWAYS_OK_CONDITION.D %VCSID <> "" ;;If PVCS environment set then its a development box!
#define? ONLYON_ALWAYS_OK_CONDITION.P
#define? ONLYON_ALWAYS_OK_CONDITION <$ONLYON_ALWAYS_OK_CONDITION.[MMMODE]> ;;Blank or "0" (non-true) means don't ignore
;----------------------------------------------------------------------------
;--- Process "OnlyOn" keywords value ----------------------------------------
;----------------------------------------------------------------------------
#if ['<$ProdInfo.OnlyOn>' <> '']
;--- YES, we don't run on just any type of box -----------------------
#DefineRexx ''
;--- Loop through all space separated "keywords" ---------------------
@@Categories = '<$ProdInfo.OnlyOn>';
@@OnlyOnDesc = ''
@@OnlyOnCode = d2c(10);
@@OnlyOnCondition = ''
@@OnlyOnErrInfo = ''
@@UnknownCategories = ''
call Info "Only Installs on: " || @@Categories;
do while @@Categories <> ''
;--- Get next category --------------------------------------------
parse var @@Categories @@Category @@Categories;
;--- Is it valid (previously defined)? ----------------------------
@@MacBase = 'ONLYON.' || @@Category || '.'
if Defined(@@MacBase || 'Desc') = 'N' then
@@UnknownCategories = strip(@@UnknownCategories || ' ' || @@Category);
else
do
;--- Valid keyword, get details -----------------------------
@@Desc = ReplaceMacros(MacroGet(@@MacBase || 'Desc'));
if Defined(@@MacBase || 'Condition') = 'N' then
error('The "ONLYON" keyword "' || @@Category || '" is missing a condition definition!');
else
@@Condition = ReplaceMacros(MacroGet(@@MacBase || 'Condition'));
if Defined(@@MacBase || 'Code') = 'N' then
@@Code = '';
else
@@Code = ReplaceMacros(MacroGet(@@MacBase || 'Code'));
if Defined(@@MacBase || 'ErrInfo') = 'N' then
@@ErrInfo = '';
else
@@ErrInfo = ReplaceMacros(MacroGet(@@MacBase || 'ErrInfo'));
;--- Combine info -------------------------------------------
if @@OnlyOnDesc <> '' then
do
;--- Not the first item (seperator required) ------------
@@OnlyOnDesc = @@OnlyOnDesc || ' and '
@@OnlyOnCondition = @@OnlyOnCondition || ' and '
end;
@@OnlyOnDesc = @@OnlyOnDesc || @@Desc;
@@OnlyOnCondition = @@OnlyOnCondition || '(' || @@Condition || ')';
if @@Code <> '' then
do
if @@OnlyOnCode <> '' then
@@OnlyOnCode = @@OnlyOnCode || ' '
@@OnlyOnCode = @@OnlyOnCode || @@Code;
end;
if @@ErrInfo <> '' then
do
if @@OnlyOnErrInfo <> '' then
@@OnlyOnErrInfo = @@OnlyOnErrInfo || '{NL}'
@@OnlyOnErrInfo = @@OnlyOnErrInfo || @@ErrInfo;
end;
end;
end;
if @@UnknownCategories <> '' then
error('The "ONLYON" keyword specified these unknown categories:',, ' ' || @@UnknownCategories);
;--- Must restrict the message to 255 characters (MSI schema retriction) ---
if length(@@OnlyOnErrInfo) > 255 then
@@OnlyOnErrInfo = left(@@OnlyOnErrInfo, 252) || '...';
;--- We may have a condition which indicates alls OK in any circumstance ---
@@OkCondition = strip(ReplaceMacros(MacroGet('ONLYON_ALWAYS_OK_CONDITION')));
if @@OkCondition <> '' then
do
;--- We do have such a condition (useful for testing etc) -------
@@OnlyOnCondition = '(' || @@OnlyOnCondition || ') or (' || @@OkCondition || ')'
end;
;--- The condition can't be too long... ------------------------------
@@FullCondition = 'not (' || @@OnlyOnCondition || ')'; ;;True means OK (we need true to mean NOT OK)
if length(@@FullCondition) > 255 then
error('The ONLYON condition is ' || length(@@FullCondition) || ' bytes long (its limit is 255)!', 'The full condition is:',,@@FullCondition);
;--- Bit of a cludge -------------------------------------------------
@@OnlyOnErrInfo = ReplaceString(@@OnlyOnErrInfo, "{NL}", "<$CRLF>");
;--- Want this info in the summary -------------------------------
@@H = '<p><b><i>'
@@H = @@H || '<span title="This MSI has a launch condition (specified by the "OnlyOn" keyword).">'
@@H = @@H || 'This product will only install on computers of type ' || @@OnlyOnDesc || '!'
@@H = @@H || '</i></b>'
if @@OkCondition <> '' then
@@H = @@H || '<br><span style="font:xx-small">Note that for testing purposes this launch condition can be removed by ensuring the following condition evaluates to true: ' || @@OkCondition
@@H = @@H || '</span>'
call MacroSet "ONLYON_SUMMARY_TEXT", @@H
#DefineRexx
;--- Generate any required code (to set up for "Condition") --------------
<??@@OnlyOnCode>
;--- Now perform the validation ------------------------------------------
#(
<$AbortIf
Condition=^<??@@FullCondition>^
Message=^We can't install <$ProdInfo.ProductName> as this computer is not <??@@OnlyOnDesc><$Crlf><$Crlf><$Crlf><??@@OnlyOnErrInfo>^
Seq="AppSearch-"
SeqTable="InstallUISequence InstallExecuteSequence"
Key="TestOnlyOnConditionDieOnFailure"
>
#)
#endif
#define? ONLYON_SUMMARY_TEXT ;;If not set above make empty
;---[4MakeMsiDocumentation-OnlyOn-CODE]----
;----------------------------------------------------------------------------
;--- Do Stuff ---------------------------------------------------------------
;----------------------------------------------------------------------------
<$DirectoryTree Key="INSTALLDIR" Dir="c:\program files\TryMe (makemsi sample)\<$MAKEMSI_MM_BASENAME>" CHANGE="\" PrimaryFolder="Y">
<$Files "TryMe.*" DestDir="INSTALLDIR">