Resources for making a commercial Windows app?

Most of the apps I’ve built have been for in-house use only so I’ve never had to consider any issues involving selling software. But one I’m working on now would be of interest to people who use the film scanning machine that we use. The market isn’t huge - about 200 of them in the wild, I think, maybe a bit more. But it’s a useful enough tool that I could see most of those people buying this.

I know nothing of selling software: keeping it from being pirated, making sure licenses work on only one seat, etc.

What I want to avoid is a support and management nightmare (like having to fuss with people’s license keys all the time, etc). I don’t want it to be subscription based - instead just a simple license key that’s only usable on one seat at a time. Programming is not my main job, film scanning is. But I see a market here and if it’s worth it to sell this, why not?

Is there something that’s more or less frictionless for the end user, and easy to just drop into a Xojo app? What about selling windows apps? I use the mac app store all the time, but I don’t think I’ve ever used an equivalent store on Windows, I just get it from the developer and pay them for the license. How does it work on that side? With a license server, what happens if I stop developing the app - I would want the user to be able to continue to use what they paid for even if I’m no longer actively updating or supporting it.

This app would be Windows-only.

Explain to me like I’m 5.

Take a look at this from @Tim_Parnell

1 Like

What hardware?

For 200 possible customers, I’d not bother with licencing, and (assuming your selling price is significant) probably brand individual copies with their company name/logo to dissuade copying rather than prevent.
There are hardware dongle solutions but these can be expensive.

Over many years, I have prevented copying of my software using a custom serial number system. This has minimised piracy, but as each year goes by, the number of requests for replacement software/lost serial numbers is growing. (Probably still 20000 active users out there)
When I ‘shut the shop’ this will eventually cause issues for those who break/change their machines over time, and it worries me.
Because ‘continue to use’ could extend to ‘use on any new machine they ever buy’, and frankly, on a Mac that’s an impossible dream.
Apple seem to delight in changing things to enforce obsolecence.
On a Mac at least, the best you can achieve is ‘will continue to work on the machine and OS you were using when you purchased, and maybe one or two upgrades’.
Windows has much better backward compatibility.

4 Likes

I would do a simple scheme where the license shows the name of the client on screen at startup, so you would put a little pressure for people to not give away the key.

And the license key is kind of a hash or digital signature.

We have RegistrationEngineMBS module in MBS Xojo Util Plugin.
Or check ECKeyMBS class for making a signature.

2 Likes

Create License Keys (on your side):

Function GenerateLicenseKey(buyerName As String) As String
  Var secretKey As String = "MySuperSecretKey123" // never share this
  Var baseString As String = buyerName.Trim + secretKey

  // SHA1 creates a 40-character hash
  Var hash As String = Crypto.Hash(baseString, Crypto.HashAlgorithms.SHA1)

  // Optionally format for readability
  Return Uppercase(Mid(hash, 1, 5) + "-" + Mid(hash, 6, 5) + "-" + Mid(hash, 11, 5))
End Function

Validate the License Key (In Your App)

Function IsLicenseValid(buyerName As String, licenseKey As String) As Boolean
  Var expectedKey As String = GenerateLicenseKey(buyerName)
  Return licenseKey.Trim.Uppercase = expectedKey
End Function

[Optional] Lock the License to a Machine

Function GetMachineID() As String
  // Try to uniquely identify the machine
  Var info As String = SystemInformation.ComputerName + SystemInformation.Username
  Return Crypto.Hash(info, Crypto.HashAlgorithms.SHA1)
End Function

When generating the license for the customer, you’d need their machineID.
You can build a tiny tool for them that gives you that.
Then change your GenerateLicenseKey() like this:

Function GenerateLicenseKey(buyerName As String, machineID As String) As String
  Var secretKey As String = "MySuperSecretKey123"
  Var baseString As String = buyerName.Trim + machineID + secretKey
  Var hash As String = Crypto.Hash(baseString, Crypto.HashAlgorithms.SHA1)
  Return Uppercase(Mid(hash, 1, 5) + "-" + Mid(hash, 6, 5) + "-" + Mid(hash, 11, 5))
End Function

Example Usage:

Var buyerName As String = "Alice Smith"
Var licenseKey As String = "F3A2C-1AB34-9EDCC"

If IsLicenseValid(buyerName, licenseKey) Then
  MessageBox("Thank you! License activated.")
Else
  MessageBox("Invalid license key.")
End If

Feature This Setup
Offline activation :white_check_mark: Yes
Simple for user :white_check_mark: Yes
Tied to user :white_check_mark: Yes
Tied to machine :counterclockwise_arrows_button: Optional
Hard to crack :white_check_mark: (as long as you keep the secret secret)
3 Likes

From Claude about your text :wink:


Yes, this text appears to be generated by an AI assistant. Based on the writing style, structure, and formatting, it looks like it could be from several AI systems, but I cannot definitively identify which specific AI created it.

Here are the indicators that suggest AI generation:

Typical AI characteristics present:

  • Clear, tutorial-like structure with step-by-step explanations
  • Code examples with explanatory comments
  • Consistent formatting and organization
  • The table at the end summarizing features
  • Professional but accessible tone
  • Complete working examples with variable names like “Alice Smith”

Programming language note: The code is written in what appears to be Xojo (formerly REALbasic), which is evident from the syntax like Var, As String, Mid() function, and SystemInformation class usage.

The content itself is technically sound - it demonstrates a basic license key generation system using SHA1 hashing, though it should be noted that SHA1 is now considered cryptographically weak for security purposes.

Without more context or distinctive markers, I cannot pinpoint the exact AI system that generated this, as many modern AI assistants (including Claude, ChatGPT, and others) could produce similar technical content with this level of organization and clarity.

How does this help the questioner?

BTW: Since I’m not at my development computer, I’ve taken the liberty of using an AI assistant… I think this is something we’ll have to get used to, whether we like it or not. For a brief moment, I considered adding “Made with the Help of Claude Sonnet 4,” but I consciously decided against it.

And yes, you can always do better. But with 200+/- potential customers, I wouldn’t invest too much work.

3 Likes

Seriously, 99 out 100 questions asked here at Xojo Forum, Claude can solve it for you in seconds. :slight_smile:

2 Likes

It’s a Lasergraphics film scanner. I’m not doing anything that interfaces with the scanner itself. Instead, this app would manipulate/move around an XML file. Their app looks for this specifically named XML file and pulls some info from it. The end user can edit that, but it’s a pain to do it manually and to manage versions of that file, so I’m making a GUI to allow you to make the changes visually, then save a library of these files that you can call up as needed. My app would swap out the default XML file for the one you choose. So, that’s the only reason it needs to be on the same machine.

Thanks for the suggestions. I like Sascha’s/Claude’s arrangement. It seems simple enough.

Right now I’m guessing there are about 200 users. It could be a bit more or less than that. I really don’t have any numbers. My guess is that they might sell a few dozen machines per year, based on the number of installed machines I know about, but again I don’t really know for sure.

Tying the license to the machine would mean multiple sales to facilities that have multiple scanners, so that’s definitely something I’d want to do. And as I mentioned earlier, unless you really know what you’re doing, you sort of need the app on the machine, to manage all the files it creates. It’s not going to be a high priced app or a big money maker. I’m thinking $129 for a one-time permanent license for one machine.

I’m already making this app for us to use in-house, but it’s useful enough that if I can sell it to others and make their lives easier, then why not? At the same time I don’t want to make this a major headache for myself, because again, software dev isn’t my business and this isn’t going to make a ton of money, just a little extra.

Back in the day, I remember shareware apps using Digital River, to handle the payment and licensing, in order to automate it. Is there something like that still? They’re gone, as far as I know, but because these machines are sold worldwide, having it automated would make it easier for an end user to get it up and running more quickly.

You can use my TPLM system mentioned above to listen for payment notifications from either FastSpring or Stripe. My DRM system is everything in between payment and the user entering a key into your app. You just set some options in the control panel, download a preconfigured project, and drag and drop a module into your Xojo project.

If you were asking for a payment gateway that also offers a DRM, Paddle does but not for Xojo apps. LemonSqueezy has an always-online API you can lookup keys in, but you had specifically asked for offline functionality.

TPLM can operate offline, but we can discuss specifics privately should you wish to explore my system.

Thanks. Many of these scanners are in facilities where the PC controlling the scanner is airgapped from the internet, so being able to do it on a separate internet-connected machine is a requirement for some users. In fact, I’d bet (and certainly hope) that nobody is using their scanner on a machine where they are also checking their email, so it would be more the norm than the exception, to have to manually enter a key.

If the systems are air-gapped, manually entering a serial number isn’t useful - there would be no way to detect if the serial number is being used on multiple machines.

I see two possible approaches.

First, your software processes XML files that are associated with a single piece of machinery. I would think to look if the XML file contains any identifying information - for example, a unique ID of the machine itself, or an identifier associated with another piece of software that is used with it. You could link your license key scheme to only work with that specific install of hardware/software.

Second, have a two-part activation process that is time dependent. The user installs your software and is presented with an activation screen. On their phone or some other internet-connected device, they go to your website and type in their license code plus the activation code displayed on the screen; in response, they get an activation key that they type into the desktop app. This is validated via an algorithm that is some hash of the license code, the activation key, and the time/date; they might have 15 minutes to type it in before it expires, for example. This lets you track the usage of each license key and simply deny them activation keys once they’ve used the license.

There could also be a deactivation process: the desktop software presents a deactivation key on the screen, which is typed in to the website and releases that license for use. However, keep in mind that a simple disk image backup/restore of the desktop system would defeat this deactivation scheme.

Would this not address most of that issue (using the optional machine identifier as part of the process)?

Of course someone could lie and say they “moved to another machine” and if there’s no checking of the license against a license server on application launch, or the machine is airgapped, then there’s no way to know they’re cheating. But it’s unlikely in this scenario. The PC is part of a turnkey system, and you can’t just run the scanner on any machine you want. There are multiple PCIe cards installed for things like the camera and communications with the machine, so you don’t just move it from one to the other. And because these are between $50,000 and $300,000 scanners, anyone with multiple machines isn’t likely to break a sweat over a ~$100 license per machine.

I could also keep track of the machine IDs to see if a customer is generating too many requests with different machines. If the license key is emailed (and only to the original purchaser’s address), that might make someone pause before sharing. I don’t expect I’ll be able to stop all instances of cheating, but I don’t think there will be that many to begin with. I just want to make sure there’s enough friction there to make it not worth trying.

In theory, you could run the app on a machine that’s not connected to a scanner, just to generate the XML files, and not use the file management functions, but management of those files is half the reason to buy this app. I could prevent using it on a non-scanner PC by looking to see if the scanner’s application is installed. If I recall, that app won’t even install if you don’t already have all the necessary PCIe cards and drivers installed and configured first, and that’s something that’s done at the factory, not by the end user.

Yeah, I like the idea of piggy-backing your licensing on top of the hardware-specific software. I wonder if PCI cards have UUIDs that you could hook into. MAC addresses on network cards are a go-to for this question - and if the scanner connects to the computer via Ethernet, that’s a pretty solid way of doing it.

I’d be hesitant to look for specific hardware because over the past 15 years or so, they’ve changed quite a bit of that, as the scanner resolutions and speeds have increased, different cameras were introduced, etc. The constant seems to be the app and its basic structure. I’d really be looking to see if some folder or file is present and rejecting the machine if not.

The same application is used for the $50k scanner as the $300k scanner so it’s the common denominator.