#winapi #visual-c #environment-variables
Вопрос:
Поэтому я пытался выяснить, как найти переменную среды и распечатать ее на экране в c , но в течение последних 3 часов или около того я застрял. Когда я распечатываю переменную currentDesktop, она выводит только «/Рабочий стол». Но то, что я ищу, — это имя пользователя перед ним. Я читал документацию по функции GetEnviromentVariable с форума Microsoft, и это то, что я придумал до сих пор. Помощь была бы очень признательна, так как у меня еще нет такого опыта, Тх.
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#define BUFSIZE 4096
using namespace std;
int main()
{
LPCWSTR Env = L"%USERPROFILE";
LPTSTR pszOldVal;
string IPADD;
pszOldVal = (LPTSTR)malloc(BUFSIZE * sizeof(TCHAR));
if (NULL == pszOldVal)
{
printf("Out of memoryn");
return FALSE;
}
string currentDesktop = GetEnvironmentVariable(Env,pszOldVal,BUFSIZE) "\Desktop";
cout << currentDesktop;
return 0;
}
Комментарии:
1. В документации std::getenv есть простой для подражания пример.
2. Если вам нужен пользователь, почему бы не использовать
%USERPROFILE%
?3. @CPPNEWBIE внимательно перечитайте свой код. То, что в нем содержится, а не то, что вы думаете, что оно делает.
4. Ага, вы забыли преобразовать
GetEnvironmentVariable(Env,pszOldVal,BUFSIZE)
в аstd::string
, прежде чем добавлять"\Desktop"
к возвращенным результатам.GetEnvironmentVariable
возвращает achar*
, а не astd::string
5. @NathanOliver »
GetEnvironmentVariable
возвращает achar*
» — нет, он принимает achar[]
и возвращает aDWORD
, указывая, сколько символов было скопировано вchar[]
. Вместо этого вы думаете о(std::)getenv()
себе.
Ответ №1:
Вы злоупотребляете этой GetEnvironmentVariable()
функцией. Во-первых, вам не хватает конца %
имени переменной L"%USERPROFILE"
. Во-вторых, возвращаемое значение-это количество символов, скопированных в предоставленный буфер. Вы добавляете это целое число в строковый литерал "\Desktop"
, а это не то, что вы хотите.
Попробуйте это вместо этого:
#include <iostream>
#include <string>
#include <windows.h>
std::wstring GetEnv(const std::wstring amp;varName)
{
std::wstring str;
DWORD len = GetEnvironmentVariableW(varName.c_str(), NULL, 0);
if (len > 0)
{
str.resize(len);
str.resize(GetEnvironmentVariableW(varName.c_str(), amp;str[0], len));
}
return str;
}
std::wstring GetUserDesktopPath()
{
std::wstring path = GetEnv(L"%USERPROFILE%");
if (!path.empty()) path = L"\Desktop";
return path;
}
int main()
{
std::wstring currentDesktop = GetUserDesktopPath();
std::wcout << currentDesktop;
return 0;
}
При этом, если вам просто нужно имя пользователя, используйте %USERNAME%
вместо %USERPROFILE%
. Или лучше, используйте GetUserName()
вместо GetEnvironmentVariable()
:
#include <iostream>
#include <string>
#include <windows.h>
std::wstring GetUserName()
{
std::wstring str;
DWORD len = 0;
if (!GetUserNameW(NULL, amp;len))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
str.resize(len);
if (GetUserNameW(amp;str[0], amp;len))
str.resize(len-1);
else
str = L"";
}
}
return str;
}
int main()
{
std::wstring currentUser = GetUserName();
std::wcout << currentUser;
return 0;
}
Однако правильный способ получить путь к рабочему столу пользователя-просто запросить у Windows этот конкретный путь, не предполагая, что он находится в корне профиля пользователя или что он имеет имя Desktop
. Используйте SHGetFolderPath()
или SHGetKnownFolderPath()
для этого запроса, например:
#include <iostream>
#include <string>
#include <windows.h>
#include <shlobj.h>
std::wstring GetFolderPath(CSIDL folderID)
{
WCHAR path[MAX_PATH] = {};
SHGetFolderPathW(NULL, folderID, NULL, SHGFP_TYPE_CURRENT, path);
return path;
}
/* or:
std::wstring GetFolderPath(REFKNOWNFOLDERID folderID)
{
std::wstring str;
PWSTR path = NULL;
if (SHGetKnownFolderPath(folderID, 0, NULL, amp;path) == S_OK)
str = path;
CoTaskMemFree(path);
return str;
}
*/
std::wstring GetUserDesktopPath()
{
return GetFolderPath(CSIDL_DESKTOPDIRECTORY);
// or: return GetFolderPath(FOLDERID_Desktop);
}
int main()
{
std::wstring currentDesktop = GetUserDesktopPath();
std::wcout << currentDesktop;
return 0;
}
Комментарии:
1. При тестировании заголовка Shlobj я получил пару ошибок. в частности, при использовании пути к папке(CSIDL_DESKTOP, FOLDERID_Desktop). Ошибка гласит: «нет экземпляра конструктора». Что это значит?
2. @CPPNEWBIE Пожалуйста, предоставьте точное сообщение об ошибке дословно и укажите, на какую строку кода ссылается ошибка.
3. Спецификация связи несовместима с предыдущим «SHGetKnownFolderPath»(объявлена в строке 1046 «C:/blah/blah/blaH/shlobj_core.h»
4. Вместо этого я попытался использовать путь SHGETKNOWNFOLDERPATH (). Понял, что эта ошибка выходит за рамки моей лиги, и я понятия не имею, что я делаю на данный момент.
5. @CPPNEWBIE Ну, теперь вы цитируете совершенно другую ошибку. Что случилось с ошибкой конструктора, о которой вы впервые упомянули? Вы делаете это трудным, чтобы помочь себе.