PDA

View Full Version : Uninstall registry settings


David Wellman
03-29-2007, 03:44 AM
Hi,

I've created a global function (GF) which sets up the registry keys to give me a file association for files created by my program. This seems to work really well.

However when I run the uninstall, the registry keys set up by my GF don't get removed. In a test install project I have also included a Registry.SetValue command outside of my GF, that seems to be removed when I run the uninstall, but not the entries added within my GF.

Firstly, is what I'm seeing 'correct' or is this a bug ?

Secondly, if SF7 is working as designed (i.e. it's not a bug) I'm guessing that I can sort this out by changing my GF to add the necessary uninstall commands when it runs. This is where I get stuck. I can't see how ot add a Registry.xxx action using the UninstallData action. Can someone point me in the right direction ?

I am using version 7.0.6.1 of SF7.

Cheers,
Dave

Adam
03-29-2007, 02:11 PM
Registry actions are not automatically reversed on uninstall. You could use:

UninstallData.AddItem(UNINDATA_SCRIPTS, ItemData);

And make a script to remove the key

OR

You could add the action to remove the key to the Uninstall -> Actions section.

Adam Kapilik

David Wellman
03-30-2007, 03:06 AM
Hi Adam,

Thanks for that. It confirms that I'm heading in the right direction.

Next bit. Can you please give me or point me to an example of the "ItemData" that would be included in the "UninstallData.AddItem(UNINDATA_SCRIPTS, ItemData);" command ?

This may be very simple but I don't have a clue where to start. I've looked in the Help file and I can't see an example using UNINDATA_SCRIPTS.

Cheers,
Dave

Adam
03-30-2007, 09:45 AM
Here is a sample of how to add an action to the uninstall


ItemData = {ID="123",Timing=2,Script='Dialog.Message("Hello","World");'};
UninstallData.AddItem(UNINDATA_SCRIPTS, ItemData);


Adam Kapilik

David Wellman
03-30-2007, 12:54 PM
Hi Adam,

I'm obviously missing something here. I have added two "UninstallData.AddItem" commands, one for each registry key that are added by my global function.

Each "UninstallData.AddItem" command consists of two lines of code as follows (obviously the ID value is changed):

sItemData = {ID="WardSFA001",Timing="4",Script="Registry.DeleteKey(HKEY_CLASSES_ROOT, \".\"..String.Lower(sFileType));"};

UninstallData.AddItem(UNINDATA_SCRIPTS, sItemData);

In my example setup that I'm testing with, sFileType has a value of "psm".

The install runs ok, but the uninstall fails with the following message:

Extra Script:WardSFA001, Line 1: Argument 1 must be of type string.

The uninstall.xml file contains the following:

<ExtraScript>
<ID>WardSFA001</ID>
<Timing>4</Timing>
<Script>
UmVnaXN0cnkuRGVsZXRlS2V5KEhLRVlfQ0xBU1NFU19ST09ULC AiLiIuLlN0cmlu
Zy5Mb3dlcihzRmlsZVR5cGUpKTs=
</Script>
</ExtraScript>


Where am I going wrong ?

Cheers,
Dave

csd214
04-04-2007, 06:30 AM
Is there any chance you have used an identical ID for your two UNINDATA_SCRIPTS?

I have no experience with neither file association nor UNINDATA_SCRIPTS, but I did a test with your first Registry.DeleteKey and Adam’s “Hello World”. They both worked fine, even with the same timing, but as soon I use an identical ID, an error occurs (and none of the scripts are executed). The log file shows:

Error Script: Extra Script: WardSFA001, Line 1: invalid control char near `char(14)' (-1)
Error Run extra uninstall script: 4 (3)

With unique IDs, the scripts are executed correctly. The log:
Success Run extra uninstall script: 4
Success Run extra uninstall script: 4

SUGGESTION for a later release: Include the extra script ID in the log even when it runs with success.

I have used UninstallData.AddItem() several times with files and folders; it is nice to automate the uninstall procedures when you are working with the setup code. When it comes to scripts, I think I would prefer ordinary scripts, maybe a global function to be called from On Post Uninstall. It is easier to add conditional commands, log entries etc. this way. The UNINDATA_SCRIPTS covers only one single command line?

It should be possible to have only one global function to cover the file association. There might be two different paragraphs based on the global variable _DoingUninstall (& a common paragraph?) The GF might be called from On Post Install/On Post Uninstall.

As mentioned, I’m not familiar with the issues raised by Dave. I read the excellent article about File Association in the Knowledge Base and I found Dave’s issues to be a nice case to study.

David Wellman
04-04-2007, 09:17 AM
Hi,

Thanks for the thoughts. My two scripts definitely have different ID values (WardSFA001 and WardSFA002) so I don't think that's the problem. Also, I get a different error message than you do.

Could you please post your Registry.DeleteKey example here. I'll see if I can get that to work in my SF7 project. Cheers.

Anyone else have any thoughts ?

Cheers,
Dave

csd214
04-10-2007, 01:47 AM
Hi Dave,

I have now added the second delete command as an extra script:

On Post Install
tItemData = {ID="WardSFA001",Timing="4",Script="Registry.DeleteKey(HKEY_CLASSES_ROOT, \".\"..String.Lower(sFileType));"};
UninstallData.AddItem(UNINDATA_SCRIPTS, tItemData);
tItemData = {ID="WardSFA002",Timing="4",Script="Registry.DeleteKey(HKEY_CLASSES_ROOT, sExtDoc);"};
UninstallData.AddItem(UNINDATA_SCRIPTS, tItemData);

Be aware; the variables, sFileType and sExtDoc in my case, must have the correct value when the uninstaller runs. The simplest method is to define the variables in the Global Function area. If you define them in On Post Install an error occurs:

Script: Extra Script: WardSFA002, Line 1: Argument 2 must be of type string. (-1)

(That’s almost identical to your error message.)

When I put
sFileType = "kqx";
cExtDoc = "KQXEditor"
to the global function section, the uninstall runs smoothly. Try this solution; does it work?

If I’m right there should be a warning in the help doc.

You told your Uninstall.xml contains:
UmVnaXN0cnkuRGVsZXRlS2V5KEhLRVlfQ0xBU1NFU19ST09ULC AiLiIuLlN0cmluZy5Mb3dlcihzRmlsZVR5cGUpKTs=

This seems to be a Base64 encoded string. Decoded the command reads:
Registry.DeleteKey(HKEY_CLASSES_ROOT, "."..String.Lower(sFileType));

At execution of the uninstall process the variable sFileType has to be declared.

David Wellman
04-10-2007, 05:16 AM
Hi,

Thanks very, very much. With your help I have now managed to get my GF running as desired.

Your comment about the variable value needing to be set for the Uninstaller and the 'decoding' of the uninstall script got me thinking (finally !). I think what was missing is that when the uninstaller runs this script, variable sFileType hadn't been initialised, therefore it had a value/type of 'nil', but the Registry.DeleteKey action is expecting a string variable, hence the error message that I was getting.

I have now changed my GF to the code shown below. What I'm sure now happens is that the script that gets written out to the uninstall file contains the actual value of sFileType, and so the Registry.DeleteKey action is able to run ok.

************** start of GF **********************
function SetFileAssoc(sFileType,sProgramName,sDescription,n IconIndex)
SessionVar.Set("%SFAFileType%", sFileType);-- create a new session variable

-- Create the registry keys required for File Associations
Registry.SetValue(HKEY_CLASSES_ROOT, "."..String.Lower(SessionVar.Expand("%SFAFileType%")), "",String.Upper(SessionVar.Expand("%SFAFileType%")).."File", REG_SZ);
Registry.SetValue(HKEY_CLASSES_ROOT, String.Upper(SessionVar.Expand("%SFAFileType%")).."File".."\\\\shell\\\\open\\\\command" , "" ,sProgramName.." "..String.Char(34).."%1"..String.Char(34) , REG_SZ);
Registry.SetValue(HKEY_CLASSES_ROOT, String.Upper(SessionVar.Expand("%SFAFileType%")).."File", "", sDescription, REG_SZ);
Registry.SetValue(HKEY_CLASSES_ROOT, String.Upper(SessionVar.Expand("%SFAFileType%")).."File".."\\\\DefaultIcon", "",sProgramName..","..nIconIndex, REG_SZ);
-- Now update the uninstall so that the above registry keys get deleted
sItemData = {ID="WardSFA001",Timing=4,Script='Registry.DeleteKey(HKEY_CLASSES_ ROOT, \".\"..String.Lower(SessionVar.Expand(\"%SFAFileType%\")));'};
UninstallData.AddItem(UNINDATA_SCRIPTS, sItemData);
sItemData = {ID="WardSFA002",Timing="4",Script="Registry.DeleteKey(HKEY_CLASSES_ROOT, String.Upper(SessionVar.Expand(\"%SFAFileType%\"))..\"File\");"};
UninstallData.AddItem(UNINDATA_SCRIPTS, sItemData);
end
**************** end of GF ***********************

Once again, many thanks for your help.

Cheers,
Dave

csd214
04-11-2007, 08:02 AM
No problem; I’m pleased my examinations solved your difficulties. It was enjoyable to learn something new about SUF70. :)