這裡介紹如何從電腦中找出 Windows 或 Office 的產品金鑰,讓重灌電腦時不必煩惱找不到序號。
Windows 用久了難免需要重灌,而安裝 Windows 與 Office 時都會需要輸入產品序號,但是如果序號不見了,就很令人頭痛了。
雖然我們可以用登錄編輯程式(regedit.exe
)來從登錄檔找出產品序號(路徑為 HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsNTCurrent VersionDigitalProductId
):
不過因為在登錄檔中所儲存的序號都是二進位的形式,不容易看出真正的序號,以下介紹幾種可以解讀序號的方式。
我們可以用 VBScript 撰寫一個讀取序號的指令稿,這樣的方式完全不需要下載與安裝任何軟體。將下面這段程式碼複製起來,儲存成一個 .vbs
檔(如 getkey.vbs
):
Set WshShell = CreateObject("WScript.Shell") MsgBox ConvertToKey(WshShell.RegRead("HKLMSOFTWAREMicrosoftWindows NTCurrentVersionDigitalProductId")) Function ConvertToKey(Key) Const KeyOffset = 52 i = 28 Chars = "BCDFGHJKMPQRTVWXY2346789" Do Cur = 0 x = 14 Do Cur = Cur * 256 Cur = Key(x + KeyOffset) + Cur Key(x + KeyOffset) = (Cur 24) And 255 Cur = Cur Mod 24 x = x -1 Loop While x >= 0 i = i -1 KeyOutput = Mid(Chars, Cur + 1, 1) & KeyOutput If (((29 - i) Mod 6) = 0) And (i <> -1) Then i = i -1 KeyOutput = "-" & KeyOutput End If Loop While i >= 0 ConvertToKey = KeyOutput End Function
建議將這個 getkey.vbs
檔案儲存在桌面上,然後用滑鼠點兩下執行,就會出現自己 Windows 的序號了。
在這個顯示序號的視窗上按下 Ctrl
+ c
就可以直接複製這組序號。
這裡有已經寫好的指令稿可以參考,這是適用於 Windows 7、Windows 10 與 Office 2010 – 2013 的指令稿:
Const HKLM = &H80000002 wscript.echo "View Product Keys | Microsoft Products" & vbCrLf 'Install Date Computer = "." Set objWMIService = GetObject("winmgmts:" & Computer & "rootcimv2") Set Obj = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem") dim InsDate For Each item in Obj InsDate = item.InstallDate ' Gather Operating System Information Caption = Item.Caption OSArchitecture = Item.OSArchitecture CSDVersion = Item.CSDVersion Version = Item.Version Next dim NewDate NewDate = mid(InsDate,9,2) & ":" & mid(InsDate,11,2) & ":" & mid(InsDate,13,2) NewDate = NewDate & " " & mid(InsDate,7,2) & "/" & mid(InsDate,5,2) & "/" & mid(InsDate,1,4) QueryWindowsProductKeys() wscript.echo 'vbCrLf & "Office Keys" & vbCrLf QueryOfficeProductKeys() Function DecodeProductKey(arrKey, intKeyOffset) If Not IsArray(arrKey) Then Exit Function intIsWin8 = BitShiftRight(arrKey(intKeyOffset + 14),3) And 1 arrKey(intKeyOffset + 14) = arrKey(intKeyOffset + 14) And 247 Or BitShiftLeft(intIsWin8 And 2,2) i = 24 strChars = "BCDFGHJKMPQRTVWXY2346789" strKeyOutput = "" While i > -1 intCur = 0 intX = 14 While intX > -1 intCur = BitShiftLeft(intCur,8) intCur = arrKey(intX + intKeyOffset) + intCur arrKey(intX + intKeyOffset) = Int(intCur / 24) intCur = intCur Mod 24 intX = intX - 1 Wend i = i - 1 strKeyOutput = Mid(strChars,intCur + 1,1) & strKeyOutput intLast = intCur Wend If intIsWin8 = 1 Then strKeyOutput = Mid(strKeyOutput,2,intLast) & "N" & Right(strKeyOutput,Len(strKeyOutput) - (intLast + 1)) End If strKeyGUIDOutput = Mid(strKeyOutput,1,5) & "-" & Mid(strKeyOutput,6,5) & "-" & Mid(strKeyOutput,11,5) & "-" & Mid(strKeyOutput,16,5) & "-" & Mid(strKeyOutput,21,5) DecodeProductKey = strKeyGUIDOutput End Function Function RegReadBinary(strRegPath,strRegValue) Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!.rootdefault:StdRegProv") objReg.GetBinaryValue HKLM,strRegPath,strRegValue,arrRegBinaryData RegReadBinary = arrRegBinaryData Set objReg = Nothing End Function Function BitShiftLeft(intValue,intShift) BitShiftLeft = intValue * 2 ^ intShift End Function Function BitShiftRight(intValue,intShift) BitShiftRight = Int(intValue / (2 ^ intShift)) End Function Function QueryOfficeProductKeys() strBaseKey = "SOFTWARE" strOfficeKey = strBaseKey & "MicrosoftOffice" Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!.rootdefault:StdRegProv") objReg.EnumKey HKLM, strOfficeKey, arrOfficeVersionSubKeys intProductCount = 1 If IsArray(arrOfficeVersionSubKeys) Then For Each strOfficeVersionKey In arrOfficeVersionSubKeys Select Case strOfficeVersionKey Case "11.0" CheckOfficeKey strOfficeKey & "11.0Registration",52,intProductCount Case "12.0" CheckOfficeKey strOfficeKey & "12.0Registration",52,intProductCount Case "14.0" CheckOfficeKey strOfficeKey & "14.0Registration",808,intProductCount Case "15.0" CheckOfficeKey strOfficeKey & "15.0Registration",808,intProductCount End Select Next End If strBaseKey = "SOFTWAREWow6432Node" strOfficeKey = strBaseKey & "MicrosoftOffice" Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!.rootdefault:StdRegProv") objReg.EnumKey HKLM, strOfficeKey, arrOfficeVersionSubKeys intProductCount = 1 If IsArray(arrOfficeVersionSubKeys) Then For Each strOfficeVersionKey In arrOfficeVersionSubKeys Select Case strOfficeVersionKey Case "11.0" CheckOfficeKey strOfficeKey & "11.0Registration",52,intProductCount Case "12.0" CheckOfficeKey strOfficeKey & "12.0Registration",52,intProductCount Case "14.0" CheckOfficeKey strOfficeKey & "14.0Registration",808,intProductCount Case "15.0" CheckOfficeKey strOfficeKey & "15.0Registration",808,intProductCount End Select Next End If End Function 'Office Product Key Sub CheckOfficeKey(strRegPath,intKeyOffset,intProductCount) Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!.rootdefault:StdRegProv") objReg.EnumKey HKLM, strRegPath, arrOfficeRegistrations If IsArray(arrOfficeRegistrations) Then For Each strOfficeRegistration In arrOfficeRegistrations objReg.GetStringValue HKLM,strRegPath & "" & strOfficeRegistration,"ConvertToEdition",strOfficeEdition objReg.GetBinaryValue HKLM,strRegPath & "" & strOfficeRegistration,"DigitalProductID",arrProductID If strOfficeEdition <> "" And IsArray(arrProductID) Then WriteData "Product", strOfficeEdition WriteData "Key", DecodeProductKey(arrProductID,intKeyOffset) & vbCrLf intProductCount = intProductCount + 1 End If Next End If End Sub 'Windows Product Key Sub QueryWindowsProductKeys() strWinKey = CheckWindowsKey("SOFTWAREMicrosoftWindows NTCurrentVersion","DigitalProductId",52) If strWinKey <> "" Then wscript.echo "Product: " & Caption & Version & " (" & OSArchitecture & ")" wscript.echo "Installation Date: " & NewDate WriteData "Key", strWinKey Exit Sub End If strWinKey = CheckWindowsKey("SOFTWAREMicrosoftWindows NTCurrentVersion","DigitalProductId4",808) If strWinKey <> "" Then wscript.echo "Product: " & Caption & Version & " (" & OSArchitecture & ")" wscript.echo "Installation Date: " & NewDate WriteData "Key", strWinKey Exit Sub End If strWinKey = CheckWindowsKey("SOFTWAREMicrosoftWindows NTCurrentVersionDefaultProductKey","DigitalProductId",52) If strWinKey <> "" Then wscript.echo "Product: " & Caption & Version & " (" & OSArchitecture & ")" wscript.echo "Installation Date: " & NewDate WriteData "Key", strWinKey Exit Sub End If strWinKey = CheckWindowsKey("SOFTWAREMicrosoftWindows NTCurrentVersionDefaultProductKey","DigitalProductId4",808) If strWinKey <> "" Then wscript.echo "Product: " & Caption & Version & " (" & OSArchitecture & ")" wscript.echo "Installation Date: " & NewDate WriteData "Key", strWinKey Exit Sub End If End Sub Function CheckWindowsKey(strRegPath,strRegValue,intKeyOffset) strWinKey = DecodeProductKey(RegReadBinary(strRegPath,strRegValue),intKeyOffset) If strWinKey <> "BBBBB-BBBBB-BBBBB-BBBBB-BBBBB" And strWinKey <> "" Then CheckWindowsKey = strWinKey Else CheckWindowsKey = "" End If End Function Function RegReadBinary(strRegPath,strRegValue) Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!.rootdefault:StdRegProv") objReg.GetBinaryValue HKLM,strRegPath,strRegValue,arrRegBinaryData RegReadBinary = arrRegBinaryData Set objReg = Nothing End Function Function OsArch() Set objShell = WScript.CreateObject("WScript.Shell") If objShell.ExpandEnvironmentStrings("%ProgramFiles(x86)%") = "%ProgramFiles(x86)%" Then OsArch = "x86" Else OsArch = "x64" End If Set objShell = Nothing End Function Sub WriteData(strProperty,strValue) WScript.Echo strProperty & ": " & Trim(strValue) 'Set objShell = CreateObject("WScript.Shell") 'strKey = "HKLMSOFTWARECentraStageCustom" & strProperty 'objShell.RegWrite strKey,Trim(strValue),"REG_SZ" 'Set objShell = Nothing End Sub
NirSoft 所提供的 ProduKey 是一個很好用的免費小工具,它可以將系統中的 Windows 與 Office 序號一次都抓取出來,非常方便,不過缺點是有些防毒軟體會將這個工具判斷為惡意程式,因為它會竊取您的序號。
從 NirSoft 網站上將 ProduKey 的壓縮檔下載回來,解壓縮之後直接就可以使用,不需要安裝。
ProduKey 除了可以取得目前系統的序號之外,也可以從其他的資料來源中尋找序號。
這個工具也非常實用,假設我們的 Windows 系統出了問題,無法正常開機的時候,我們就可以直接把硬碟拔下來,插在另外一台正常的電腦上,用這個工具將出問題系統的序號取出來。
參考資料:HTG