>> "and thanks for a great licensing system!"
Thanks, we really appreciate that!
>> "If it is expired, I want to give the customer the option to buy a new key. I do a TA_Deactivate and a TA_DeactivationRequestToFile so that TurboActivate do not open with the activation success window. Is this the best way to do this?"
No, it's not the best way. The better way to do things is just modify the existing product key with the new expiration date. Here's an example in the custom license fields docs: https://wyday.com/limelm/help/license-features/#change-datetime
>> "For my offline activating customers this returns "Error code 4: The system cannot open the file"."
Visual Studio expands "HRESULT" return codes to their own error codes. Those don't match our actual return codes. See TurboActivate.h for a full list of return codes with full descriptions and how to handle them. A "4" return code has nothing to do with files. It's TA_E_INET, which means TurboActivate couldn't contact the activation servers for any of a million reasons.
>> "If so, I do TA_ActivateFromFile(taHandle, _("ActivationResponse.xml")). This call always returns S_FALSE and the app is closed. "
You need to specify the full path. Otherwise it will use the "current directory" which is never what you would expect it to be.
Also, TurboActivate doesn't return S_FALSE. Again, that's a Windows thing. It returns TA_[SOMETHING}. Like TA_OK, TA_FAIL, etc., etc.
>> "Also, is there a way to check if the activation was done online or offline? "
No, but you can tell IsGenuineEx() to not worry about offline activations if it fails to contact the servers.
>> "And a way to ask for the file path of the response file?"
You would do that in your app and then pass the path to the TurboActivate functions.