如何從電腦中找出 Windows 或 Office 的產品金鑰

這裡介紹如何從電腦中找出 Windows 或 Office 的產品金鑰,讓重灌電腦時不必煩惱找不到序號。

Windows 用久了難免需要重灌,而安裝 Windows 與 Office 時都會需要輸入產品序號,但是如果序號不見了,就很令人頭痛了。

雖然我們可以用登錄編輯程式(regedit.exe)來從登錄檔找出產品序號(路徑為 HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\Current Version\DigitalProductId):

regedit-1

不過因為在登錄檔中所儲存的序號都是二進位的形式,不容易看出真正的序號,以下介紹幾種可以解讀序號的方式。

使用 VBScript 讀取 Windows 序號

我們可以用 VBScript 撰寫一個讀取序號的指令稿,這樣的方式完全不需要下載與安裝任何軟體。將下面這段程式碼複製起來,儲存成一個 .vbs 檔(如 getkey.vbs):

Set WshShell = CreateObject("WScript.Shell")
MsgBox ConvertToKey(WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"))

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 的序號了。

windows-serial-key

在這個顯示序號的視窗上按下 Ctrl + c 就可以直接複製這組序號。

使用 VBScript 讀取 Office 序號

這裡有已經寫好的指令稿可以參考,這是適用於 Windows 7 與 Office 2010 – 2013 的指令稿:

Const HKLM = &H80000002

wscript.echo "View Product Keys | Microsoft Products" & vbCrLf

'Install Date 
Computer = "."
Set objWMIService = GetObject("winmgmts:\\" & Computer & "\root\cimv2")
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}!\\.\root\default: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 & "Microsoft\Office"
        Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default: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.0\Registration",52,intProductCount
                    Case "12.0"
                        CheckOfficeKey strOfficeKey & "\12.0\Registration",52,intProductCount
                    Case "14.0"
                        CheckOfficeKey strOfficeKey & "\14.0\Registration",808,intProductCount
                    Case "15.0"
                        CheckOfficeKey strOfficeKey & "\15.0\Registration",808,intProductCount
                End Select
            Next
        End If

        strBaseKey = "SOFTWARE\Wow6432Node\"

        strOfficeKey = strBaseKey & "Microsoft\Office"
        Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default: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.0\Registration",52,intProductCount
                    Case "12.0"
                        CheckOfficeKey strOfficeKey & "\12.0\Registration",52,intProductCount
                    Case "14.0"
                        CheckOfficeKey strOfficeKey & "\14.0\Registration",808,intProductCount
                    Case "15.0"
                        CheckOfficeKey strOfficeKey & "\15.0\Registration",808,intProductCount
                End Select
            Next
        End If
End Function

'Office Product Key
Sub CheckOfficeKey(strRegPath,intKeyOffset,intProductCount)

    Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default: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("SOFTWARE\Microsoft\Windows NT\CurrentVersion","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("SOFTWARE\Microsoft\Windows NT\CurrentVersion","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("SOFTWARE\Microsoft\Windows NT\CurrentVersion\DefaultProductKey","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("SOFTWARE\Microsoft\Windows NT\CurrentVersion\DefaultProductKey","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}!\\.\root\default: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 = "HKLM\SOFTWARE\CentraStage\Custom\" & strProperty
    'objShell.RegWrite strKey,Trim(strValue),"REG_SZ"
    'Set objShell = Nothing

End Sub

ProduKey

NirSoft 所提供的 ProduKey 是一個很好用的免費小工具,它可以將系統中的 Windows 與 Office 序號一次都抓取出來,非常方便,不過缺點是有些防毒軟體會將這個工具判斷為惡意程式,因為它會竊取您的序號。

名稱:ProduKey
網址:www.nirsoft.net

從 NirSoft 網站上將 ProduKey 的壓縮檔下載回來,解壓縮之後直接就可以使用,不需要安裝。

nirsofts-produkey

ProduKey 除了可以取得目前系統的序號之外,也可以從其他的資料來源中尋找序號。

nirsofts-produkey-source

這個工具也非常實用,假設我們的 Windows 系統出了問題,無法正常開機的時候,我們就可以直接把硬碟拔下來,插在另外一台正常的電腦上,用這個工具將出問題系統的序號取出來。

參考資料:HTG

Windows

12 Comments

  1. Danny

    你好

    為什麼軟件找出的key和VBScript找的key有不同?例windows

    • G. T. Wang

      我試的結果是一樣的,如果您的結果不一樣,那就要看看您的電腦上面的狀況了,沒有看到實際的問題,大概也很難判斷是為什麼。

      • Danny

        我發現原來軟件找出key和internet explorer的是一樣的!windows (bios oem key)都是,三個都是同一樣的key,這是什麼情況?

        • G. T. Wang

          有可能是軟體的 bug,如果真的要 debug,可能就要用登錄編輯程式(regedit.exe)直接去看二進位的機碼了。

          • Danny

            用VBScript就可以讀取嗎?謝謝你~

          • G. T. Wang

            VBScript 當然也是可以,不過程式就要自己寫了,這個難度頗高,如果不是駭客等級的人,建議上 Google 找找看有沒有別的工具可以用。

  2. kui

    那有VBScript讀取office的程式碼嗎?

  3. SHUANG KUEI LIU

    這組VB真是好用~~
    感謝版主詳盡的圖文解說 & 資訊收集~
    無私分享~~3Q ~~

  4. SKY

    謝謝你的幫助!

  5. ha

    这个可以查看office2013的吗?

  6. 逸名

    老師,
    本人的電腦 DELL XPS 8500 WIN 8 最近出了問題,
    微軟用入侵程式把本人的 WIN 8 升級為 WIN 10, 後來不知怎的死了機, 當重裝時要入KEY, 可是當問DELL支援時說KEY在底板, 用坊間的rweverything程式也找不到[ACPI](找到) -> [MSDM](找不到)(更加找不到KEY了)。
    找過DELL及微軟都不願意幫忙,DELL說KEY在底板, 非要付費才幫忙找。
    但WIN 8已經是買了的, 當時沒有收到任何 文字記錄的KEY。
    請問 win 8 又怎樣找出bios裏的key呢?

Leave a Reply