我怎样才能在.NET(C#或VB.NET)中以编程方式从registry中删除Windows产品密钥,以重现与使用/cpky
参数调用Microsoft合法slmgr.vbs脚本文件相同的效果… …请不要误解我的问题“删除”为“卸载”。 我只想删除与HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
: DigitalProductId
registry值中存储和编码的Windows的产品密钥对应的字节,因此产品密钥仍然安装,但第三方无法访问像ProduKey的应用程序。
我试图检查slmgr.vbs脚本文件(存储在C:\ Windows \ System32 ),并导致我到这个方法块:
Private Sub ClearPKeyFromRegistry() Dim objService On Error Resume Next set objService = GetServiceObject("Version") QuitIfError() objService.ClearProductKeyFromRegistry() QuitIfError() LineOut GetResource("L_MsgClearedPKey") End Sub
然而,我有点迷路,试图find并了解从哪里来,它做了什么GetServiceObject("Version")
调用,因为它似乎不是一个内置的VBS成员既不似乎是声明为脚本文件中的任何本地成员,并且我没有在MSDN文档/ VBS参考中find有关“GetServiceObject”的任何信息。
PS:请注意,我不会依靠slmgr.vbs文件的存在来解决这个问题,只需从C#中调用该脚本文件即可…
我只是扫描Windows文件系统的dll文件中的string“ ClearProductKeyFromRegistry ”,并发现它在sppwmi.dll文件中,但不幸的是,该function没有导出,然后通过对Google的简单研究,将其引导到ClearProductKeyFromRegistry方法 MSDN 上的SoftwareLicensingService类 ,但现在我不知道如何使用它。 我试图find有关如何在.NET中使用现有WMI提供程序的信息,但是我在WWW周围看到的所有信息都是关于如何实现/创buildWMI提供程序。
在同一个脚本中,您将找到GetServiceObject
方法(以及它使用的常量和全局变量)。 要找到它们,请在脚本中搜索以下术语:
- 函数GetServiceObject
- ServiceClass =
- g_objWMIService =
- L_MsgClearedPKey =
所以这只是跟踪代码和转换行的问题。 下面是我想到的完整的VBScript
版本的方法,它的依赖关系:
private const L_MsgClearedPKey = "Product key from registry cleared successfully." private const ServiceClass = "SoftwareLicensingService" g_strComputer = "." Set g_objWMIService = GetObject("winmgmts:\\" & g_strComputer & "\root\cimv2") Private Sub ClearPKeyFromRegistry() Dim objService On Error Resume Next set objService = GetServiceObject("Version") QuitIfError() objService.ClearProductKeyFromRegistry() QuitIfError() LineOut GetResource("L_MsgClearedPKey") End Sub Function GetServiceObject(strQuery) Dim objService Dim colServices On Error Resume Next Set colServices = g_objWMIService.ExecQuery("SELECT " & strQuery & " FROM " & ServiceClass) QuitIfError() For each objService in colServices QuitIfError() Exit For Next QuitIfError() set GetServiceObject = objService End Function
下一步是把这个减少到一个方法。 我继续去除了所有的QuitIfError()
调用和On Error Resume Next
,因为我们可以将我们的代码包装在try/catch
块中。 替换常量和全局变量,并结合方法后,我想出了这个:
Dim objService Dim colServices Dim g_objWMIService Set g_objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colServices = g_objWMIService.ExecQuery("SELECT Version FROM SoftwareLicensingService") For each objService in colServices Exit For Next objService.ClearProductKeyFromRegistry() LineOut "Product key from registry cleared successfully."
现在,由于我们使用的是WMI,我们需要引用system.management程序集并添加一个using:
using System.Management;
然后这只是一个转换的问题。 其中一些我以前没有做过,但它应该做的伎俩:
private static void ClearProductKeyFromRegistry() { const string query = "SELECT Version FROM SoftwareLicensingService"; var searcherProd = new ManagementObjectSearcher("\\\\.\\ROOT\\cimv2", query); var results = searcherProd.Get(); foreach (ManagementObject result in results) { result.InvokeMethod("ClearProductKeyFromRegistry", null); break; } Console.WriteLine("Product key from registry cleared successfully."); }
最后我发现了调用一个方法的方法,看这个例子 。 然后,我只是按照我在那里看到的,根据需要进行调整,所以我编写了这个在VB.NET中开发的有用的代码片段:
''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Removes the Windows product key from registry (to prevent unauthorized diffusion). ''' <para></para> ''' It does not uninstall the product key. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <remarks> ''' <see href="https://msdn.microsoft.com/en-us/library/cc534586(v=vs.85).aspx"/> ''' </remarks> ''' ---------------------------------------------------------------------------------------------------- ''' <exception cref="PlatformNotSupportedException"> ''' Windows 7 or newer is required to use this feature. ''' </exception> ''' ''' <exception cref="Exception"> ''' Unknown error occurred during the product key removal attempt. ''' </exception> ''' ---------------------------------------------------------------------------------------------------- <DebuggerStepThrough> Public Shared Sub RemoveWindowsProductKeyFromRegistry() ' If Not (WindowsUtils.IsWin7OrGreater) Then ' Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.") ' End If Using query As New ManagementObjectSearcher("SELECT * FROM SoftwareLicensingService") For Each product As ManagementObject In query.Get() Dim result As UInteger Try result = CUInt(product.InvokeMethod("ClearProductKeyFromRegistry", Nothing)) Catch ex As COMException Marshal.ThrowExceptionForHR(ex.HResult) Catch ex As Exception Throw End Try If (result <> 0UI) Then Throw New Exception("Unknown error occurred during the product key removal attempt.") End If Next product End Using End Sub
再加上这个其他代码片段,以编程方式安装产品密钥(它可以在我的机器上运行Windows 10,但可能需要更多的测试):
''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Installs a Windows product key. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <remarks> ''' <see href="https://msdn.microsoft.com/en-us/library/cc534590(v=vs.85).aspx"/> ''' </remarks> ''' ---------------------------------------------------------------------------------------------------- ''' <example> This is a code example. ''' <code> ''' Dim productKey As String = "YTMG3-N6DKC-DKB77-7M9GH-8HVXX" ''' InstallProductKey(productKey) ''' </code> ''' </example> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="productKey"> ''' The product key. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <exception cref="PlatformNotSupportedException"> ''' Windows 7 or newer is required to use this feature. ''' </exception> ''' ''' <exception cref="ArgumentNullException"> ''' productKey ''' </exception> ''' ''' <exception cref="Exception"> ''' The Software Licensing Service determined that the product key is invalid. ''' or ''' Unknown error occurred during the product key installation attempt. ''' </exception> ''' ---------------------------------------------------------------------------------------------------- <DebuggerStepThrough> Public Shared Sub InstallProductKey(ByVal productKey As String) ' If Not (WindowsUtils.IsWin7OrGreater) Then ' Throw New PlatformNotSupportedException("Windows 7 or newer is required to use this feature.") ' End If Using query As New ManagementObjectSearcher("SELECT * FROM SoftwareLicensingService") For Each product As ManagementObject In query.Get() Dim result As UInteger Try result = CUInt(product.InvokeMethod("InstallProductKey", {productKey})) product.InvokeMethod("RefreshLicenseStatus", Nothing) Catch ex As COMException When (ex.HResult = -1073418160) Throw New Exception("The Software Licensing Service determined that the product key is invalid.", ex) Catch ex As COMException Marshal.ThrowExceptionForHR(ex.HResult) Catch ex As Exception Throw End Try If (result <> 0UI) Then Throw New Exception("Unknown error occurred during the product key installation attempt.") End If Next product End Using End Sub