Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Howto update a Text Control from CA DLL?


11 replies to this topic

Danielt

Danielt
  • Members
  • 2 posts

Posted 01 November 2005 - 00:54

Hello All, this one is breaking me up for days sad.gif

I have a working MSI installer that also checks a serial code entered by the user. So, the CustomAction DLL and basic interaction works perfectly!
I decided to add a label on the CustomerInfoForm (`SerialLabelError`) that would replace the MessageBox that would pop up in case the user entered a wrong serial code.

Problem is: I cannot get the CustomAction DLL to update the Label `SerialLabelError`! I tried various examples on the internet, using ActionData, but the MSI doesn't update the Text Control in the MSI. wacko.gif
How do I tackle this? The DLL returns ERROR_SUCCES on all functions that post data back, so the DLL functions seems to be sending the data correctly back to the MSI.
In the MSI, I added (using ORCA) an ActionData entry to the to the EventMapping table. The entry points to the CustomerInfoForm > SerialLabelError > Text Attribute. Exactly as suggested by the articles I red.

Please, could anyone help me out? unsure.gif
Thanks, Daniel


The piece of code in the DLL used to send data back is:
CODE

PMSIHANDLE hRecord=MsiCreateRecord(3);
result=MsiRecordSetString(hRecord, 1, TEXT("CA_CheckSerial"));
result=MsiRecordSetString(hRecord, 2, TEXT("n.a."));
result=MsiRecordSetString(hRecord, 3, TEXT("Error: [1]"));

       result=MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONSTART, hRecord);

MsiCloseHandle(hRecord);
hRecord=MsiCreateRecord(1);    
result=MsiRecordSetString(hRecord, 1, TEXT(" (nothing yet) "));

       result=MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);

Edited by Danielt, 01 November 2005 - 09:45.


luke_s

luke_s
  • Full Members
  • 532 posts

Posted 09 November 2005 - 06:37

Can you set the text inside the control to a property?

i.e. My control text [MYPROPERTY]

You can then use MsiSetProperty in your custom action to set the text label.



Danielt

Danielt
  • Members
  • 2 posts

Posted 14 November 2005 - 23:57

First of all: Thanks for trying to help me!

I indeed tried that, but... the text is only being updated when the dialog loads (the screen were the textbox is located at).

In other words: if I am at (par example) the EULA screen and call a DLL to do some things, and want to update a textbox within that EULA dialog, I can set the [MYPROPERTY] field but the textbox doesn't update. Only if I go to the next step in the setup and then go back to the EULA screen it will have the MyProperty value loaded.

So, this doesnt realy work. I think it should be done with MsiProcessMessage, but I cannot get it working! dry.gif

luke_s

luke_s
  • Full Members
  • 532 posts

Posted 15 November 2005 - 00:32

Sorry I was a bit confused with what you were trying to achieve in my first response. Can i just confirm what you are trying to achieve?

You have a serial number dialog. When the user user enters a serial number, you want to validate this number, and if it is incorrect, you want to modify the text label to contain your own text.

If that is correct, then the main problem I can see is that you need to somehow make the custom action spit out ActionData messages while the dialog in currently on display. This is probaly achievable, but I could get quite complicated.

I would handle the problem this way:

Change the custom action to execute on the Next button of the serial number dialog. This will then validate the serial number, and if invalid, set a property, say SERIAL_NO_ERROR to 1.

The the control event after the custom action will check the value of the property SERIAL_NO_ERROR and if set to 1, then use a SpawnDialog with an error dialog, telling the user to enter a valid serial number. They then click on OK and will be returned to the serial number dialog to re-enter the number.

If the serial number is invalid, you can also create a property that contains some text about how the serial number is invalid.

You will then set this property value in your custom action, and the serial number dialog or error dialog would contain a text control that displays this property - [MY_ERROR_TEXT].

What do you think?


Kelter

Kelter
  • Full Members
  • 14 posts

Posted 12 July 2011 - 00:09

I am trying to do pretty much the same thing.

My first thought was to use a disabled edit field, and from the CA, i set the property value associated wit the edit control. this works, but it does't wrap the text properly.

My next attempt was to use ActionData. I used a text control instead of an edit control (since a text control will wrap text automatically). I set the subscription to (ActionData, Text). I created a row for the custom action in question in the ActionText table. the Template field is set to [1]. Finally here's the function i call when i want to set the text in that control:

CODE

function SetActionData1( hMSI, sMsg )
 HWND hRecActionData;
 NUMBER nRes;
begin

 hRecActionData = MsiCreateRecord(1);
 if( hRecActionData = NULL )then
   DbgOut( "Failed to create record." );
 endif;
 
 nRes = MsiRecordSetString( hRecActionData, 1, sMsg );
 if( nRes != ERROR_SUCCESS )then
   DbgOut( "SetString failed" );
 endif;
   
 nRes = MsiProcessMessage( hMSI, INSTALLMESSAGE_ACTIONDATA, hRecActionData );
 if( nRes != ERROR_SUCCESS )then
   DbgOut( "ProcessMessage failed" );
 endif;
 
end;


The other step i took that hasn't been mentioned on this thread is to use twin dialogs to make the contents update. create two dialogs that are identical. after the control event on the "next" button that calls the action which updates some data, do a "NewDialog" and point to the other copy of the dialog if validation fails. this twin dialog implemetation was necessary to make the edit box update, but like i said that's not really what i want here. i want the text control to update. i tested with and without the twin dialog implementation and the text control is not updating!

please, if anybody has any ideas, let me know!

Glytzhkof

Glytzhkof
  • Moderators
  • 1,447 posts

Posted 12 July 2011 - 03:54

I don't have time to read all this, but what I would like to say is that you should never put the license validation logic into your setup. This makes it way too easy for hackers to crack your license keys, and the GUI features of MSI aren't really good enough to allow proper entry of keys.

I suggest you put the license entry as a dialog in your application and show it on first launch. Alternatively you can allow the setup to write a public property with the license key to the registry during installation and allow this property to be specified at the msi command line. The application can then verify the key on launch.
Regards
-Stein Åsmul

Kelter

Kelter
  • Full Members
  • 14 posts

Posted 12 July 2011 - 15:00

In this case I'm actually validating some other configuration information that's being entered into the GUI.

Glytzhkof

Glytzhkof
  • Moderators
  • 1,447 posts

Posted 12 July 2011 - 16:12

Interactive configuration isn't part of deployment as far as I am concerned. When I need to be able to install a configuration I deploy it as configuration files or registry settings passed in at the command line. This allows large scale deployment to many server without visiting each server if the administrator prepares the configuration file. If only a single install is needed to a single server the user can install the setup and the configuration is done by the application itself on first launch.

An application EXE file is much better equipped to do the configuration. It has a full set of windows events and GUI features to interact with the user in a familiar way. Even a web GUI is superior to the MSI dialogs.

I would NOT complicate my deployment by doing too many tasks in the setup. Keep deployment as simple as possible, it's hard enough as it is. Deployment deploys files and registry settings and runtime components. Configuration is either done by an administrator before the installation is started and just fed to the setup, or done in the application by the user after install.

IIS setups typically involve a lot of setup configuration. In my opinion the installation should install the files and a prepared configuration file should be applied as a whole to the site if requested. Further tweaks should be done through the IIS management console, but it seems people are really trying to "do it all" in the setup.
Regards
-Stein Åsmul

Kelter

Kelter
  • Full Members
  • 14 posts

Posted 12 July 2011 - 16:52

Due to the nature of our product, our customers want to be able to configure everything that requires a reboot before the installation completes.

if they aren't running the installation silently, then we're not going to make them open a command prompt. if they are importing our merge modules then they can set the parameters themselves. so if they are running the full gui, we are going to provide what they want.

the reason people want to add configuration to the installation process is because customers want it. i'm certainly not trying to make my life more complicated, just for fun. ;-)

now i'm sure that you'll probably suggest that we just launch our control panel after installation completes or something to that effect, but there are problems with that approach that i won't get into here, and ultimately, the logic is all implemented, but i want a pretty way to provide feedback. the custom setup dialog uses a text control and a subscription and it updates during the UI sequence, so i'm sure there's a way to do it. I could fall back on a messagebox, but i don't want to make that extra click necessary for the user.

also, as an engineer, i'd rather learn to make something work rather than bailing out if there's a way to do it.

it's been fun exchanging opinions in the meantime. :-)

Glytzhkof

Glytzhkof
  • Moderators
  • 1,447 posts

Posted 12 July 2011 - 19:12

I spent days trying to implement a satisfactory MSI configuration dialog many years ago, and I ended up implementing a custom dialog shown from a dll custom action because I was not able to make a sensible user experience out of MSI dialogs. Unfortunately I do not have access to the code that I used for this.

MSI dialogs really stink (at least they did back then). I would get dialog boxes showing up at the back of all other windows with no way to bring them to the front, short of sending keystrokes. There would be update problems between controls on the dialog and in general a lot of mess.

The solution I implemented was certainly no bailout. I remember sweating a lot trying to get it working before the deadline. C++ isn't easy to rush. Maybe things are better now with MSI dialogs, but frankly I don't think so.
Regards
-Stein Åsmul

Kelter

Kelter
  • Full Members
  • 14 posts

Posted 13 July 2011 - 14:40

You're right that it's a pain, and in the future, we just might go with C# for our dialogs, but meanwhile, I've learned to do some interesting stuff. Then again, when you're holding a hammer, every problem looks like a nail. :-)

Thanks for your advice; I really appreciate your input.

Glytzhkof

Glytzhkof
  • Moderators
  • 1,447 posts

Posted 13 July 2011 - 15:37

Glad to hear it is working out for you. I assume you meant C++ instead of C#? For deployment I would not use C# just yet. Too many systems without .NET installed (unless you are targeting an SOE - Standard Operating Environment).

Too bad I don't have the code for the C style dialog I spawned from the MSI parent dialog. It worked OK, and it gave me the proper events and features I needed to make the dialog acceptable.
Regards
-Stein Åsmul