If you install your tracking as an add-in, you can have an exit script. See page 526 of the scripting manual, "Specify Start-up and Exit Scripts (Optional)".
One caution when using a shared table for tracking - namely, user contention when 2 users are trying to open the file. More specifically, user1 has it open - then user2 starts up and tries to open it. A couple of ways to address this:
- put a try() around the whole script! You'll loose tracking on user2, but user2 won't error out.
- Lock files - before opening the JMP table, user1 creates a "lock.txt" file, which can be blank. When User2 starts up, the script first checks for the presence of lock.txt -- if abscent, create it and open the JMP table. If lock.txt is present, then either 1) wait a few seconds and try again, or 2) exit the script cleanly without trying log start information. After user1 is done updating the JMP data table, then user1 deletes the lock.txt file. The problem you can get with this method is lock.txt files persisting in the shared directory and not getting deleted - this would happen, for example, if user1 crashed before lock.txt was deleted.
- You could also potentially trap the error on JMP table open instead of using lock files. Lock files are good if the subsequent table operation takes a long time. Your JMP tracking file will steadily grow in size and take longer for users to open each time.If you trap the error & retry after a short delay, be sure to put a counter and a maximum number of retries - otherwise uses can get stuck waiting for a file that never becomes available.
- An alternative to logging into 1 file is to log into multiple files. When a user starts JMP, he creates a JMP table - with a filename that includes the datetime and username. You then need to write a script that reads all these 1 line JMP tables and appends them to 1 big file.
I've also seen user tracking done by borrowing methods of advertisers on the Internet - namely, web beacons. You could use the web() to open a web page.
Finally, I would recommend you publish a "privacy policy" and let the users know that their usage is being monitored, what data is being collected, and how it is going to be used. If the use of the data changes in the future, publish a revised "privacy policy" stating the new use(s) of the data.
I agree with klaus819, and from an admin's perspective there are non-JMP methods for tracking software installs and software use.
Inside JMP, there are some other options besides sending e-mail. I was recently playing with an idea to track my own JMP use using a JMP start up script. The details on how to do it are in the JMP Scripting Guide, somewhere around page 257.
The script below is for JMP10 running in Windows 7, little tweaks are necessary for other operating systems or versions (see the reference above). This script will write a new row in a data table every time JMP is stated. Its set up to run without being displayed.
I used another similar script where the "event" variable has another definition, and the script is run by the windows scheduler at specified times. In this case the script only runs if my laptop is running, which is a surrogate for me running too.
The script depends on having a specific data table with specific column names. This table script is included at the end of the script below.
//!
// "//!" on the first line of a script lets the script open and run without being displayed.
// When this script is opened, it will run, and then close. To open it, to edit it, right click on it from the JMP Home Window file list and // select "Edit".
//Notes:
//This script opens a file called Data1.jmp. The script for an empty table is included below
//In practice, the "log" file would be on a directory that all users have access to
//The script will run when any user opens JMPon this computer
//
//The script must have this name: jmpStartAdmin.jsl
//The script can be in several places in windows 7
// ref: Scripting Guide p.257 (JMP 10)
// Save the script here (assuming JMP is installed here) C:\ProgramData\SAS\JMP\jmpStartAdmin.jsl
// If there is already a jmpStartAdmin.jsl file, it probably wouldn't be a good idea to write over it.
////////////////////////////////////////////////////////The script
Names Default To Here( 1 );
////////Step 1: Get the Username and ID (from R. Lucas (thank you))
// See http://msdn2.microsoft.com/en-us/library/ms724435.aspx
NameUnknown = 0;
NameFullyQualifiedDN = 1;
NameSamCompatible = 2;
NameDisplay = 3;
NameUniqueId = 6;
NameCanonical = 7;
NameUserPrincipal = 8;
NameCanonicalEx = 9;
NameServicePrincipal = 10;
NameDnsDomain = 12;
securDll = Load DLL( "Secur32.dll", AutoDeclare( false ) );
securDLL << DeclareFunction(
"GetUserNameExW",
Arg( Int32 ), // Name format (use code from above)
Arg( UnicodeString( 80 ), output ), // Name buffer
Arg( UInt32, update ) // Buffer length
);
UserName = "";
Userid = "";
NameLen = 80;
securDLL << GetUserNameExW( NameDisplay, UserName, NameLen );
securDLL << GetUserNameExW( NameSamCompatible, Userid, NameLen );
Show( UserName );
Show( Userid );
ver=JMP Version();
/////////Step 2: Open the file you want to add information to
//note: you have to add your own file path for the location of the data table
dt=open("C:\file path\Data1.jmp",invisible); //the invisible argument hides it from the user.
////////Step 3: Add the information to the data table
dt<
////////Step 4: Close the log data table
close(dt,save("C:\file path\Data1.jmp"));
//Exit(); This closes (exits) JMP right after the script runs
//if this script were run with the windows scheduler this would
//be a convenient step to run, but in this case it would be really really annoying.
///////////////////////////////////////////////////////////////////end of Script
//This is the table script for "Data1.jmp", run this to make the initial empty data table
//Then save it as your file path so that the script can use it.
/*
New Table( "Data1",
Add Rows( 0 ),
New Column( "TimeStamp",
Numeric,
Continuous,
Format( "m/d/y h:m:s", 23, 0 ),
Input Format( "m/d/y h:m:s", 0 ),
Set Values( [] )
),
New Column( "Event", Character, Nominal, Set Values( {} ) ),
New Column( "User Name", Character, Nominal, Set Selected, Set Values( {} ) ),
New Column( "UserID", Character, Nominal, Set Values( {} ) ),
New Column( "Version",
Numeric,
Continuous,
Format( "Best", 12 ),
Set Values( [] )
),
New Column( "Date",
Numeric,
Continuous,
Format( "m/d/y", 12 ),
Input Format( "m/d/y" ),
Formula( :TimeStamp - Time Of Day( :TimeStamp ) )
),
New Column( "Duration to Complete Task",
Numeric,
Continuous,
Format( "hr:m", 12 ),
Input Format( "hr:m" ),
Formula( Time Of Day( :TimeStamp - :Target Time ) )
),
New Column( "Target Time",
Numeric,
Continuous,
Format( "h:m", 8 ),
Input Format( "h:m" ),
Set Values( [] )
),
New Column( "Day of Week",
Numeric,
Continuous,
Format( "Best", 12 ),
Formula( Day Of Week( :TimeStamp ) )
)
)
You can have a jsl script that runs automatically when JMP is started. Look in the JMP scripting guide page 259 (JMP 10).
This snippet below should send a mail with User and Time information each time someone starts JMP. The script must be named jslStart.jsl and placed locally in C:\ProgramData\SAS\JMP\ (may differ among Windows versions, check the scripting guide).
However, I am not aware of a command that is activated by exiting JMP. An OS solution is probably more powerful. I have not tested the script below as I use JMP for Macintosh.
// Sends a mail when JMP is started with info on username and start time
If( Host is( Windows ),
Mail(
"to@me.com",
"User " || Word( 3, Get Default Directory(), "/" ) || " runs JMP",
"User " || Word( 3, Get Default Directory(), "/" ) || "has started a JMP session on " ||
Format( Today(), "m-d-y h.m" ) || "."
),
"Mail is only available on Windows."
);