SHGetKnownFolderPath: неоднозначный символ 'IServiceProvider'?

Я пытаюсь создать папку для своего приложения в /AppData/local чтобы я мог сохранить в нем некоторые ini-файлы, я попытался найти путь к месту назначения, используя:

#include <ShlObj.h>

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

Это не работает и дает мне эти ошибки:

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

Я пытался добавить #pragma comment (lib, "Shell32.lib") и связывая Shell32.lib в настройках проекта и ничего не изменилось.

Ошибки исчезают, когда я удаляю #include <ShlObj.h> но тогда SHGetKnownFolderPath функция становится неопределенной. Как я могу это исправить?

Примечание: я на Windows 7

Изменить: файлы заголовка моего проекта:

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");
    }
}

1 ответ

Решение

IServerProvider действительно неоднозначно, он существует как тип интерфейса COM в заголовочном файле Windows SDK servprov.h и как тип интерфейса.NET в пространстве имен System.

Самый простой способ воспроизвести вашу проблему - поместить директиву namespace в неправильное место:

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

Бам, 18 ошибок. Нет проблем, если вы заказываете их правильно:

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

Осторожнее с теми, кто использует директивы, они действительно хороши в создании двусмысленности.

IServerProvider неоднозначен, потому что это тип интерфейса COM в servprov.h (который вы получаете с windows.h) и как тип интерфейса.NET в пространстве имен System.

Если вам не нужны все API в windows.h, вы можете #define WIN32_LEAN_AND_MEAN чтобы получить подмножество, исключающее IServiceProvider определение и избегает двусмысленности.

Сделайте #define перед #include и, наверное, неплохо #undef потом, вот так:

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
Другие вопросы по тегам