I run a software company that has dealt with this issue for nearly 20 years. As both a developer and a business owner, I'd like to first encourage you to broaden your goals a bit. For example, it is simply a mistake to define your problem as "preventing piracy." Your goal should be to maximize revenue.
With that being said, there are some people who simply will never buy your software but who may make fairly significant efforts to get it for free. It isn't "fair" that they get a free copy but placing a lot of resources into the effort to prevent it is largely a waste of time. Indeed, these folks often end up "going legit" simply to get on our update list, to get support or because their business evolves to the point where they can now afford our license. In these cases, the original piracy ends up enhancing our revenue.
So, how do we license?
We generate a random license number with each new install (a number between 10K and 99K does nicely). We then have an algorithm for generating a matching number (anything non-trivial will do). We use a random number, by the way, so that any attempt reinstall on another computer results in different license/match numbers.
Next, we ask users to call us on the phone to get the matching number for their license (this is important). The software looks at the matching number they enter and compares it to the matching value generated on the user's side. If there is a match, the software is fully activated.
I say that having them phone us is important because we use that as an opportunity to talk with them about their setup, answer any questions, and let them know they are dealing with real people. Very few people have the nerve to try calling and impersonating another company (we look them up and compare their information to our purchase database). Note that our package runs nearly $2K so phone calls are reasonable. If your package costs less and has higher volume, you could do this via email. Finally, we use the call-in to tell users how to get upgrades and technical support with their new license.
Finally, we store the key in the application's database (a locally-installed MSDE/SQL Express database) so that any attempt to copy the app will A) be non-trivial and B) bring over a lot of data specific to the organization that first bought the legitimate version (making them less likely to share). The licensing key is encrypted and "split" into two different keys that are kept in two different tables. Thus, a simple "find the key and enter it in the pirated version" will not work.
The bottom line? When you make the entire package more than just the software, build in a few basic protective mechanisms, and introduce the human element, you should see that you don't need the expense and trouble of a dongle to maximize revenue.