2

我正在尝试使用 WinAPI 函数GUIDFromString(),但它需要一些技巧才能将其包含在我的项目中。

根据msdn文档:

此函数未在标头中声明或按名称从 .dll 文件中导出。它必须从 Shell32.dll 作为 GUIDFromStringA 的序号 703 和 GUIDFromStringW 的序号 704 加载。

它也可以从 Shlwapi.dll 作为 GUIDFromStringA 的序号 269 和 GUIDFromStringW 的序号 270 访问。

我以前从未加载过 DLL,所以我不确定我应该做什么,我不确定加载 DLL 是否足够,我是否还必须包含一个编号为 703 的“序数”?任何人都可以就我需要做什么来使用这个功能甚至是一个例子提供任何建议吗?

我在下面的尝试不起作用(我使用的是 VC++ 2010 Express):

#pragma comment(lib, "shell32.lib") // if I am including the dll do I need to include the lib aswell?

// I've heard that the dll location differs across versions of windows
// Does anyone know of a Cross-Windows-Version way to include Shell32.dll no matter where it is? Maybe use a keyword like "%SYSTEM%/Shell32.dll"
HINSTANCE shell32DLL = LoadLibary("C:/System/Shell32.dll"); 

// Now do I include 'Ordinal 703' as described in msdn? And how do I do that?
4

3 回答 3

6

如果您阅读 的文档GUIDFromString()它会说:

GUIDFromString 可通过带有 Service Pack 2 (SP2) 的 Windows XP 或 Windows Vista 获得。在后续版本中可能会更改或不可用。应用程序应使用 CLSIDFromString 或 IIDFromString 代替此函数。

CLSIDFromString()并且IIDFromString()都按名称从 Ole32.dll 导出,因此您可以像使用任何其他 DLL 函数一样使用它们。

话虽如此,如果您仍然想使用GUIDFromString()然后使用LoadLibrary()加载shell32.dll然后使用GetProcAddress()访问该功能。 MSDN 文档演示了如何做到这一点。要按序号加载函数,可以MAKEINTRESOURCE()在调用时使用宏GetProcAddress()

因此,例如:

// MAKEINTRESOURCE() returns an LPTSTR, but GetProcAddress()
// expects LPSTR even in UNICODE, so using MAKEINTRESOURCEA()...
#ifdef UNICODE
#define MAKEINTRESOURCEA_T(a, u) MAKEINTRESOURCEA(u)
#else
#define MAKEINTRESOURCEA_T(a, u) MAKEINTRESOURCEA(a)
#endif

BOOL myGUIDFromString(LPCTSTR psz, LPGUID pguid)
{
    BOOL bRet = FALSE;

    typedef BOOL (WINAPI *LPFN_GUIDFromString)(LPCTSTR, LPGUID);
    LPFN_GUIDFromString pGUIDFromString = NULL;

    HINSTANCE hInst = LoadLibrary(TEXT("shell32.dll"));
    if (hInst)
    {
        pGUIDFromString = (LPFN_GUIDFromString) GetProcAddress(hInst, MAKEINTRESOURCEA_T(703, 704));
        if (pGUIDFromString)
            bRet = pGUIDFromString(psz, pguid);
        FreeLibrary(hInst);
    }

    if (!pGUIDFromString)
    {
        hInst = LoadLibrary(TEXT("Shlwapi.dll"));
        if (hInst)
        {
            pGUIDFromString = (LPFN_GUIDFromString) GetProcAddress(hInst, MAKEINTRESOURCEA_T(269, 270));
            if (pGUIDFromString)
                bRet = pGUIDFromString(psz, pguid);
            FreeLibrary(hInst);
        }
    }

    return bRet;
}
于 2013-01-28T09:00:48.387 回答
1

将以下行另存为 SHLWAPIX.DEF:

LIBRARY SHLWAPI
VERSION 6.0
EXPORTS
 GUIDFromStringA @269
 GUIDFromStringW @270

将以下行保存为 SHLWAPIX.C:

// https://msdn.microsoft.com/en-us/library/bb776431.aspx

__declspec(dllexport)
int __stdcall GUIDFromStringA(void *_1, void *_2)
{ return 0; }

__declspec(dllexport)
int __stdcall GUIDFromStringW(void *_1, void *_2)
{ return 0; }

运行 CL.EXE /LD /Zl SHLWAPIX.C /link /DEF:SHLWAPIX.DEF /NOENTRY 创建导入库SHLWAPIX.LIB,然后删除SHLWAPIX.OBJ、SHLWAPIX.EXP和SHLWAPIX.DLL

将以下行保存为 SHLWAPIX.H:

#pragma once
#pragma comment(linker, "/DEFAULTLIB:SHLWAPIX.LIB")

__declspec(dllimport)
BOOL WINAPI GUIDFromStringA(LPCSTR psz, LPGUID pguid);

__declspec(dllimport)
BOOL WINAPI GUIDFromStringW(LPCWSTR psz, LPGUID pguid);

最后将以下行保存为 SHLWAPIX.C:

#pragma comment(lib, "SHLWAPIX.LIB")
#pragma comment(lib, "USER32.LIB")

#pragma comment(linker, "/ENTRY:wWinMainCRTStartup")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS,5.0")
#pragma comment(linker, "/VERSION:1.0")

#define STRICT
#define UNICODE
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include "shlwapix.h"

VOID wWinMainCRTStartup()
{
    GUID guid = {0};
    WCHAR szBuffer[1025] = L"";

    if (GUIDFromStringA("{00112233-4455-6677-8899-AABBCCDDEEFF}", &guid))
        if (wsprintf(szBuffer, L"GUID = {%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",`
                     guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]) > 0)
            MessageBox((HWND) NULL, szBuffer, L"GUIDFromStringA()", MB_OK);

    if (GUIDFromStringW(L"{FFEEDDCC-BBAA-9988-7766-554433221100}", &guid))
        if (wsprintf(szBuffer, L"GUID = {%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
                     guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]) > 0)
            MessageBox((HWND) NULL, szBuffer, L"GUIDFromStringW()", MB_OK);
}

最后运行CL.EXE /GS- SHLWAPIX.C创建SHLWAPIX.EXE,再运行后者。

于 2016-11-12T15:32:35.033 回答
0

这会给你一个错误“语法错误'('”:

typedef BOOL WINAPI (*LPFN_GUIDFromString)(LPCTSTR, LPGUID);

正确的版本是:

typedef BOOL (WINAPI *LPFN_GUIDFromString)(LPCTSTR, LPGUID);
于 2013-02-21T12:49:52.723 回答