gpt4 book ai didi

c - 有没有办法在 Windows 7 上以编程方式激活 Windows

转载 作者:太空宇宙 更新时间:2023-11-04 08:10:00 24 4
gpt4 key购买 nike

我正在开展一个项目,我需要在 Windows 7 PC 上激活 Windows。我使用 Windows 软件许可 API 编写了以下代码。 MSDN 说下面使用的三个函数需要 Windows 8 或 Windows Server 2012,这表明这些函数在 Windows 7 上不可用。但是如果我在我的 C:\Windows\System32 中的 depends.exe 中打开 slc.dll Windows 7 机器,我执行 SLOpen 和 SLClose 函数。但不是 SLActivateProduct。

当我构建程序时出现链接器错误:

1>  main.cpp
1>main.obj : error LNK2019: unresolved external symbol _SLActivateProduct@28 referenced in function _main
1>activate_windows.exe : fatal error LNK1120: 1 unresolved externals

这在链接时是如何工作的?我认为这意味着 slc.lib(请参阅下面的代码)没有 SLActivateProduct 函数?

这个程序不需要用 C 语言编写,所以我可以从脚本中调用任何东西。任何人都知道在 Windows 7 上是否有任何方法可以做到这一点?它必须是一种可以通过运行脚本启动的编程方式。

代码如下:

#include <Windows.h>
#include <Slpublic.h>
#include <slerror.h>

#include <stdio.h>

// lib to use
#pragma comment(lib, "slc.lib")

int main() {

// slmgr.vbs has:
// private const WindowsAppId = "55c92734-d682-4d71-983e-d6ec3f16059f"
// Windows AppId for SLID: {55c92734-d682-4d71-983e-d6ec3f16059f} - this is a GUID
const SLID SLID_WINDOWS = {0x55c92734, 0xd682, 0x4d71, 0x98, 0x3e, 0xd6, 0xec, 0x3f, 0x16, 0x05, 0x9f};

HSLC hslc;
HRESULT hr = SLOpen(&hslc);
if (SUCCEEDED(hr))
{
// try to activate windows
hr = SLActivateProduct(hslc, &SLID_WINDOWS, 0, NULL, NULL, NULL, 0);
switch(hr) {
case E_INVALIDARG:
printf("SLActivateProduct - one or more arguments are not valid\n");
break;
case SL_E_PUBLISHING_LICENSE_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;
case SL_E_PKEY_NOT_INSTALLED:
printf("SLActivateProduct - The product key is not available\n");
break;
case SL_E_PRODUCT_SKU_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case S_OK:
printf("SLActivateProduct - returned S_OK\n");
break;
default:
printf("SLActivateProduct - unknown return code\n");
break;
}
hr=SLClose(hslc);
}
}

最佳答案

SLActivateProduct() 在 Windows 7 上根本不可用,即使您可以在编译时链接到它(显然您不能,因为您的 slc.lib 缺少该引用)。

但是,您可以使用 GetProcAddress() 在运行时动态加载 SLActivateProduct()。这将使您克服链接器错误(直到您更新开发环境)并允许您的代码至少在 Windows 8 及更高版本上运行。

仅供引用,slidefs.h 定义了一个 WINDOWS_SLID 常量,因此您无需在代码中手动定义它。

尝试更像这样的东西:

#include <Windows.h>
#include <Slpublic.h>
#include <slerror.h>
#include <sliddefs.h>

#include <stdio.h>

// lib to use
#pragma comment(lib, "slc.lib")

// if your version of Slpublic.h does not define these then uncomment this...
/*
typedef enum _tagSL_ACTIVATION_TYPE {
SL_ACTIVATION_TYPE_DEFAULT = 0,
SL_ACTIVATION_TYPE_ACTIVE_DIRECTORY = 1
} SL_ACTIVATION_TYPE;

typedef struct _tagSL_ACTIVATION_INFO_HEADER {
DWORD cbSize;
SL_ACTIVATION_TYPE type;
} SL_ACTIVATION_INFO_HEADER;
*/

typedef HRESULT WINAPI (*LPFN_SLActivateProduct)(HSLC, const SLID*, UINT, const PVOID, const SL_ACTIVATION_INFO_HEADER*, PCWSTR, WORD);

int main()
{
LPFN_SLActivateProduct lpSLActivateProduct = (LPFN_SLActivateProduct) GetProcAddress(GetModuleHandle(TEXT("slc.dll")), "SLActivateProduct");
if (!lpSLActivateProduct)
{
printf("SLActivateProduct - The product cannot be activated on this system\n");
return 0;
}

HSLC hslc;

HRESULT hr = SLOpen(&hslc);
if (FAILED(hr))
{
printf("SLOpen - unknown return code 0x%08X\n", hr);
return 0;
}

// try to activate windows
hr = lpSLActivateProduct(hslc, &WINDOWS_SLID, 0, NULL, NULL, NULL, 0);
switch(hr)
{
case E_INVALIDARG:
printf("SLActivateProduct - one or more arguments are not valid\n");
break;

case SL_E_PUBLISHING_LICENSE_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case SL_E_PKEY_NOT_INSTALLED:
printf("SLActivateProduct - The product key is not available\n");
break;

case SL_E_PRODUCT_SKU_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case S_OK:
printf("SLActivateProduct - returned S_OK\n");
break;

default:
printf("SLActivateProduct - unknown return code 0x%08X\n", hr);
break;
}

hr = SLClose(hslc);

return 0;
}

更新:毕竟 SLActivateProduct() IS 在 Windows 7 上可用。它只是位于 slcext.dll 而不是 slc.dll 中,如 MSDN 所说。您可以相应地调整 GetProcAddress() 调用:

LPFN_SLActivateProduct lpSLActivateProduct = (LPFN_SLActivateProduct) GetProcAddress(GetModuleHandle(TEXT("slc.dll")), "SLActivateProduct");
if (!lpSLActivateProduct)
{
// TODO: if SLCEXT.DLL is not already loaded, use LoadLibrary() instead of GetModuleHandle()...
lpSLActivateProduct = (LPFN_SLActivateProduct) GetProcAddress(GetModuleHandle(TEXT("slcext.dll")), "SLActivateProduct");
}
if (!lpSLActivateProduct)
{
printf("SLActivateProduct - The product cannot be activated on this system\n");
return 0;
}

更新:如果稍后,您更新到一个开发环境,其 slc.lib 不再缺少对 SLActivateProduct()< 的引用,您可以删除对 GetProcAddress() 的显式调用,而是使用链接器的 delay loaded DLLs feature .这允许您编写代码,就好像您是静态链接一样,但随后链接器会注入(inject)特殊代码,该代码将在运行时第一次调用 DLL 函数时为您调用 GetProcAddress()。这将允许您在“静态”调用该函数之前检查操作系统版本,从而允许您的应用程序仍然在较旧的 Windows 版本上运行,但仅在 Windows 7+ 上执行激活。

#include <Windows.h>
#include <Slpublic.h>
#include <slerror.h>
#include <sliddefs.h>

#include <stdio.h>

// lib to use
#pragma comment(lib, "slc.lib")

// if your version of Slpublic.h does not define these then uncomment this...
/*
typedef enum _tagSL_ACTIVATION_TYPE {
SL_ACTIVATION_TYPE_DEFAULT = 0,
SL_ACTIVATION_TYPE_ACTIVE_DIRECTORY = 1
} SL_ACTIVATION_TYPE;

typedef struct _tagSL_ACTIVATION_INFO_HEADER {
DWORD cbSize;
SL_ACTIVATION_TYPE type;
} SL_ACTIVATION_INFO_HEADER;
*/

int main()
{
OSVERSIONINFO osi = {0};
osi.dwOSVersionInfoSize = sizeof(osi).
GetVersionEx(&osi);

if ((osi.dwMajorVersion < 6) || ((osi.dwMajorVersion == 6) && (dwMinorVersion < 1)))
{
printf("SLActivateProduct - The product cannot be activated on this system\n");
return 0;
}

// alternatively:
/*
#include <VersionHelpers.h>

if (!IsWindows7OrGreater())
{
printf("SLActivateProduct - The product cannot be activated on this system\n");
return 0;
}
*/

HSLC hslc;

HRESULT hr = SLOpen(&hslc);
if (FAILED(hr))
{
printf("SLOpen - unknown return code 0x%08X\n", hr);
return 0;
}

// try to activate windows
hr = SLActivateProduct(hslc, &WINDOWS_SLID, 0, NULL, NULL, NULL, 0);
switch(hr)
{
case E_INVALIDARG:
printf("SLActivateProduct - one or more arguments are not valid\n");
break;

case SL_E_PUBLISHING_LICENSE_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case SL_E_PKEY_NOT_INSTALLED:
printf("SLActivateProduct - The product key is not available\n");
break;

case SL_E_PRODUCT_SKU_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case S_OK:
printf("SLActivateProduct - returned S_OK\n");
break;

default:
printf("SLActivateProduct - unknown return code 0x%08X\n", hr);
break;
}

hr = SLClose(hslc);

return 0;
}

但是,要解决 slc.dllslcext.dll 的问题,您可以使用 delay-load failure hook检测何时在 slc.dll 中找不到 SLActivateProduct(),然后从 slcext.dll 加载它。

事实上,这是首选选项,因为它还提供了另一个机会 - 它允许您完全删除操作系统版本检查!如果在任一 DLL 中均未找到 SLActivateProduct(),您可以改为返回指向自定义用户定义函数的指针。当代码调用 SLActivateProduct() 时,如果它调用该函数,它可以简单地返回 E_NOTIMPLmain() 可以在其处理switch语句:

#include <Windows.h>
#include <Slpublic.h>
#include <slerror.h>
#include <sliddefs.h>

#include <stdio.h>
#include <delayimp.h>

// lib to use
#pragma comment(lib, "slc.lib")

// if your version of Slpublic.h does not define these then uncomment this...
/*
typedef enum _tagSL_ACTIVATION_TYPE {
SL_ACTIVATION_TYPE_DEFAULT = 0,
SL_ACTIVATION_TYPE_ACTIVE_DIRECTORY = 1
} SL_ACTIVATION_TYPE;

typedef struct _tagSL_ACTIVATION_INFO_HEADER {
DWORD cbSize;
SL_ACTIVATION_TYPE type;
} SL_ACTIVATION_INFO_HEADER;
*/

HRESULT WINAPI Dummy_SLActivateProduct(HSLC, const SLID*, UINT, const PVOID, const SL_ACTIVATION_INFO_HEADER*, PCWSTR, WORD)
{
return E_NOTIMPL;
}

HMODULE hSlcExtDll = NULL;

FARPROC WINAPI MyDliFailureHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
if ((dliNotify == dliFailGetProc) && (pdli->dlp.fImportByName) && (lstrcmpA(pdli->dlp.szProcName, "SLActivateProduct") == 0))
{
hSlcExtDll = LoadLibrary("slcext.dll");
FARPROC fn = GetProcAddress(hSlcExtDll, "SLActivateProduct");
if (!fn) fn = &Dummy_SLActivateProduct;
return fn;
}

return NULL;
}

int main()
{
__pfnDliFailureHook2 = &MyDliFailureHook;

HSLC hslc;

HRESULT hr = SLOpen(&hslc);
if (FAILED(hr))
{
printf("SLOpen - unknown return code 0x%08X\n", hr);
return 0;
}

// try to activate windows
hr = SLActivateProduct(hslc, &WINDOWS_SLID, 0, NULL, NULL, NULL, 0);
switch(hr)
{
case E_NOTIMPL:
printf("SLActivateProduct - The product cannot be activated on this system\n");
break;

case E_INVALIDARG:
printf("SLActivateProduct - one or more arguments are not valid\n");
break;

case SL_E_PUBLISHING_LICENSE_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case SL_E_PKEY_NOT_INSTALLED:
printf("SLActivateProduct - The product key is not available\n");
break;

case SL_E_PRODUCT_SKU_NOT_INSTALLED:
printf("SLActivateProduct - The license is not installed\n");
break;

case S_OK:
printf("SLActivateProduct - returned S_OK\n");
break;

default:
printf("SLActivateProduct - unknown return code 0x%08X\n", hr);
break;
}

hr = SLClose(hslc);

return 0;
}

关于c - 有没有办法在 Windows 7 上以编程方式激活 Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40175955/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com