I'm using the core of the OnGuard functions.
I take the "HW" ID (dir timestamp), mix in a bit of version limit, program mode, and a few spare bits here and there and then use OnGuard's special key function and their scrambling function to generate (and decode) the registration key. It took me a few months (evening hours) to get this working. And then when I discovered the flaws in the hardware information that OnGuard was extracting, I had to revise it to use the timestamp. (sigh)
I do send the customer the registration key via email and they apply the key to unlock the program. The registration key is stored in an ini file, which the customer can see and edit. However, I think that the encoding and checking I do within the program is sufficient to protect the key against casual "attack".
Will this protect me 100%? No, but my target audience is not gaming, but rather a business app for folks with more work to do than spare time, so they are less likely to break it I (hope).