How to import IWinHttpRequest into MSVC++ Project?

Viewed 409

I have been looking at the example code from Microsoft for using WinHTTP over COM, see: https://docs.microsoft.com/en-us/windows/win32/winhttp/iwinhttprequest-open

The first few lines of the code are as follows:

#include <windows.h>
#include <stdio.h>
#include <objbase.h>

#include "httprequest.h"

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

// IID for IWinHttpRequest.
const IID IID_IWinHttpRequest =
{
  0x06f29373,
  0x5c5a,
  0x4b54,
  {0xb0, 0x25, 0x6e, 0xf1, 0xbf, 0x8a, 0xbf, 0x0e}
};

int main()
{
    // Variable for return value
    HRESULT    hr;

    // Initialize COM
    hr = CoInitialize( NULL );

    IWinHttpRequest *  pIWinHttpRequest = NULL;

I am confused with the correct way to #include the IWinHttpRequest type. I think it comes from the httprequest.h file which is not a system include file.

Also, I guess httprequest.h is the result of compiling httprequest.idl. Am I supposed to manually compile httprequest.idl, or as this is part of the Windows SDK is there a better way to access this type?

2 Answers

Well, knowing absolutely nothing about this beforehand, I looked up the interface you gave, IWinHttpRequest. I went to the registry and searched for it in HKCR\Interface, found the typelib for the interface in the registry. The typelib is HKEY_CLASSES_ROOT\TypeLib\{662901FC-6951-4854-9EB2-D9A2570F2B2E}. From the typelib, looked up HKEY_CLASSES_ROOT\TypeLib\{662901FC-6951-4854-9EB2-D9A2570F2B2E}\5.1\0\win32. The win32 entry shows where the location of the typelib on disk is: %SystemRoot%\system32\winhttpcom.dll

Since the %SystemRoot%\system32 directly is always in the path, you can use the typelib simmply like this:

#import "winhttpcom.dll"

Behind the scenes, the Visual C++ compiler will create files named winhttpcom.tlh and winhttpcom.tli. You can ignore those files. The compiler just automatically includes and links with those files.

It will declare COM smart pointers in the .tlh file:

_COM_SMARTPTR_TYPEDEF(IWinHttpRequest, __uuidof(IWinHttpRequest));
_COM_SMARTPTR_TYPEDEF(IWinHttpRequestEvents, __uuidof(IWinHttpRequestEvents));

All of this will be wrapped in a C++ namespace:

namespace WinHttp { 
// definitions in here
}

If you don't want namespaces, you can do something like:

#import "winhttpcom.dll" no_namespace

Documentation for #import is at https://docs.microsoft.com/en-us/cpp/preprocessor/hash-import-directive-cpp?view=vs-2019

There are just missing instructions on how to get the httprequest.h file. The Windows SDK only has the .idl file. This is somehow unusual, many Windows APIs have the .idl and the .h, some only have .h, some only have .idl ... But you can create the .h from the .idl:

This is a sample output:

**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.5.1
** Copyright (c) 2019 Microsoft Corporation
**********************************************************************

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional>midl httprequest.idl /out D:\MyPath\MyAppDir
Microsoft (R) 32b/64b MIDL Compiler Version 8.01.0622
Copyright (c) Microsoft Corporation. All rights reserved.
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\httprequest.idl
httprequest.idl
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\oaidl.idl
oaidl.idl
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\objidl.idl
objidl.idl
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\unknwn.idl
unknwn.idl
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\wtypes.idl
wtypes.idl
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\wtypesbase.idl
wtypesbase.idl
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\basetsd.h
basetsd.h
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\guiddef.h
guiddef.h
Processing C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\oaidl.acf
oaidl.acf

It will create 3 files: httprequest.h, httprequest.tlb and httprequest_i.c in your project directory.

Now you should be able to compile the sample code. Note if you include the httprequest_i.c file, you can even remove the manual declaration of IID_IWinHttpRequest in the sample.

Related