Как найти Path of Desktop в C ++ - PullRequest
       17

Как найти Path of Desktop в C ++

2 голосов
/ 16 февраля 2012

ОБНОВЛЕНО: после ответа Коди Грея

Я хочу найти способ сохранить файл на рабочем столе. Поскольку у каждого пользователя свое имя, я обнаружил, что следующий код поможет мне найти путь к чужому рабочему столу. Но как я могу сохранить следующее на рабочий стол?

#include <iostream>
#include <windows.h>
#include <fstream>
#include <direct.h>
#include <shlobj.h>
using namespace std;
int main ()
{
    ofstream file;  

    TCHAR appData[MAX_PATH];
    if (SUCCEEDED(SHGetFolderPath(NULL,
                                  CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
                                  NULL,
                                  SHGFP_TYPE_CURRENT,
                                  appData)))

    wcout << appData << endl; //This will printout the desktop path correctly, but
    file.open(appData +"/.txt"); //how can I open the desktop path here??
    file<<"hello\n";
    file.close();
    return 0;
}

Microsoft Visual Studio 2010, Windows 7, консоль C ++

1 Ответ

5 голосов
/ 16 февраля 2012

Проблема в том, что вы компилируете приложение с определением UNICODE (как вам и следует), то есть строки в стиле C не хранятся в массивах char (как это было бы для строк ANSI), а точнее wchar_t массивы.

Вот почему вы не можете конвертировать из char* в LPWSTR (что в заголовках Windows обозначено typedef wchar_t*).

Решение состоит в том, чтобы изменить тип вашего строкового буфера. Вы можете использовать wchar_t явно:

wchar_t appData[MAX_PATH];

или воспользуйтесь макросом TCHAR, который автоматически #define приведет к соответствующему типу, в зависимости от того, компилируете ли вы с UNICODE определено:

TCHAR appData[MAX_PATH];

Это не единственная проблема, хотя. Еще пара вещей, на которые стоит обратить внимание:

  1. При написании кода Win32 настоятельно рекомендуется использовать символы TRUE и FALSE вместо литералов 0 и 1. Когда документация функции указывает, что она принимает значения типа BOOL, используйте символы, которые уже определены для этого типа. Это делает ваш код намного понятнее и легче для чтения, даже если вы можете разумно предположить, что эти символы никогда не изменят свои определения в заголовках.

  2. CSIDL_LOCAL_APPDATA не является правильной константой для использования, если вам нужна папка desktop . Это вернет папку, которая связана с текущим пользователем и предназначена для использования приложениями для хранения данных, которые должны , а не перемещаться с пользователем (она должна храниться и быть доступной только на локальном компьютере ). Учитывая все вышесказанное, в любом случае это, вероятно, лучший выбор, чем настольный компьютер, поскольку у приложений действительно должна быть чертовски веская причина, прежде чем выкидывать мусор на рабочий стол пользователя.

    Если вам нужны данные для роуминга с приложением, вы должны использовать CSIDL_APPDATA. Я кратко излагаю, что представляют собой все эти различные папки, что они означают, и когда вы должны использовать их в моем ответе здесь .

    Обратите внимание, однако, что функция SHGetSpecialFolderPath ограничивает вас определенным подмножеством специальных папок. Что приводит меня к ...

  3. Начиная с Windows 2000 (и я, честно говоря, не думаю, что кто-нибудь все еще пишет приложения, ориентированные на версии Windows до до 2000), SHGetSpecialFolderPath функция устарела.

    Предпочтительной заменой для тех, на кого ориентированы Windows 2000 и XP, является SHGetFolderPath, который вы использовали бы аналогичным образом:

    TCHAR appData[MAX_PATH];
    
    if (SUCCEEDED(SHGetFolderPath(NULL, 
                                  CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 
                                  NULL, 
                                  SHGFP_TYPE_CURRENT, 
                                  appData))) 
    {
        wcout << appData << endl;
    }
    

    И самый новый член семейства - SHGetKnownFolderPath для новых приложений, предназначенных только для Windows Vista и более поздних версий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...