c++-cliknown-folders

SHGetKnownFolderPath: ambiguous symbol 'IServiceProvider'?


I'm trying to create a folder for my app in /AppData/local so that i can save some ini files in it, i tried to get the Destination path using:

#include <ShlObj.h>

if (SHGetKnownFolderPath (FOLDERID_LocalAppData, 0, NULL, &tempPath) == S_OK)
{
....
}

It doesn't work and gives me these errors:

Error   1   error C2872: 'IServiceProvider' : ambiguous symbol  c:\program files\windows kits\8.0\include\um\ocidl.h    6482    1   Project2
Error   2   error C2872: 'IServiceProvider' : ambiguous symbol  C:\Program Files\Windows Kits\8.0\Include\um\shobjidl.h 9181    1   Project2

I tried adding #pragma comment (lib, "Shell32.lib") and linking the Shell32.lib in the project settings and nothing changed.

The errors disappear when i remove #include <ShlObj.h> but then the SHGetKnownFolderPath function becomes undefined. How can i fix this?

Note: I'm on Windows 7

Edit: My Project Header files are:

MyForm.h

#pragma once

#define CRTDBG_MAP_ALLOC
#include "gamepad.h"
#include "configure.h"
#include <stdlib.h>
#include <crtdbg.h>
#include <Dbt.h>

namespace Project2 {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::Diagnostics;

    public ref class MyForm : public System::Windows::Forms::Form
    {
    public:
        MyForm(void)
        {
            InitializeComponent();
            this->gamepad = gcnew Gamepad();
            this->SETTINGS = gcnew Settings();
        }
        ....
    };
}

gamepad.h

#pragma once

#include <Windows.h>
#include <WinUser.h>
#include <tchar.h>
#define _USE_MATH_DEFINES
#include <math.h>
extern "C"
{
#include <hidsdi.h>
}
#include "InputHandler.h"
#include "keycodes.h"

using namespace System;

public ref class Gamepad
{
    ....
}

configure.h

#pragma once

#include "keycodes.h"
#include <Windows.h>
#include <Shlwapi.h>
#include <ShlObj.h>
#include <msclr\marshal.h>


using namespace System;
using namespace System::Diagnostics;
using namespace System::IO;
using namespace msclr::interop;

public ref class Settings
{
public:
    Settings(void)
    {
        PWSTR tempPath;
        if (SUCCEEDED (SHGetKnownFolderPath (FOLDERID_LocalAppData, 0, NULL, &tempPath)))
            Debug::WriteLine (gcnew String (tempPath));
        else Debug::WriteLine ("Failed");
    }
}

Solution

  • IServerProvider is indeed ambiguous, it exists both as an COM interface type in the servprov.h Windows SDK header file and as .NET interface type in the System namespace.

    Simplest way to repro your problem is to put the using namespace directive in the wrong spot:

      #include "stdafx.h"
      using namespace System;
      #include <ShlObj.h>
    

    Bam, 18 errors. No problemo if you order them right:

      #include "stdafx.h"
      #include <ShlObj.h>
      using namespace System;
    

    Careful with those using directives, they are really good at creating ambiguity.