0

我有一个在 windows 2003、window 2008 和 windows 小型企业服务器上运行的应用程序。

我有一个 Windows 调用来重新启动系统。下面提到的所有调用都来自 advapi32.dll

InitiateSystemshutdown - 这在 windows 2003 和 windows 2008 中很好,但由于某种原因在 windows aurora 中不起作用

InitiateShutdown - 由于上述调用在 windows aurora 中不起作用,我们使用了此调用,并且此调用的最低支持操作系统是 windows 2008

现在我的应用程序无法在 Windows 2003 中运行,因为 Windows 2003 上的 advapi32.dll 中不存在 InitiateShutDown

我在 advapi32.dll 中找不到 Initiateshutdown 的过程入口点

我已经设置了一个条件,以便针对 Windows 版本调用正确的函数调用。

有没有办法在应用程序启动时停止在 dll 中寻找入口点。条件将确保调用正确的函数调用?

或者

我应该问微软为什么旧的调用 InitiateSystemshutdown 不能正常工作?

4

2 回答 2

2

您必须使用 GetProcAddress 并为早期版本的 Windows 设置预处理器变量。请参阅http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx#setting_winver_or__win32_winnt

基本上,您应该:

  1. 将 WINVER 设置为您必须支持的最早的 Windows 版本,这样您就不会意外使用更新的东西。

  2. 某些 API 调用和定义在您的代码中将不再起作用(例如您的情况下的 InitiateShutdown),因为它们不包含在头文件中。对于这些,您必须动态使用它们。通常,您使用 GetProcAddress API 并使用“typedef”来定义函数的签名(因为它不再包含在头文件中)。一个例子在这里:http: //msdn.microsoft.com/en-us/library/ms683212 (VS.85).aspx 。在您的情况下,您将使用 InitiateShutdown API 而不是给定的 GetNativeSystemInfo。如果对 GetProcAddress 的调用失败,那么您可以假定该 API 在该版本的 Windows 上不受支持。

于 2011-08-22T18:46:03.080 回答
1

而不是在您的代码中显式调用该函数(这样,如果无法从预期的 DLL 加载该函数,您的应用程序将无法加载),而是通过 LoadLibrary 和 GetProcAddress 隐式调用它。

在 advapi32.dll 上执行“LoadLibrary”。然后为“InitiateShutdown”调用 GetProcAddress。如果函数不存在,则优雅地失败,否则将其转换为适当的函数指针并调用它。

typedef DWORD (WINAPI *InitiateSystemShutdownTypeA) (char*, char*, DWORD, DWORD, DWORD);
typedef DWORD (WINAPI *InitiateSystemShutdownTypeW) (wchar_t*, wchar_t*, DWORD, DWORD, DWORD);

InitiateShutdownTypeA func = NULL;
HMODULE hMod = LoadLibrary("advapi32.dll"); 
if (hMod)
    func = (InitiateShutdownTypeA)GetProcAddress("InitiateShutdownW");

if (func)
    func(pwszMachineName, pwszMessage, dwGracePeriod, dwFlags, dwReason);
于 2011-08-22T18:49:05.770 回答