Getting a Windows Product Key

Hey guys,

As part of the scheme for generating my user’s license code, I grab their Windows license/product key. I use Christian’s SystemInformationMBS to perform this. Christian basically uses some APIs from Microsoft to get the key. Normally this works fine. But I have some users (and I think they are all Microsoft Volume Licensing installs) were the product key is not always reported back correctly. Instead, a string of B’s is returned. This completely screws up the license key that I generate?

Has anyone else seen anything like this and how do you work around it?

so there is a problem and you didn’t tell me? :frowning:

I’ve only just been able to verify it but I don’t think it’s your problem. It’s the WIndow’s APIs that aren’t reporting correctly. I’ve seen this with other things like the hard drive serial number. If you plug a thumb drive into the computer, Microsoft reports THAT as the hard drive serial number instead of the boot disk. I’ve verified this by using both your code as well as directly accessing the Windows APIs myself. So I don’t know if you can do anything about it…

:frowning:

[quote=204638:@Jon Ogden]Hey guys,

As part of the scheme for generating my user’s license code, I grab their Windows license/product key. I use Christian’s SystemInformationMBS to perform this. Christian basically uses some APIs from Microsoft to get the key. Normally this works fine. But I have some users (and I think they are all Microsoft Volume Licensing installs) were the product key is not always reported back correctly. Instead, a string of B’s is returned. This completely screws up the license key that I generate?

Has anyone else seen anything like this and how do you work around it?[/quote]

I guess this what you are looking for:

  // INFO:
  // http://library.wmifun.net/cimv2/win32_operatingsystem.html
  //
  //https://msdn.microsoft.com/en-us/library/aa389273%28v=vs.85%29.aspx
  
  Dim locator, objWMIService, objs, objProperty  As OLEOBJECT
  Dim nobjs as Integer
  
  //  Connect to WMI
  locator = new oleObject("WbemScripting.SWbemlocator", true)
  
  Dim wmiServiceParams(2) as variant
  wmiServiceParams(1) = "."
  wmiServiceParams(2) = "root\\cimv2"
  
  objWMIService= locator.invoke("ConnectServer", wmiServiceParams)
  
  // Run the WMI query
  objs = objWMIService.ExecQuery ("SELECT SerialNumber FROM Win32_OperatingSystem")
  
  nobjs = objs.count - 1
  
  //msgbox ("Number of Objects: " + str(nobjs +1))
  
  For i as integer = 0 to nobjs
    Dim stringData As String
    
    objProperty = objs.ItemIndex(i)
    // ItemIndex() is not supported in Windows XP only from Windows Vista and upwards
    
    stringData = "SerialNumber: " + objProperty.Value("SerialNumber") + EndOfLine 
    
    
    msgbox stringData
  Next
  
  locator = Nil
  
exception err as oleexception
  msgbox err.message

Thanks, John,

But is this the same thing basically that Christian’s code does. The issue is not needing code to get the product key. The issue is getting the product key on systems that are volume licensed and have a KMS (Key Management Server) key. That’s where I think the issue is…

If there is no fix for the BBBB, then maybe combine the key you get with / or use another attribute of the system.

So - if you get a valid key, use it.
If you don’t, grab the hard disc number, or the installation date (to the second) of your software, pad it to the same size as a windows key, and use that instead?
It may not be completely unique, but the odds are good…

That’s just it - I don’t know if there’s a workaround or if anyone else has experienced this…

But the issue is that sometimes it reports a valid key. Other times it reports BBBBB-BBBBB-BBBBB-BBBBB-BBBBB.

If it was consistent then I don’t have an issue really. But it’s not consistent. The user has the correct key identified on their machine when the license my software. Then they reboot, the key goes to BBBBB-BBBBB-BBBBB-BBBBB-BBBBB and then my key doesn’t work. Or vice versa.

So it’s making me not want to rely on the Windows product key. That’s fine, but I’ve already had to change my licenses once as I found that the Hard Drive Serial number API from Microsoft is buggy.

So if someone has a way to reliably grab the key data on a volume license system, that is what I’m hoping for…

well, maybe it’s a convention that microsoft puts this dummy key there for volume licensing.

You may need to use other values.
e.g. the creation timestamp of the C:\Windows folder or other unique values.
CPU Brand name for example.

What about use the Bios Serial Number. See link: https://forum.xojo.com/4447-shell-issue/p1#p30972

Yeah, that’s an item I use as well - I use multiple forms of ID. Unfortunately, it looks like I’ll need to build in yet another Windows license code check…

Ugh…

[quote=204652:@Christian Schmitz]well, maybe it’s a convention that microsoft puts this dummy key there for volume licensing.

[/quote]

Yeah but the rub is that it is not consistent. If it always returned the dummy values then that’s fine. But it doesn’t return consistent information. I wish I knew what triggers it reporting one key vs. the other.

[quote]
You may need to use other values.
e.g. the creation timestamp of the C:\Windows folder or other unique values.
CPU Brand name for example.[/quote]

Yeah, that’s what I’m thinking. I was hoping someone had experienced this and had the “Oh yeah, this is how you fix it” response…But no such luck.

Just a thought… Could it be reporting differently depending on whether it has a live network connection to the license server ?

That’s what I am wondering - it has to be something like that. But as I don’t have a system like that to test on, it’s impossible to tell…

What if you call it a second time if your get the BBBB string? I’ve got couple of other Windows API calls that I use in which I receive garbage on the first call and good values on the second call immediately after.

BTW - that’s not mine, it was provided by our MSDN liaison when I first ran into the problem in C under VS6 a while back and seems to still exist.

From what I understand, you just need that as part of the calculus of the license number.

What about, if you encounter the BBBB, using SQLDate and/or Microseconds as data ?