Inno Setup - Does not call deactivate during uninstall:

Hello,

So, I'd added the inno setup script to automatically deactivate the program when it gets uninstalled. However, the script which came out of the box didn't work.I then edited the script as shown below, but it still doesn't work. My app remains activated even after uninstallation (to test it, I just re-install the app after uninstallation, and the previous activation is still active).

I'd appreciate any assistance, thanks!! 👽

//Upon uninstall, deactivateprocedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);var ret: LongInt;begin // Call our function just before the actual uninstall process begins if CurUninstallStep = usUninstall then begin ret := Deactivate(True); UnloadDLL(ExpandConstant('{app}\Rubix.dll')); end; end;end;

Well, if you look at the code you'll see that if the Deactivation fails then it just continues on like nothing happened. So, you need to modify the script to use the "ret" value from Deactivate(), and prompt the user to either cancel the installation, warn them that no deactivation took place, or to let them connect to the internet and/or unblock the LimeLM activation servers to allow the deactivation to take place.

Wyatt -

I've edited the code as below. I have the function use the 'ret' value, however, it still isn't being deactivated..

//Upon uninstall, deactivateprocedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);var ret: LongInt;begin // Call our function just before the actual uninstall process begins if CurUninstallStep = usUninstall then begin // check if activated ret := IsActivatedUninstall(VERSION_GUID);

// deactivate if activated if ret = 0 then begin ret := Deactivate(True); end;

// Now that we're finished with it, unload Rubix.dll from memory. // We have to do this so that the uninstaller will be able to remove the // DLL and the {app} directory. UnloadDLL(ExpandConstant('{app}\Rubix.dll')); end;end;

For additional information - I'm not using any activation functions in inno setup. I'm having the users activate the program after install.

All I'm looking to accomplish, is to have the program get deactivated and the product key erased upon uninstall.

As such, I have included just the two functions below, and the procedure from earlier in my ISS file.

I don't distinctly call out to include the dat and dll files in the code, since they are already included in the 'Files' section of inno setup as part of my program. Also, I've renamed the turboactivate.dat and .dll files, hopefully that isn't the issue?

//TODO: goto the version page at LimeLM and paste this GUID hereconst VERSION_GUID = 'XXXXXXXXX'; // functions for the uninstallerfunction IsActivatedUninstall(versionGUID: WideString): longint;external 'IsActivated@{app}\Rubix.dll cdecl uninstallonly';function Deactivate(erasePkey: boolean): longint;external 'Deactivate@{app}\Rubix.dll cdecl uninstallonly';

Thanks.

Run the installer in the Inno Setup debugger. What is the actual return code? Is the function actually being executed? You need to give me more information before I can help you.

My guess is that because you've renamed TurboActivate.dat, you haven't passed the new filename to TurboActivate.dll so that it know where the file actually is. And thus Deactivate is giving you an error "8" (which is 0x8 in hexadecimal, which you can then look up in TurboActivate.h and see this:

/* MessageId: TA_E_PDETS Message code (in Hex): 0x8 Message code (in Decimal): 8


 MessageText:


 The product details file "TurboActivate.dat" failed to load.*/#define TA_E_PDETS                ((HRESULT)0x00000008L)

Of course this is just speculation. You need to read the actual error codes to know what is actually happening. If that is what's happening, and you want you continue to use custom filenames, then you'll have to use "PDetsFromPath()".

When I run the uninstaller via inno setup, I get an exit code of 0. Running it step by step, I see that the setup just ignores the block under 'if CurUninstallStep = usUninstall then begin'.

I then commented that line out, and then the setup proceeds to execute this statement 'ret := IsActivatedUninstall(VERSION_GUID);'.

However, in the next line, though the program is activated, the if condition is skipped. // deactivate if activated if ret = 0 then begin ret := Deactivate(True); end;

Please let me know what other information you require to help, and I will provide it.

When I run the uninstaller via inno setup, I get an exit code of 0.

I'm not talking about the exit code of the installer or uninstaller. I'm talking about the return codes for the functions. Use message boxes to print out what the return code for the TurboActivate functions (without the return codes you're just flying blind changing things that don't matter).

And, like I said in response to this:

Also, I've renamed the turboactivate.dat and .dll files, hopefully that isn't the issue?

Yes it is indeed a problem:

My guess is that because you've renamed TurboActivate.dat, you haven't passed the new filename to TurboActivate.dll so that it know where the file actually is. And thus Deactivate is giving you an error "8" (which is 0x8 in hexadecimal, which you can then look up in TurboActivate.h and see this:

/* MessageId: TA_E_PDETS Message code (in Hex): 0x8 Message code (in Decimal): 8


 MessageText:


 The product details file "TurboActivate.dat" failed to load.*/#define TA_E_PDETS                ((HRESULT)0x00000008L)

Of course this is just speculation. You need to read the actual error codes to know what is actually happening. If that is what's happening, and you want you continue to use custom filenames, then you'll have to use "PDetsFromPath()".

Please see below:

1. There are only two functions I use: IsActivatedUninstall, and Deactivate.

2. I tried to get the value of 'IsActivatedUninstall' in a message box, but I got a type mismatch error. if CurUninstallStep = usUninstall then begin // check if activated ret := IsActivatedUninstall(VERSION_GUID); msgbox(ret, mbInformation, MB_OKCancel) // deactivate if activated if ret = 0 then begin ret := Deactivate(True); end; // Now that we're finished with it, unload Rubix.dll from memory. // We have to do this so that the uninstaller will be able to remove the // DLL and the {app} directory. UnloadDLL(ExpandConstant('{app}\Rubix.dll')); end

3. If renaming turboactivate.dat is the problem, I understand I'll need to pass in the PDetsFromPath function. However, while I was able to use this function in my vb application, I don't know how to use this in my inno set up program, since the PDetsFromPath function isn't part of the inno setup API. I'm not sure of the syntax or how I'd need to pass this function in.

If it's too complicated, I could have a messagebox asking that the user deactivate prior to install as a workaround.

Please let me know your thoughts.

If it's too complicated, I could have a messagebox asking that the user deactivate prior to install as a workaround.

That would probably be the easiest thing for you to do. Unfortunately the debugging abilities of InnoSetup are truly limited, and a lot of things about it seem to be confusing you.

3. If renaming turboactivate.dat is the problem, I understand I'll need to pass in the PDetsFromPath function. However, while I was able to use this function in my vb application, I don't know how to use this in my inno set up program, since the PDetsFromPath function isn't part of the inno setup API. I'm not sure of the syntax or how I'd need to pass this function in.

You have to declare the function at the top of the script like the other functions are declared.

2. I tried to get the value of 'IsActivatedUninstall' in a message box, but I got a type mismatch error.

That because the msgbox() function expects a string and you're giving it an integer. So, convert it to a string first.

Also, you need the "ret" from Deactivate(True); That's the important thing. That tells you whether the deactivation succeeded or not and what to do based on that error code.