Detecting/Preventing Package Installation

One of the Newton 2.x OS Q&As
Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.


Detecting/Preventing Package Installation (4/18/97)

Q: How can I keep my package from being installed on some devices that may not support it? How can I find out if my package has just been downloaded or Put Away, as opposed to being installed as a result of card insertion or resetting?

A: In Newton 2.0 and later releases, frame parts (including form/application parts and auto parts) can have a DoNotInstall function. This function is called when the package containing the part is activated for the first time as a result of downloading to the unit, putting away to the Extras Drawer, or installation with API functions such as SuckPackageFromBinary or SuckPackageFromEndpoint. The function is not called when the package is installed as a result of card insertion, resetting the unit, or moving the package from one store to another using the Extras Drawer filing. This function is incorrectly mentioned in the Newton Programmer's Guide and Newton Programmer's Reference as DoNotInstallScript. The proper name of the function is simply DoNotInstall.

The function takes no arguments. If the function for any part in a package returns non-nil, the entire package will not be installed on the device. This provides a convenient way to prevent installation on devices that do not support your package. It's considered bad form to simply fail to install and provide no notification to the user. We recommend at least using GetRoot():Notify(...) to display a message explaining why you are not installing.

The function is not copied to internal memory before executing. You must take care to EnsureInternal anything this function leaves behind to avoid the "Grip of Death" problems (the error with the alert "The package 'MyApp' still needs the card you removed...").

To create this function for a part, use SetPartFrameSlot. For example, to create a package that will not install on any unit after the year 2000 (because the world will have ended anyway), do the following:

    SetPartFrameSlot('DoNotInstall, func()
        if Time() >= 50492160 then
            begin
                GetRoot():Notify(kNotifyAlert, "Millenial",
                    "This application, and all existence, has expired.");
                true;    // return non-nil to prevent install
            end);


Note that this does nothing to prevent packages that were installed before the year 2000 from continuing to function.

Because this script executes only when a package is first installed on a given device, it may be used to set a flag that can be used by other parts of your application to do things like suggest user registration, go into demo mode, show some extra help, etc. It's probably not appropriate as a way to initialize user preferences or create initial data. Operations like that are best done by checking each time the package is installed or launched, and initializing then if it hasn't been done. This is the case because a user may install your package on a card, then remove that card from one machine and insert it into a different machine that has not previously been used with your application. The part's InstallScript will execute in this case, but the part's DoNotInstall function will not.