PDA

View Full Version : Serial Number Validation



s3594753
01-28-2010, 12:17 AM
Hi guys,

I have around 10 features in my project. I am trying to implement check for serial number which is located on 'CustomerInformation' dialog,
i.e.
IF user enters eg. 12345 as a serial number then display all features on 'CustomSetup' dialog
ELSE IF user enters eg. ABCDE as a serial number then hide 2 of those features (don't install them).

I want to perform validation when 'NEXT' button on 'CustomerInformation' dialog is clicked.

Could you please provide me the best way how to implement it?

I appreciate you time and thanks in advance...

Regards,
s3594753

Kelter
01-28-2010, 09:47 AM
You might think that this should be simple, but it kindof... isn't. I think my description will work better if i start with the narrow answer, and work my way outward.

Making the features displayed in the CustomSetupDialog reflect the serial number:
1. Set conditions on your features such that the install level for each feature is set to 0 if it should not be installed, and, let's say, 1 otherwise.
2. Author a custom action that sets the property(ies) upon which the feature conditions depend. (In my implementation, the CA also sets/clears a "Success" value based on validation of the serial number.)
3. Add "the action that validates the serial number" to the control events associated with the "Next" button on the CustomerInformation dialog.
4. Make the NewDialog action already associated with this control depend on your "Success" property.
5. Schedule a "SetInstallLevel" event between the SN validation CA and the NewDialog event. This should probably also depend on the "Success" property. You don't actually have to change the value of the install level (for this example, I'll use 100, but any value over "1" would do, since that's what I'm setting the Features' InstallLevels to.)Calling this is just done to force re-evaluation of Feature conditions (to actually evaluate teh conditions based on the properties you set during the SN validation.)...(forgive my overuse of parenthesis.)

Okay, so at this point, you have what you want, but you may have a problem with the feature costs being improperly displayed in the CustomSetup dialog. Perhaps I'll take a break and wait for you to ask before I answer that question.

Oh, you might have trouble reinitializing on upgrade/maintenance, too, so feel free to give that a shot, and then get back at me if there is a problem... i don't know how many of these problems are due to my particular implementation, so i don't want to make you do all sorts of extra stuff if you don't have any problem with it.

s3594753
01-28-2010, 05:28 PM
Hi Kelter,

Firstly, thank you very much for a quick reply.

Sorry, forgot to mention that I am new to IS. I understand what you are saying in part 1, but I do not know how to construct a CA to check all the business logic. I would appreciate if you could provide me with a sample code how to implement CA for part 2 and above.

Once again, appreciate your time and effort to put up with my questions

Kind Regards,
s3594753

Kelter
01-29-2010, 02:12 PM
okay let's say that you applied the following for a pair of conditions to each of your "conditional" features:


Level Condition
0 NOT(EDITION="FULL")
1 EDITION="FULL"


and the "Property" property of your Serial Number edit field in the CustomerInformation dlg is set to "SERIALNUM".

Fully implement this stub:


export prototype NUMBER ValidateSerialNum( HWND );
prototype NUMBER GetEditionFromSerialNum( STRING, BYREF STRING );

function NUMBER ValidateSerialNum( hMSI )
STRING sSerialNum, sEdition;
NUMBER nSize, nRes;
begin

MsiGetProperty( hMSI, "SERIALNUM", sSerialNum, nSize );

// TODO: Do some validation

nRes = GetEditionFromSerialNum( sSerialNum, sEdition );

if( nRes = ISERR_SUCCESS )then
MsiSetProperty( "EDITION", sEdition, nSize );
MsiSetProperty( "SUCCESS", "TRUE", nSize );
else
MsiSetProperty( "EDITION", "", nSize );
MsiSetProperty( "SUCCESS", "", nSize );
endif;

return nRes;
end;

function NUMBER GetEditionFromSerialNum( szSerialNum, svEdition )
begin

if( SOME_CONDITION )then
svEdition = "FULL";
elseif( SOME_OTHER_CONDITION )
svEdition = "EXPRESS";
else
svEdition = "";
return -1;
end;

return ISERR_SUCCESS;

end;


Then create a CA with the following properties
Function Name: ValidateSerialNum
Return Proc: Synchronous (ignore)
In-Script Exec: Immediate
Exec Sched: Always

Now that you've defined "the action that validates the serial number", you're ready for step three!

s3594753
02-16-2010, 11:06 PM
Hi Kelter,

Thanks for the last replay. Sorry I was on my holiday for a while. I did implement step 1 and step 2, but I get all sorts of the compile errors:


InstallShield Script Compiler
Version 14.0.0.162
Copyright 1997-2006 Macrovision Europe Ltd. and/or Macrovision Corporation. All Rights Reserved.

Compiling...
setup.rul
\script files\setup.rul(21) : error C8038: 'EDITION' : numeric value required
\script files\setup.rul(21) : error C8039: 'nSize' : string value required
\script files\setup.rul(22) : error C8038: 'SUCCESS' : numeric value required
\script files\setup.rul(22) : error C8039: 'nSize' : string value required
\script files\setup.rul(24) : error C8038: 'EDITION' : numeric value required
\script files\setup.rul(24) : error C8039: 'nSize' : string value required
\script files\setup.rul(25) : error C8038: 'SUCCESS' : numeric value required
\script files\setup.rul(25) : error C8039: 'nSize' : string value required
\script files\setup.rul(34) : error C8025: 'SERIALNUM' : undefined identifier
\script files\setup.rul(34) : error C8025: 'sSerialNum' : undefined identifier
\script files\setup.rul(36) : error C8025: 'SERIALNUM' : undefined identifier
\script files\setup.rul(36) : error C8025: 'sSerialNum' : undefined identifier
\script files\setup.rul(37) : error C8073: 'svEdition' : missing 'then' keyword
\script files\setup.rul(38) : error C8088: 'else' : not inside if statement
\script files\setup.rul(43) : error C8019: 'return' : expected type declaration
\script files\setup.rul(43) : error C8008: '0' : identifier expected
\script files\setup.rul(45) : error C8019: 'end' : expected type declaration
Setup.inx - 17 error(s), 0 warning(s)
ISDEV : error -4370: There were errors compiling InstallScript


In your function there is section "//TO DO..." do I have to do something here?

I would appriciate if you could help me to implement this function properly.

Once again thank you very much for you time and effort.

Regards,
s3594753

J_anitha
02-17-2010, 06:24 AM
You have to create public variables "SUCCESS" and "EDITION", under property table to use them in script.

Also, use nSize = MAX_PATH, before calling MsiGetProperty().

You've missed endif in GetEditionFromSerialNum().
Rest of the errors are syntax errors.

s3594753
02-17-2010, 07:40 AM
Hi guys,

Thanks for the fast reply. I tried the ways described above, but I could not get it working. I have to finish my project by the end of this week and I would appriciate if could help me how to validate serial number entered in CustomerInfo dialog. Please guys help me as I am new to the IS and Installscripts. Thanks in advance..

Kind Regards,
s3594753:confused:

Kelter
02-17-2010, 08:50 AM
my bad...the first param in MsiSetProperty (http://msdn.microsoft.com/en-us/library/aa370391(VS.85).aspx) (and pretty much all of the Msi functions for that matter) is an MSI handle. Use hMsi as the first param. I goofed. Oh, and i guess that one doesn't takea size parameter either...so here's my revision to my terrible code.


export prototype NUMBER ValidateSerialNum( HWND );
prototype NUMBER GetEditionFromSerialNum( STRING, BYREF STRING );

function NUMBER ValidateSerialNum( hMSI )
STRING sSerialNum, sEdition;
NUMBER nSize, nRes;
begin

MsiGetProperty( hMSI, "SERIALNUM", sSerialNum, nSize );

// TODO: Do some validation

nRes = GetEditionFromSerialNum( sSerialNum, sEdition );

if( nRes = ISERR_SUCCESS )then
MsiSetProperty( hMSI, "EDITION", sEdition );
MsiSetProperty( hMSI, "SUCCESS", "TRUE" );
else
MsiSetProperty( hMSI, "EDITION", "" );
MsiSetProperty( hMSI, "SUCCESS", "" );
endif;

return nRes;
end;

function NUMBER GetEditionFromSerialNum( szSerialNum, svEdition )
begin

if( SOME_CONDITION )then
svEdition = "FULL";
elseif( SOME_OTHER_CONDITION )
svEdition = "EXPRESS";
else
svEdition = "";
return -1;
endif;

return ISERR_SUCCESS;

end;

s3594753
02-18-2010, 01:20 AM
Hi Kelter,

Thank you very much for your reply. There is no more Installscript errors showing up, but not there yet. This is what I have done:
--In Property Manager I created 2 variables: EDITION & SUCCESS and left values of those EMPTY. Also value of SERIALNUM is EMPTY

--In Installscript changed modified this line of codes:
if( "SERIALNUM" = "1234567890" )then
svEdition = "FULL";
elseif( "SERIALNUM" = "ABCDE" ) then
svEdition = "EXPRESS";
else
svEdition = "";
return -1;
endif;

--In my Feature I have condition:
LEVEL CONDITION
1 EDITION="FULL"
(only to show and install this feature if "SERIALNUM" = "1234567890") otherwise don't show and don't install)

--And on "Next" button in CustomerInformation I have these Evente,Arguments and Conditions (please see the attachment).

But I still could not successfuly validate serial number. Could you please help me with this one and tell me how to implement steps 3 and above fully. Once again thank you very much for your patiance and if you ever come to Australia I'll buy you barrel of beer
:)

Kelter
02-18-2010, 08:49 AM
You need to include the "0" condition on the feature. (See my second reply in this thread.) Also, unfortunately, the image is too compressed for me to see what's in the ControlEvent fields (mate), so i can't tell if you've done something wrong there. I'd elaborate some more, but i want to get this out to you before you leave work...

Kelter
02-18-2010, 09:16 AM
also, try to be more specific about a malfunction than simply "could not validate the serial number."

What steps did you take to test the logic? Did you try using the debugger to step through the code?


Australia sounds nice (as i shovel and salt my snowy driveway). :-]

s3594753
02-19-2010, 01:10 AM
Hi Kelter,

Thanks for a reply. I have updated attachment in my previous post, so you can see what events and conditions I am using on 'Next' button in CustomerInformation dialog. This is function at the moment:
#include "ifx.h"

export prototype NUMBER ValidateSerialNum( HWND );
prototype NUMBER GetEditionFromSerialNum( STRING, BYREF STRING );

function NUMBER ValidateSerialNum( hMSI )
STRING sSerialNum, sEdition;
NUMBER nSize, nRes;
begin

MsiGetProperty( hMSI, "SERIALNUM", sSerialNum, nSize );

// TODO: Do some validation

nRes = GetEditionFromSerialNum( sSerialNum, sEdition );

if( nRes = ISERR_SUCCESS )then
MsiSetProperty( hMSI, "EDITION", sEdition );
MsiSetProperty( hMSI, "SUCCESS", "TRUE" );
else
MsiSetProperty( hMSI, "EDITION", "" );
MsiSetProperty( hMSI, "SUCCESS", "" );
MessageBox("Invalid", INFORMATION);
endif;

return nRes;
end;

function NUMBER GetEditionFromSerialNum( szSerialNum, svEdition )
begin

if( "SERIALNUM" = "1234567890" )then
svEdition = "FULL";
elseif( "SERIALNUM" = "ABCDE" ) then
svEdition = "EXPRESS";
else
svEdition = "";
return -1;
endif;

return ISERR_SUCCESS;

end;

I added messagebox(red color font) to see when it fails, and msg box pops up all time when I enter '1234567890' in the serial number textbox. I did not debug the code. I would appriciate if you could tell me how to do that. I would like to get some of your snow here :). It is most in 30 C most of the time. Once again thank you very much for your patience, time and effort to deal with my miserable questions.

Kind Regards,
s3594753:)

J_anitha
02-19-2010, 03:41 AM
I guess your variable sSerialNum is not able to hold the value in SERIALNUM.

Please try this way:

nSize = MAX_PATH;
MsiGetProperty( hMSI, "SERIALNUM", sSerialNum, nSize );

Kelter
02-19-2010, 08:56 AM
If you click the white exclamation mark with the checkmark next to it in the toolbar at the top, the Debugger will run the UI sequence, and every time a scripted CA is launched, it will open a debugger window so you can step through the code.

Also, if you run the installation with logging, (use something like setup.exe /v"/lv SetupLog.txt") you can see each property change that happens. There's no time like the present to start getting used to reading MSI logs!

Run the installation with logging, and you can actually peek at the log while you're running the install...so after clicking the next button, check the log and search for your custom action name. You'll see a line that says "Doing action: ValidateSerialNumber" or something like that. There should be a line shortly after that (but before the "Action ended") you'll see "PROPERTY CHANGE: " and it should show the new value of the property. (I should add that using /lv! instead of just /lv will for every line to be flushed to the log immediately, so if you get annoyed by the log not catching up to you consider using that option.) Additionally, you can help yourself out by writing little debugging statements out to the log using SprintfMsiLog.

I use this little thing here for writing debugging information:

function DbgOut( sOutput )
begin
#ifdef _DEBUG
MessageBox(sOutput,INFORMATION);
#endif
#ifdef _DEBUG_LOG
SprintfMsiLog( sOutput );
#endif
end;
I just call DbgOut() throughout my code with important bits of information. When i want to see each of those statements in a MessageBox, i #define _DEBUG, otherwise, i #define _DEBUG_LOG...and when i release, i don't #define either, so that i don't show the customer all my tricks.

Those little tidbits should help you quite a bit. Check out the help topic "Setup.exe and Update.exe Command-Line Parameters" for more info on running the installation with logging.

s3594753
02-25-2010, 12:59 AM
Hi guys,

Thanks for you reply. I tried every possible solution, but I could not get it working:( . I performed every step you mention above. Also, I am not sure if I am setting events on 'Next' button in my CustomerInformation dialog (please see attachment). I tried to debug using UI using that icon in the tool bar but nothing. Message always pops up. Please guys help me on this one.

Much appriciate..

REgards,
s3594753

Kelter
02-25-2010, 09:17 AM
Oh ****! Try the "Debug" button instead of the exclamation mark! Boy, I'm slippin' aren't I? Suffice it to say, I haven't needed to debug into my UI CAs in a long while.


export prototype NUMBER ValidateSerialNum( HWND );
prototype NUMBER GetEditionFromSerialNum( STRING, BYREF STRING );

function NUMBER ValidateSerialNum( hMSI )

STRING sSerialNum, sEdition;
NUMBER nSize, nRes;
begin


MsiGetProperty( hMSI, "SERIALNUM", sSerialNum, nSize );

// TODO: Do some validation

MessageBox( "In ValidateSerialNum\n\tsSerialNum = "+sSerialNum, INFORMATION );
nRes = GetEditionFromSerialNum( sSerialNum, sEdition );
MessageBox( "In ValidateSerialNum\n\tsEdition = "+sEdition, INFORMATION );

if( nRes = ISERR_SUCCESS )then

MsiSetProperty( hMSI, "EDITION", sEdition );
MsiSetProperty( hMSI, "SUCCESS", "TRUE" );
else

MsiSetProperty( hMSI, "EDITION", "" );
MsiSetProperty( hMSI, "SUCCESS", "" );
MessageBox("Invalid", INFORMATION);
endif;

return nRes;
end;

function NUMBER GetEditionFromSerialNum( szSerialNum, svEdition )
begin

MessageBox( "In GetEditionFromSerialNum\n\tszSerialNum = "+szSerialNum, INFORMATION );

if( "SERIALNUM" = "1234567890" )then

svEdition = "FULL";
MessageBox( "Setting EDITION to FULL.", INFORMATION );
elseif( "SERIALNUM" = "ABCDE" ) then

svEdition = "EXPRESS";
MessageBox( "Setting EDITION to EXPRESS.", INFORMATION );
else

MessageBox( "Resetting EDITION.", INFORMATION );
svEdition = "";
return -1;
endif;

return ISERR_SUCCESS;

end;


Just in case there's still trouble with the debugger, i threw some message boxes in there for ya. They should be sufficient to determine what values aren't getting where they need to get.

Here's what you need to do if that doesn't provide you with enough information to pick out the problem: You need to substitute those MessageBox() calls with calls to SprintfMsiLog (or use my DbgOut function, and make sure you #define _DEBUG_LOG at the top of your script.) You then need to rebuild and run your installation with logging. (You'll probably want to do a Find/Replace on the log to replace your companyname with "Company_Name" so that you don't give stuff away...) Then post your log file. just so we don't miss anything, you may want to use \lv* instead of just \lv.

s3594753
03-02-2010, 12:42 AM
Hi Kelter and J_anitha,

Thank you for your reply. Debug is working fine now, but still complications :( . I have tried various different ways to implement serial number validation but I was unsuccessful. This is what I have done and tried:
I have one feature (Feature A) which should be visible in CustomSetup dialog only if correct serial number is entered in CustomerInformation dialog. The other features should be installed regardless.

At the moment these are Feature A properties:
Install Level = 9998
Display = Visible and Collapsed
Required = No
Condition: Level=1, Condition=EDITION="FULL" (I also tried setting other condition: Level=0, Condition= NOT(EDITION="FULL" but without any success). I removed second condition as I want to make sure that the default InstallLevel for this feature is not set to 0, otherwise I would have problem with upgrade.
- I tried to create public variables "SUCCESS=0" and "EDITION=0", under property table (Property Manager) to use them in script, but that also did not help.

-I change:

if( "SERIALNUM" = "1234567890" )then
svEdition = "FULL";
MessageBox( "Setting EDITION to FULL.", INFORMATION );
elseif( "SERIALNUM" = "ABCDE" ) then
svEdition = "EXPRESS";
MessageBox( "Setting EDITION to EXPRESS.", INFORMATION );
else
MessageBox( "Resetting EDITION.", INFORMATION );
svEdition = "";
return -1;
endif;
return ISERR_SUCCESS;
end;

to

if( szSerialNum = "12345" )then
svEdition = "FULL";
MessageBox( "Setting EDITION to FULL.", INFORMATION );
elseif( szSerialNum = "ABCDE" ) then
svEdition = "EXPRESS";
MessageBox( "Setting EDITION to EXPRESS.", INFORMATION );
else
MessageBox( "Resetting EDITION.", INFORMATION );
svEdition = "";

return -1;
endif;

return ISERR_SUCCESS;
end;

but still Feature A shows in CustomSetup dialog if invalid serial number is entered.
- 'Next' button in CustomerInformation dialog has Events,Arguments and Conditions (please see the attachment).
My INSTALLLEVEL = 100. I tried changing install level for Feature A but it did not make any difference. I really do not know what to anymore. Guys I would appreciate if you could help me to finish this project which was due last Friday.
Once again thank you very much and I appreciate your help.

Regards,
s3594753

Kelter
03-03-2010, 11:20 AM
did you run this with logging? try running with logging enabled, and then post your log. you don't need to go through the full install, just get past the customer information dialog, so we can see the properties getting set...

also:
I removed second condition as I want to make sure that the default InstallLevel for this feature is not set to 0, otherwise I would have problem with upgrade.
You want to keep both conditions. You just need to make sure you've got the logic to initialize the EDITION property during upgrade. (eg: save the SerialNumber in the registry, and use the System Search view to read the value from the registry during maintenance mode.) Any information gathered during the installation that affects how the install should be have needs to be saved for maintenance mode operations.

s3594753
03-08-2010, 07:13 PM
Hi Kelter,

Thank you very much for the reply. I will try your recommendation and let you know how I went.

Regards,
s3594753