lido Posted January 5, 2019 Posted January 5, 2019 Please advise me about the step by step procedure, algorithm, etc., to license an AutoLISP program (VLX file) to the end user with a trial period of 30 days, during which the user can test the demo version of the program. Thank you Quote
BIGAL Posted January 7, 2019 Posted January 7, 2019 There are various ways of testing a date via lisp, lee-mac has a check date via internet this removes the PC clock which can be wound back. you just IF date > expire date then a exit defun use (Exit) last. This question has been posted here before. Quote
Lee Mac Posted January 7, 2019 Posted January 7, 2019 11 hours ago, BIGAL said: lee-mac has a check date via internet this removes the PC clock which can be wound back. Internet Time Thanks for the recommendation @BIGAL 1 Quote
Grrr Posted January 7, 2019 Posted January 7, 2019 (edited) BTW one could do this aswell, by putting a fixed (expiration) date : (cond ( (>= (read (substr (rtos (getvar 'cdate) 2 5) 1 8)) 20181226) (prompt "\nProgram Expired !") (princ) ) ; expiration ( ; .. Define functions for our program (defun C:MyHandsomeProgram nil ; ... ); defun (defun C:AnotherHandsomeProgram nil ; ... ); defun (defun SomeFancySubFun ( args ) ;... ); defun ; ... ) ); cond Although one thing I couldn't figure out yet, was how to alert when the program expires in X days, when the year or the month is changed - ( (lambda ( cdate expdate / ) (cond ( (and (= 3 (- expdate cdate)) (alert "\nProgram will exipre in 3 days.")) ) ( (and (= 2 (- expdate cdate)) (alert "\nProgram will exipre in 2 days.")) ) ( (and (= 1 (- expdate cdate)) (alert "\nProgram will exipre in 1 day.")) ) ( (>= cdate expdate) (alert "\nProgram Expired !") (princ) ) ; expiration (t (defun C:test ( / ) (alert "Hello World") (princ) ); defun C:test ; .. Define functions for our program ); t ); cond ); lambda (read (substr (rtos (getvar 'cdate) 2 5) 1 8)) 20190131 ) Say the expiration date is on 2019.02.01 and the current date is 2019.01.30, so we'd like to alert that there are 2 days remaining. Edited January 7, 2019 by Grrr Quote
Lee Mac Posted January 7, 2019 Posted January 7, 2019 (edited) 58 minutes ago, Grrr said: Say the expiration date is on 2019.02.01 and the current date is 2019.01.30, so we'd like to alert that there are 2 days remaining. The easiest way is to use the contiguous Julian date system, e.g.: ( (lambda ( date expdate / dif ) (if (cond ( (not (or dtoj (and (load "julian.lsp" nil) dtoj)))) ( (<= (setq dif (- (fix (dtoj expdate)) date)) 0) (alert "Program has expired.") ) ( (progn (alert (strcat "Program will expire in " (itoa dif) " day" (if (= 1 dif) "." "s."))) t)) ) (progn (defun c:test ( ) (alert "Hello World!") (princ) ) ) ) ) (fix (getvar 'date)) 20190131 ) Here, the Express Tools' dtoj function is only used to make it easier to specify the expiration date in the code - you can easily remove this reliance by specifying the expiration date as a Julian date directly in the code. Note that this approach is still susceptible to the user changing the system clock - hence the suggestion to use my Internet Time function above. Edited January 7, 2019 by Lee Mac 2 Quote
ssdd Posted January 7, 2019 Posted January 7, 2019 (edited) Can I add a MacAddress? ( (lambda ( date expdate / dif ) (if (cond ( (not (or dtoj (and (load "julian.lsp" nil) dtoj)))) ( (<= (setq dif (- (fix (dtoj expdate)) date)) 0) (alert "Program has expired.") ) ( (not get_macaddress) (princ "\nFunction get_macaddress is not loaded.") ) ( (not (eq MyMacAddress (get_macaddress))) (princ "\nYou have no permission to run this routine.") ) ( (progn (alert (strcat "Program will expire in " (itoa dif) " day" (if (= 1 dif) "." "s."))) t)) ) (progn (defun c:test ( ) (alert "Hello World!") (princ) ) ) ) ) (fix (getvar 'date)) 20190131 ) Edited January 7, 2019 by ssdd 1 Quote
Grrr Posted January 7, 2019 Posted January 7, 2019 25 minutes ago, Lee Mac said: The easiest way is to use the contiguous Julian date system, e.g.: Wow nice one, Lee! 33 minutes ago, Lee Mac said: Here, the Express Tools' dtoj function is only used to make it easier to specify the expiration date in the code - you can easily remove this reliance by specifying the expiration date as a Julian date directly in the code. Well I could also violate a bit Autodesk's terms of use, by appending the dtoj function definition into the expiration date wrapper. Ofcourse this doesn't sound like the right thing to do, but on the other hand the algorithm could be replicated (if its not already somewhere on the internet) and overall doesn't do any harm. 41 minutes ago, Lee Mac said: Note that this approach is still susceptible to the user changing the system clock - hence the suggestion to use my Internet Time function above. I remember we were doing such clock-adjusting back in the 90's in order to run some expired programs I find your LM:InternetTime great, but theres one thing to keep in mind, since when defined the subfunction remains "public" - It must be defined while running the expiration wrapper...else one could simple redefine your sub in order to bypass the checks like so: (defun LM:InternetTime ( format ) "01.01.99" ; "MO.DD.YY" ) Assuming the "bad" guy nailed the date format. Thats why I try to keep some stuff localised/private within a scope. Thanks Lee! 1 Quote
Lee Mac Posted January 7, 2019 Posted January 7, 2019 4 minutes ago, Grrr said: I find your LM:InternetTime great, but theres one thing to keep in mind, since when defined the subfunction remains "public" - It must be defined while running the expiration wrapper...else one could simple redefine your sub in order to bypass the checks like so: (defun LM:InternetTime ( format ) "01.01.99" ; "MO.DD.YY" ) Assuming the "bad" guy nailed the date format. Thats why I try to keep some stuff localised/private within a scope. If you were going to the trouble of implementing an trial license, you would of course compile the entire application to a separate-namespace vlx, meaning that the definition of the LM:InternetTime function could not be modified (or, rather, any definition would not affect the definition within the vlx namespace) as it resides outside of the document namespace. 1 Quote
Grrr Posted January 7, 2019 Posted January 7, 2019 9 minutes ago, Lee Mac said: you would of course compile the entire application to a separate-namespace vlx, meaning that the definition of the LM:InternetTime function could not be modified Oh wow seems like you already thought about this problem! ..and I've forgot to like your posts, so doing it right now! Quote
Lee Mac Posted January 7, 2019 Posted January 7, 2019 (edited) 40 minutes ago, ssdd said: Can I add a MacAddress? Indeed you can - consider a function such as the following: ;; MAC Addresses - Lee Mac ;; Returns a list of MAC Addresses for all installed network adaptors (defun LM:macaddresses ( / err qry srv wmi ) (if (setq wmi (vlax-create-object "wbemscripting.swbemlocator")) (progn (setq err (vl-catch-all-apply (function (lambda ( / rtn ) (setq srv (vlax-invoke wmi 'connectserver) qry (vlax-invoke srv 'execquery "select macaddress from win32_networkadapter where macaddress is not null") ) (vlax-for itm qry (setq rtn (cons (vlax-get itm 'macaddress) rtn))) ) ) ) ) (foreach obj (list qry srv wmi) (if (= 'vla-object (type obj)) (vlax-release-object obj) ) ) (if (vl-catch-all-error-p err) (prompt (vl-catch-all-error-message err)) err ) ) ) ) Edited January 7, 2019 by Lee Mac 1 Quote
Lee Mac Posted January 7, 2019 Posted January 7, 2019 13 minutes ago, Grrr said: Oh wow seems like you already thought about this problem! ..and I've forgot to like your posts, so doing it right now! Thanks! Quote
BIGAL Posted January 9, 2019 Posted January 9, 2019 Mac address PC Date Internet date Hard disk ID Regapp entry Autocad serial number Ping a web server Lots of methods available Oh yeah the phone call "the software is not working how do I fix ?" bottom line the end user tried to install on another computer without paying. 1 Quote
joemcanciller Posted January 9, 2019 Posted January 9, 2019 On 08/01/2019 at 02:16, Lee Mac said: Internet Time Thanks for the recommendation @BIGAL This is great sir @Lee Mac. Im also looking for this. Will it work even if the user has no internet connection? Quote
lido Posted January 9, 2019 Author Posted January 9, 2019 Thank all of you guys for your answers. Bellow, I will try to analyze the options. Please correct me if I'm wrong. If we were talking about the date, finding the current date is not enough. It is important to check the difference between the date of installing the program and the current one (<=30, in days). So the installing date must be saved. Options: 1. Use the registry key from the installation kit (NSIS, for example). 2. Create a file as hidden as possible, containing the date of the first launch of the program (with AutoLISP). In my opinion, both variants are weak and do not provide an effective protection system. Another approach is to not check the 30 days trial period. In this case the program can be used as usual, with some limitations until the user decides to purchase it. Now, with regard to how licensing can be done, at least at this time, the licensing option is offline. What data should be provided by the user? Let's see the vendor's options for licensing: 1. Identify hardware components: HDD serial number, BIOS data, MAC address, etc.: PROS: strong level of protection. CONS: replacing a hardware component will result in the license being canceled. 2. Using (Auto)CAD system variables: a) _PKSER: PROS: level of protection under (Auto)CAD. CONS: if (Auto)CAD is cracked, there is no control over the program. b) LOGINNAME: PROS: same as 2a above. CONS: same as 2 above; only the licensed user can use the program (case of multiple users for the same PC). 3. Any combination between option 1 and option 2 above. Concluding, let's say that I chose option 2a. Considering this option, in my opinion, the type of (Auto)CAD license should be checked: Standalone or Network (multi-users); the number of licenses of the program should be equal to the number of subscription seats, if the (Auto)CAD license type is Network. Under AutoCAD, the system variable _LINFO (undocumented) provide same information, as follow: - AutoCAD 2005 Network license: (getvar "_LINFO") return "ADLM Network License Granted. Connects: 1" - AutoCAD 2015 Standalone license: (getvar "_LINFO") return nil. I do not know if the system variable _LINFO exists and how it behaves under other CAD platforms. Questions: 1. The (Auto)CAD license type (Standalone or Network) can be found out otherwise than by using system variable _LINFO? 2. How to find the number of subscription seats using AutoLISP in case of (Auto)CAD Network license? Quote
Lee Mac Posted January 9, 2019 Posted January 9, 2019 2 hours ago, joemcanciller said: This is great sir @Lee Mac. Im also looking for this. Will it work even if the user has no internet connection? No, as the function retrieves the UTC time from the NIST time server (http://time.nist.gov). 1 Quote
maratovich Posted January 9, 2019 Posted January 9, 2019 lido If you need good protection, you need to use a ready-made solution. Write a request to this company: http://www.star-force.com/ They make protection on programs, and they make protection on Lisp. All your protection requirements they can do is not a problem. I have been using this protection for a long time. 1 Quote
lido Posted January 9, 2019 Author Posted January 9, 2019 @maratovich Thank you for guidance. I'll give it a try. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.