|
I am working on a desktop software that I eventually hope to sell next year.
It's an end user application, not a business app. It will cost like $30, or free if you don't mind the built-in nagware on every save.
I plan to have my licensing follow the following algorithm:
1. First Run
a. find a UniqueID for this installation
b. ask the server to provide a license key for that UniqueID (providing relevant info)
c. save licence key as text file in application folder
2. Later Runs
a. Find the installation UniqueID
b. Match system UniqueID to licence key
My problem now is step a., how to Find Installation UniqueID ?
Idea 1.
One of the best candidate so far is to get a hard drive unique ID
Searching for a reliable hardware ID
Now, as some critics said, you have to license again if you change the hard drive.
However I am not sure how one could avoid licensing again on a new hardware / system.
Idea 2
Why bother with hard drive number, simply store a GUID generated on install, or first check and store in the Windows Registry.
Pretty much the same as idea 1 practically, as far as user experience is concerned though.
Other Ideas
Any better licensing model to suggest? or key generation method?
[EDIT]
Found something interesting in StackOverflow:
c# - What is a good unique PC identifier? - Stack Overflow
Which I can get with the following snippet:
static void Main(string[] args)
{
var key = RegistryKey.OpenBaseKey(
RegistryHive.LocalMachine,
Environment.Is64BitOperatingSystem
? RegistryView.Registry64
: RegistryView.Registry32);
using (var reg = key.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"))
{
var v = reg.GetValue("ProductId");
Console.WriteLine(v);
}
}
modified 13-Dec-18 9:35am.
|
|
|
|
|
This is rather not a C# question. You are still deciding how to setup your license model. Decide that first and then implement.
I have some experience of this from my last employment where we sold licenses for an application. Several times I was asked from customers to handle crashed computers or new computers. We also had another application witch had a different license system, I prefer the later system instead of handling all by yourself. I will describe both systems.
The first system (handling all by yourself):
* We used a combination of the hard drive's ID and MAC-address to generate the ID.
* We told the customer to specify the ID and we then returned the license.
* When there was a crashed computer or the license needed a move to another computer. We sold them a "license move" with some discount. The customer had to specify both the old ID and the ID to get a new license. (This is a risk: Because the customer might be lying and actually the old computer still runs. Therefore you have sold one license for a cheaper price).
Don't store the license in the Window's registry! Store it somewhere else. Not there!
The second system (handling by a service-provider):
We used the service "Solo-server" from "softwarekey.com" which provided us with a database where we stored everything for the licenses. In our program we access the database to check the license for that customer. They supply with an online login to the database in any web browser and from there we created and handled all licenses for our customers.
When a customer bought the program we generated a new license with ID and password. After that we mailed the ID and password to the customer. The customer then "installs" the license on there computer. Our program connected to the provider's service and checked ID and password.
When a customer had a computer crash or needed to move the license. They uninstalled the license and installed it on the new computer. Same license (ID and password) but different computer. Of course we could deactivate a license for a customer anytime, and as soon as the program connected to the provider's system it deactivated the program.
I prefer this system many many times more then the first model. It was so much easier and better performance.
The only downside was when the customer didn't had internet access, which is required. But the provider had a solution for that by using another computer with internet access to create a file with the license. The "license-file" was then needed to be transferred to the computer by any means. That was the customer's problem .
There is therefore a solution for offline handling. But if your customers can handle it online with internet access, it's a piece of cake.
|
|
|
|
|
I don't think that key would exist on Win XP / Vista / 8: does that raise an issue ?
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
modified 13-Dec-18 17:47pm.
|
|
|
|
|
Thanks Bill!
I was wondering about that exact same question!
Given that I only have access to Windows 10 machines I can't really answer it...
But... This StackOverflow post is from 2010, so this key must be quite prevalent on many editions of Windows!
But now that you put it explicitly out there, me think since my app is end user stuff and since (most likely?) Windows 10 is the most prevalent edition of Windows, or bound to be... I might just go with it...
Also I am thinking to use 2 IDs, this Windows one and that other one below (auto generated) so that should be fine!
My other custom ID code
public static Guid GetUniqueAppId()
{
var company = CoreServices.AssemblyCompany;
var product = CoreServices.AssemblyProduct;
var identifier = string.IsNullOrEmpty(company)
? $@"SOFTWARE\{product}"
: $@"SOFTWARE\{company}\{product}";
using (var key = Registry.CurrentUser.CreateSubKey(identifier))
{
var ID = "InstallId";
var value = key.GetValue(ID) as string;
if (string.IsNullOrWhiteSpace(value) || !Guid.TryParse(value, out var result))
{
result = Guid.NewGuid();
key.SetValue(ID, result.ToString());
}
return result;
}
}
|
|
|
|
|
No matter how you do it, someone will complain.
I've got one bit of software that uses who-knows-what, but EVERY time Windows updates, I have to reauthorize the software. I've no idea what they're using, but they're WRONG.
|
|
|
|
|
it's a cat ass trophee!
|
|
|
|
|
Hello guys ...(.wav) Format unCompressed Audio is Playing in My Project...but (.WAV) Format Compressed Audio is not Playing in My Project
|
|
|
|
|
How do you expect us to be able to help you when we have no idea what you project does, how it does it, or even what it does when it doesn't work?
Remember that we can't see your screen, access your HDD, or read your mind - we only get exactly what you type to work with, and that there are probably thousands of different ways you could be trying to do this!
Please, stop trying to type as little as possible and provide information - help us to help you!
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
OriginalGriff wrote: How do you expect us to be able to help you when we have no idea what you project does, how it does it, or even what it does when it doesn't work?
As it looks... neither has he
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
As a suggestion - get a different library.
Or if you wrote the code yourself then either implement the compressed spec or fix your code that is supposed to be doing that and is not.
|
|
|
|
|
Try to use different decoder.
Maybe something like this :
using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read))
{
var player = new SoundPlayer(new OggDecodeStream(file));
player.PlaySync();
}
Hope this help.
Regards
Toha
|
|
|
|
|
Dear Bro, Sis
I want to design form style with tab control by using Tab Control on DevComponent Reference, but when I click on tools and select control and then to drawing on my form,it have no anythings happens on my form.
So Bro, Sis can help me to use it step by step?
Thanks!
Phearum
|
|
|
|
|
1) Go here: DotNetBar Tutorials[^]
2) Click on "Working with New Tab Control"
3) Watch video
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
If you bought this over $1000 USD software package, and don't know how to drag-drop a Control into a Form and set its Properties, you should look for another type of work. If you didn't buy it, then you should not be using it.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Upvoted.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
|
We do not do your homework: it is set for a reason. It is there so that you think about what you have been told, and try to understand it. It is also there so that your tutor can identify areas where you are weak, and focus more attention on remedial action.
Even if we did, we have no idea what question your teacher has set, so we have no idea why you want to include a heap sort into existing K-means code.
The only way to do that would be: understand each bit of code, and think about what you are trying to achieve. Try it yourself, you may find it is not as difficult as you think! Just grabbing bits of code from the internet and slamming them together is like assuming you can use the wheels from any vehicle to replace the ones on your car: some will not fit on the hub (four bolts instead of five), some won't fit under the wheel arches as they are too wide, others won't fit because they are too tall. You need to look carefully at the car and at potential wheels in order to determine if they can be fitted and if so what you need to do to fit them.
A much better solution is to write your own code instead of trying to hand in somebody else's and risking plagiarism allegations...
If you meet a specific problem, then please ask about that and we will do our best to help. But we aren't going to do it all for you!
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
ok just tell me where to start just say 1 tip please
|
|
|
|
|
If you mean "tell me where to start to bolt these two together" then I already did:
Quote: The only way to do that would be: understand each bit of code, and think about what you are trying to achieve.
If you mean "how do I start to do it for myself?" then that's just the same as any other coding homework you have been given: read the question carefully, research the algorithms (which are not code) you need, write yourself a specification (so you know exactly what you are working towards), expand that to a design, and then code and test. I can't even see your homework question, so I can't be any more specific than that!
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hi guys,
I am working in something new and I would like to write a binary file with fields of different length, being it 2, 4, 8 bytes mostly.
I already get the desired conversion for doubles with
double dTest_max = 15.020245207;
byte[] bytesDouble_max = BitConverter.GetBytes(dTest_max);
Console.WriteLine("Hexa Double MAX (byte[]) = 0x" + BitConverter.ToString(bytesDouble_max).Replace("-", ""));
Using the same with the integer "312" gives me: output = 0x38010000
If I cast the int to long I do get my desired: output = 0x380100000000
But as the desired length of the parameter in the binary telegram is fixed by header (dynamic) I would like to avoid having to evaluate the respective length of the actual parameter to choose if I have to cast it or not.
Is there any hidden function / method in .Net that could do that?
I mean something like:
Console.WriteLine("0x"+int.ToString("X"));
Console.WriteLine("0x"+int.ToString("X12"));
But for the BitConverter?
I have already had a look to: BitConverter Class (System) | Microsoft Docs[^] and its overloads, but the "start" and "length" are only to be used if the data input is an array, and haven't seen anything to determine the length of the output
If not... I am already thinking to use workarounds like filling bytes[] with different fixed lengths and then replacing only the bytes given by the conversion.
Using int.ToString("X12") and the "reversing" it would do the job too, but I am not sure if that would be reliable enough for my use case.
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
No, there isn't - ToString is a presentation function, so it adds a lot of formatting so you can present your data in "user friendly" formats depending on how they need to view the data.
But an integer only has one size: 32 bits. And a long is always 64 bits - so BitConverter will always reflect that.
However, this might be of use to you: ByteArrayBuilder - a StringBuilder for Bytes[^]
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
OriginalGriff wrote: No, there isn't I already thought that, but dreaming is for free, isn't it?
Thanks for the link. I have had a fast a look and seems promising. Pity that you didn't find the time in 5 years to complete it as you said in the comment
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
modified 11-Dec-18 3:46am.
|
|
|
|
|
Quote: I'll think about it, and maybe add it when I have a little time. A little time ... a little time ... I need a time machine some days.
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Only in some days? For me would be the other way around, some days is when I don't need it.
I am starting to think about inventing the days of 30 hours. But I know for sure that a lot of people would be pissed off and try to kill me if I did
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
I know what you mean! Maybe I'll just edit the comment ...
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|