My aim is to make a GUI, then by using deploytool to make an exe file from it.
Since I don't want the user to be able to use it for ever I want to make it as a trial version meaning that it will work only for a certain time.
I thought maybe by somehow connecting to the user's computer clock and date, and using the code for a time limit, but I found some problems it this logic.
Any ideas, how it can be done?
Using the computer's clock seems a reasonable way to go. Sure, the user than thwart that by changing the clock, but this will most likely create sufficient inconvenience that they rather pay the reasonable price of the software.
Simply put the following inside the OpeningFcn of your GUI
expiryDate = '2012-12-31';
if now > datenum(expiryDate)
h = errordlg('please upgrade to a full license');
uiwait(h)
return %# or throw an error
end
Related
I'm considering using Matlab Compiler to distribute software for a price. I'm investigating (very) simple methods to discourage re-distribution without annoying users. Any recommendations?
One thought is to email a user a license key and have them input this during the installation process to be verified on a license server. If the key matches what is on the server, the installation proceeds as usual, otherwise, a warning message is shown to inform the user to purchase another license. However, this method requires a specified function to run only during the installation process, and not thereafter (so as not to annoy the user). Is this possible using Matlab Compiler or otherwise?
I suppose I could create a file on the user's disk that the program looks for when it starts (if it exists, then it is not being run for the first time), but if the user copies the whole directory, that file would get copied too.
In order to create an effective licensing system, you have to link it to one or more properties of a user machine (MAC address, OS ID, hard disk serial numbers, CPU serial numbers, etc...).
If you don't to this, you are just going to release licenses that can be transferred from one user to another. If one user decides to spread his license file worldwide, you are doomed because everyone could potentially take that license file and use it to unlock your application.
But if you link your license files to one or more properties of a user machine, as mentioned above, you must be able to obtain these properties either:
before the user decides to buy your application;
when the user activates his license.
First Scenario
You release your software as a trial. When it is started for the first time, you set an expiration date in the registry or in a file well hidden somewhere. You check against the expiration date when the application starts and, once it is reached, you throw an error and you don't let the used play with your application anymore.
Within the application, you create a Register Now button somewhere. When it is clicked, the application retrieves the machine properties and passes them to the web page / form that will be opened to let the user perform the payment. That page will be in charge to validate the machine properties, receive the payment and, finally, deliver a valid license code based on these properties.
Within the application, you must implement the same logics that allowed your form to create the license code, because you will need to use them in order to validate the code itself every time your application starts. A pseudo-code example:
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lc = GetLicenseCode();
if (~strcmp(sha1([mp1 mp2 mp3]),lc))
errordlg('Invalid license code!');
return;
end
This is the simplest path. But keep in mind that if one or more properties of the user machine change (because he changes a device or reinstalls his OS), his license will be invalidated and you will have to provide a customer assistance service that takes care of this kind of situations.
Second Scenario
This one is much harder. You will not be able to know the user's machine properties in advance. So your licensing system will work on a two-steps basis. You release a unique code (called LID for example) when the used purchases your application. Then, once the user inserts that it in your application, your application must send it back together with the machine properties. The final key (called LKey for example) is then computed and sent back to the user.
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lkey = GetLicenseKey();
if (~strcmp(sha1([mp1 mp2 mp3]),lkey))
errordlg('Invalid license code!');
return;
end
Machine Properties
The first solution has been provided to you through a comment: the MachineGuid value located in the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography. It's pretty solid. But it will only work on Windows machines. Use winqueryreg to access the registry.
Another good alternative is the Window Domain Controller Security ID, which is another machine-specific unique identifier. You can retrieve it using Java code within Matlab:
wdc_sid = com.sun.security.auth.module.NTSystem.getDomainSID();
or through the Windows registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership. The registry approach should be the one to use if you want to maintain a certain backward compatibility with old Matlab releases. Unfortunately, the Window Domain Controller Security ID is another identifier that is available only on machines that run under Windows.
If you want to adapt your licensing system to every possible OS and environment, you have to use a more generic approach, based on universally accessible hardware properties: MAC adresses, hard disk serials and such things. As far as I know, the most reliable property is the MAC address, because its uniqueness, althrough not granted, is almost certain and it's very unfrequent to change a network adapter (there are more chances to break an hard disk actually). Retrieve the MAC adresses of the machine network adapters using Java code as follows:
mac_addrs = '';
net_int = java.net.NetworkInterface.getNetworkInterfaces();
while (net_int.hasMoreElements)
mac_addr = net_int.nextElement.getHardwareAddress();
if (~isempty(mac_addr))
mac_addrs = [mac_addrs, '-', sprintf('%.2X',typecast(mac_addr,'uint8'))];
end
end
mac_addrs = mac_addrs(2:end);
The above computation produces a character array that represents the result of the concatenation of all the MAC addresses found on the machine. Again, for compatibility reasons, this may not work on old Matlab releases, so you have to use a much more complex approach, described here.
[EDIT]
This approach to retrieve the MAC address based on the underlying OS could be easier:
switch computer('arch')
case {'maci','maci64'}
[~,a]=system('ifconfig');
c=strfind(a,'en0');if ~isempty(c),a=a(c:end);end
c=strfind(a,'en1');if ~isempty(c),a=a(1:c-1);end
% find the mac address
b=strfind(a,'ether');
mac_add=a(1,b(1)+6:b(1)+22);
case {'win32','win64'}
[~,a]=system('getmac');b=strfind(a,'=');
mac_add=a(b(end)+1:b(end)+19);
case {'glnx86','glnxa64'}
[~,a]=system('ifconfig');b=strfind(a,'Ether');
mac_add=a(1,b(1)+17:b(1)+33);
otherwise,mac_add=[];
end
I found it in the comments of this article.
I need to use "Count Day" code for indicator.
It does work fine, but this indicator keeps previous day object till I restart MT4.
What is wrong below code?
if(day >= drowDays) {
break;}
Also you can see chart screenshot link.
You're not providing sufficient information to your problem :'(
With the limited info, what I can say is that you need to delete the graphical objects created for previous day.
Assuming your indicator will plot the latest line, then you MIGHT (again, this is a guess as there is not enough information of your code) be able to achieve it with the ObjectsDeleteAll() function at the start of your OnCalculate(). Obviously, this is not efficient, but is something you can think about.
I'm a student learning to use MATLAB. For an assignment, I have to create a simple state machine and collect some results. I'm used to using Verilog/Modelsim, and I'd like to collect data only when the state machine's output changes, which is not necessarily every time/sample period.
Right now I have a model that looks like this:
RequestChart ----> ResponseChart ----> Unit Delay Block --> (Back to RequestChart)
| |
------------------------> Mux --> "To Workspace" Sink Block
I've tried setting the sink block to save as "Array" format, but it only saves 51 values. I've tried setting it to "Timeseries", but it saves tons of zero values.
Can someone give me some suggestions? Like I said, MATLAB is new to me, please let me know if I need to clarify my question or provide more information.
Edit: Here's a screen capture of my model:
Generally Simulink will output a sample at every integration step. If you want to only output data when a particular event occurs -- in this case only when some data changes -- then do the following,
run the output of the state machine into a Detect Change block (from the Logic and Bit Operations library)
run that signal into the trigger port of a Triggered Subsystem.
run the output of the state machine into the data port of the Triggered Subsystem.
inside the triggered subsystem, run the data signal into a To Workspace block.
Data will only be saved at time point that the trigger occurs, i.e. when your data changes.
In your Simulink window, make sure the Relative Tolerance is small so that you can generate many more points in between your start and ending time. Click on the Simulation option at the top of the window, then click on Model Configuration Parameters.
From there, change the Relative Tolerance to something small... like 1e-10. After that, try running your simulation again. You should have a lot more points in your output array that you can now save.
For some load testing simulations, I'm looking at scripting with AHK 1.1. The issue is we have a client-server setup with multiple workstations so I'd really like to be able to trigger the same script (or even variations) to run on multiple PCs at once, to accurately simulate multiple users all hammering the system.
Even more useful would be to make sure the same test happens at exactly (within some tolerance) the same time, to check this doesn't cause problems.
What be would the best way to do this? Do it from within AHK itself, or use some separate remote-control tool to let me fire off scripts on PCs of my choosing?
With ahk you will need scripts acting as server and clients so both needs to be running no matter the method used...
As to the TCP/IP you can do this, you just need to find out if you have any usable/open posts your scripts can use...
I just helped an australian guy the other day setup a great working lot of server/client scripts
using the Socket Class by Bentschi looking something like this
Server:
;Server
#include Socket.ahk
myTcp := new SocketTCP()
myTcp.bind("addr_any", 54321)
myTcp.listen()
myTcp.onAccept := Func("OnTCPAccept")
return
OnTCPAccept(this)
{
newTcp := this.accept()
newTcp.onRecv := func("OnTCPRecv")
newTcp.sendText("Connected")
}
OnTCPRecv(this)
{
msgbox % this.recvText()
}
Client:
;Client
#include Socket.ahk
myTcp := new SocketTCP()
myTcp.connect("your servers A_IPAddress1", 54321) ; lokal
myTcp.onRecv := Func("OnTcpRecv")
return
OnTcpRecv(this)
{
ToolTip % this.RecvText()
}
But to use and or set something like this up you may need to know what ports are usable on the network or have the ability to change settings as needed.
The speed of the TCP/IP scripts are in the low milliseconds (under 20 on my network) so no real tolerance to speak of.
Hope it helps
As wrote Sidola you can check shared folder for some file or folder. You can use
IfExist command for it. Here is example:
Loop
{
IfExist, c:\a.txt
{
break
}
}
;code to execute if c:\a.txt exists comes below.
MsgBox, 1
Also you can add Sleep command to put less stress on hdd like for example in code below:
Loop
{
IfExist, c:\a.txt
{
break
}
Sleep, 1000
}
;code to execute if c:\a.txt exists comes below.
MsgBox, 1
Also, always use AutoHotkey and its documenatation from http://ahkscript.org/ (current uptodate version, new official website)! AutoHotkey and its documentation from autohotkey.com is outdated and you may have some problems using them!
I can't provide actual code, but there is a way to kind of inject a service into your LAN machines through the Admin$ share and remotely control it. This way AHK wouldn't need to run on the LAN computers all the time.
I don't know how exactly this could be done, but PsShutdown does it to hibernate LAN PCs which is normally impossible.
In case you actually manage to do it, it would be great if you could share it.
When I create a new quote from Epicor I would like to add an item from the parts form automatically.
I am trying to do this using the following ABL code which runs when 'GetNewQuoteHed' is called:
run Update.
run GetNewQuoteDtl.
run ChangePartNumMaster("Rod Tube").
ttQuoteDtl.OrderQty = 5.
run Update.
I am getting the error:
Index -1 is either negative or above rows count.
This error occurs for each line in my ABL code.
What am I doing wrong?
That's not the proper format for a 4GL error message (nor is it at all familiar) so I'd say it is an Epicor application message. Epicor support is probably your best bet. However... Just guessing but it sounds like you might need to somehow initialize the thing that you're updating.
Agree with #Tom, but i would also say try and isolate the error and see where the error is raised as soon as you find the point the error is actually raised it is normally much easier to figure out exactly what is going wrong and how to solve it.
Working between a 0 based and a 1 based system there can be issues with the 1st or last entry depending on which way you moving. As the index for 0 based systems starts at 0 and ends at n-1 where 1 based systems start at 1 and end at n.