Best practices for creating TurboActivate wrt TA_USER TA_SYSTEM

I am using Python on Windows, though I think this does not matter for my question.

I understand that the 'flags' parameter, which defaults to TA_USER when instantiating a TurboActivate object, controls where LimeLM saves its private information. It is recommended to use TA_SYSTEM and I get all of that, but my question is this:

Given that the API has provided this switch are there some situations where trying to create a TurboActivate object with TA_SYSTEM might fail if the process does not have admin permissions? I know that I can test this, but I would like to know if the LimeLM developers already know that this will occur, as my testing might not uncover all possibilities so it would be good to know what is expected and how it will fail.

Secondly, if it does fail, is an exception thrown or is the return code different or what?

Thirdly, is it recommended to try TA_SYSTEM first, if that fails then try TA_USER? If this is what is recommended, then I would like to suggest that that the API just does this automatically, perhaps if TurboActivate is called with a new flag TA_SYSTEM_THEN_USER to make the API easier to use and I would make this the default.

Finally, I would find it very helpful if the API were fully documented as to what are the exceptions thrown by the different functions. I can't find this information fully described on your website, so if it is there, please provide a link. I am using PyCharm and with many python modules it will display 'Quick Documentation' gleaned from the comments in the source code. For TurboActivate I see only this: ------turboactivate.TurboActivate def __init__(self, guid: Any, flags: int = TA_USER, dat_file_loc: str = "", library_folder: str = "") -> Any-------which is not very helpful. And while I know you have example code, these examples do not fully define the all the usages of the parameters, possible return codes, exceptions thrown, etc. E.g. There is no example of how to use TA_SYSTEM.

Here is an example of the 'Quick Documentation' I see for a method call in the another python module that provides the kind of information I am looking for:---------tifffile.tifffile.TiffWriter def __init__(self, file: Any, bigtiff: bool = False, byteorder: Any = None, append: bool = False, imagej: bool = False) -> AnyOpen a TIFF file for writing.An empty TIFF file is created if the file does not exist, else the file is overwritten with an empty TIFF file unless 'append' is true. Use 'bigtiff=True' when creating files larger than 4 GB.Params:file File name or writable binary stream, such as an open file or BytesIO.bigtiff If True, the BigTIFF format is used.byteorder The endianness of the data in the file. By default, this is the system's native byte order.append If True and 'file' is an existing standard TIFF file, image data and tags are appended to the file. Appending data may corrupt specifically formatted TIFF files such as LSM, STK, ImageJ, or FluoView.imagej If True, write an ImageJ hyperstack compatible file. This format can handle data types uint8, uint16, or float32 and data shapes up to 6 dimensions in TZCYXS order. RGB images (S=3 or S=4) must be uint8. ImageJ's default byte order is big-endian but this implementation uses the system's native byte order by default. ImageJ hyperstacks do not support BigTIFF or compression. The ImageJ file format is undocumented. When using compression, use ImageJ's Bio-Formats import function.

------

Thank you!-Doug

Hey Doug,

>> "Given that the API has provided this switch are there some situations where trying to create a TurboActivate object with TA_SYSTEM might fail if the process does not have admin permissions? "

Yes. See TurboActivate.h for all possible ways it might fail. In particular see TA_E_PERMISSION.

>> "Secondly, if it does fail, is an exception thrown or is the return code different or what?"

Exception. On Windows the chance of an exception approach 0 (unless the customers messes things up). On Unix, you need to call any function that requires a TA_USER / TA_SYSTEM flag from an admin process first. Covered extensively in TurboActivate.h.

>> "Thirdly, is it recommended to try TA_SYSTEM first, if that fails then try TA_USER? "

Not necessarily. You can do that. Or you can force the customer to use TA_SYSTEM by having them run a process as admin.

Up to you.

>> "Finally, I would find it very helpful if the API were fully documented as to what are the exceptions thrown by the different functions. "

Every function can throw an Exception (error) that inherits the "TurboActivateError" class.

For exactly which errors are returned by which functions, again open TurboActivate.h. It's the defacto up-to-date documentation of every function, error, parameter, etc., etc.

Hi Wyatt,

Thank you for your reply. As an end user, I still think you have a lot of work to do on the documentation, especially for Python users.

When my app launches it checks for activation. If not activated, it launches the TubrboActivate wizard to handle activation because I would rather not bring all of this program logic into my app if I don't have to do so.

To check for activation I must first create a TurboActivate object passing in the TA_SYSTEM/TA_USER flag:self.ta = TurboActivate(self.version.GUID, TA_SYSTEM, dat_file_loc=data_file_path)apparently this can throw several exceptions, BUT WHAT ARE THEY?

I can find no equivalent to this call in the C code since it is C not C++ and no TurboActivate object is defined in TurboActivate.h

As I said, if my app finds that is had not been activated, then I tell the user about this, quit my app and launch the TurboActivate wizard as I would rather not add all that to my Python app.

So what does the TurboActivate wizard use? TA_SYSTEM or TA_USER because I assume it has to save something to the local store.

After activation using the wizard, then the user runs my app again, my app will find that is activated, but again, in order to do this I have to create a TurboActivate object, passing in TA_SYSTEM or TA_USER. So which one do I use? Which one did the wizard use? I have no idea! Does it matter given what the Wizard has done?

Sorry if I am missing something here, but I really think if the Python API is different than the C API in some respects, then they should be documented in the PYTHON code comments or in sample code or whatever, not asking Python user to dig around in the C headers which do not really match one for one with the python API (e.g. no TurboActivate object).

For now, I will try instantiating my TurboActivate object using TA_SYSTEM and if that throws any kind of error (will it throw TA_E_PERMISSION??) then try again with TA_USER.

As I said, I suggest that you have the Python TurboActivate object have a mode which will try TA_SYSTEM first and fall back to TA_USER if desired.

-Doug