DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
Environment.cpp
Go to the documentation of this file.
1#include "pch.h"
3#include <vector>
4#include <map>
5#include <sstream>
6
7#if defined(_WIN32)
8#include <windows.h>
9#include <Psapi.h>
10#include <shellapi.h>
11#include <shlobj.h>
12#include "Win32Internal.h"
13#pragma comment(lib, "psapi.lib")
14#pragma warning(disable : 4996)
15
16using namespace DotNetDupe::System::Internal;
17#else
18#include <unistd.h>
19#include <pwd.h>
20#include <limits.h>
21#include <sys/utsname.h>
22#include <fstream>
23#include <iostream>
24
25extern char** environ;
26#endif
27
28namespace DotNetDupe {
29 namespace System {
32#if defined(_WIN32)
33 wchar_t buffer [MAX_COMPUTERNAME_LENGTH + 1];
34 DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1;
35 GetComputerNameW(buffer, &nSize);
36 return String(WCharToUtf8(buffer).c_str());
37#else
38 char buffer[HOST_NAME_MAX + 1];
39 if (gethostname(buffer, sizeof(buffer)) == 0) {
40 return buffer;
41 }
42 return "";
43#endif
44 }
45
48#if defined(_WIN32)
49 wchar_t buffer [256];
50 DWORD nSize = 256;
51 ::GetUserNameW(buffer, &nSize);
52 return String(buffer);
53#else
54 struct passwd *pPw = getpwuid(getuid());
55 if (pPw) {
56 return pPw->pw_name;
57 }
58 const char* pUser = getenv("USER");
59 return pUser ? pUser : "";
60#endif
61 }
62
65#if defined(_WIN32)
66 SYSTEM_INFO sysInfo;
67 GetSystemInfo(&sysInfo);
68 return (int)sysInfo.dwNumberOfProcessors;
69#else
70 return (int)sysconf(_SC_NPROCESSORS_ONLN);
71#endif
72 }
73
76#if defined(_WIN32)
77 return "\r\n";
78#else
79 return "\n";
80#endif
81 }
82
85#if defined(_WIN32)
86 wchar_t buffer [MAX_PATH];
87 ::GetCurrentDirectoryW(MAX_PATH, buffer);
88 return String(WCharToUtf8(buffer).c_str());
89#else
90 char buffer[PATH_MAX];
91 if (getcwd(buffer, sizeof(buffer))) {
92 return String(buffer);
93 }
94 return String("");
95#endif
96 }
97
100#if defined(_WIN32)
101 wchar_t buffer [MAX_PATH];
102 ::GetSystemDirectoryW(buffer, MAX_PATH);
103 return String(WCharToUtf8(buffer).c_str());
104#else
105 return String("/usr/lib"); // Better POSIX default
106#endif
107 }
108
111#if defined(_WIN32)
112 OSVERSIONINFOEXW info;
113 ZeroMemory(&info, sizeof(OSVERSIONINFOEXW));
114 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
115 GetVersionExW((LPOSVERSIONINFOW)&info);
116
117 std::stringstream ss;
118 ss << info.dwMajorVersion << "." << info.dwMinorVersion << "." << info.dwBuildNumber;
119 return String(ss.str().c_str());
120#else
121 struct utsname name;
122 if (uname(&name) == 0) {
123 return String(name.release);
124 }
125 return String("Unknown");
126#endif
127 }
128
133
134#if !defined(_WIN32)
135 static int64_t ReadLinuxWorkingSet() {
136 std::ifstream statusFile("/proc/self/status");
137 std::string sLine;
138 while (std::getline(statusFile, sLine)) {
139 if (sLine.compare(0, 6, "VmRSS:") == 0) {
140 size_t nStart = sLine.find_first_of("0123456789");
141 size_t nEnd = sLine.find_first_not_of("0123456789", nStart);
142 if (nStart != std::string::npos) return std::stoll(sLine.substr(nStart, nEnd - nStart)) * 1024;
143 }
144 }
145 return 0;
146 }
147#endif
148
151#if defined(_WIN32)
152 PROCESS_MEMORY_COUNTERS pmc;
153 if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) return (int64_t)pmc.WorkingSetSize;
154 return 0;
155#else
156 return ReadLinuxWorkingSet();
157#endif
158 }
159
160 void Environment::Exit(int iExitCode) {
161 ::exit(iExitCode);
162 }
163
166#if defined(_WIN32)
167 std::wstring sWName = Utf8ToWChar(sName.GetRawString());
168 DWORD nSize = ::ExpandEnvironmentStringsW(sWName.c_str(), NULL, 0);
169 if (nSize == 0) return sName;
170 std::vector<wchar_t> buffer(nSize);
171 ::ExpandEnvironmentStringsW(sWName.c_str(), buffer.data(), nSize);
172 return String(WCharToUtf8(buffer.data()).c_str());
173#else
174 if (sName.StartsWith("%", false) && sName.EndsWith("%", false)) {
175 const char* pVal = getenv(sName.Substring(1, sName.GetLength() - 2).GetRawString());
176 return pVal ? String(pVal) : sName;
177 }
178 return sName;
179#endif
180 }
181
182 static std::vector<String> ReadCommandLineTokens() {
183 std::vector<String> tempArgs;
184#if defined(_WIN32)
185 int nArgs;
186 LPWSTR* pSzArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
187 if (pSzArglist != NULL) {
188 for (int iIndex = 0; iIndex < nArgs; iIndex++) tempArgs.push_back(String(WCharToUtf8(pSzArglist[iIndex]).c_str()));
189 LocalFree(pSzArglist);
190 }
191#else
192 std::ifstream cmdline("/proc/self/cmdline", std::ios::binary);
193 std::string sArg;
194 while (std::getline(cmdline, sArg, '\0')) tempArgs.push_back(String(sArg.c_str()));
195#endif
196 return tempArgs;
197 }
198
200 std::vector<String> tempArgs = ReadCommandLineTokens();
201 Array<String> result((int)tempArgs.size());
202 for (int iIndex = 0; iIndex < (int)tempArgs.size(); iIndex++) result[iIndex] = tempArgs[iIndex];
203 return result;
204 }
205
207#if defined(_WIN32)
208 std::wstring sWVar = Utf8ToWChar(sVariable.GetRawString());
209 DWORD nSize = ::GetEnvironmentVariableW(sWVar.c_str(), NULL, 0);
210 if (nSize == 0) return String("");
211 std::vector<wchar_t> buffer(nSize);
212 ::GetEnvironmentVariableW(sWVar.c_str(), buffer.data(), nSize);
213 return String(WCharToUtf8(buffer.data()).c_str());
214#else
215 const char* pVal = getenv(sVariable.GetRawString());
216 return pVal ? String(pVal) : String("");
217#endif
218 }
219
221 int iEqIdx = sLine.IndexOf("=");
222 if (iEqIdx != -1) {
223 result.Add(sLine.Substring(0, iEqIdx), sLine.Substring(iEqIdx + 1, sLine.GetLength() - iEqIdx - 1));
224 }
225 }
226
229#if defined(_WIN32)
230 wchar_t* pLpvEnv = GetEnvironmentStringsW();
231 for (wchar_t* pLpszVariable = pLpvEnv; *pLpszVariable; pLpszVariable += wcslen(pLpszVariable) + 1) {
232 ParseAndAddEnvEntry(String(WCharToUtf8(pLpszVariable).c_str()), result);
233 }
234 FreeEnvironmentStringsW(pLpvEnv);
235#else
236 for (char** ppEnv = environ; *ppEnv; ++ppEnv) {
237 ParseAndAddEnvEntry(String(*ppEnv), result);
238 }
239#endif
240 return result;
241 }
242
243#if defined(_WIN32)
246 switch (eFolder) {
247 case SF::ApplicationData: return CSIDL_APPDATA;
248 case SF::CommonApplicationData: return CSIDL_COMMON_APPDATA;
249 case SF::CommonProgramFiles: return CSIDL_PROGRAM_FILES_COMMON;
250 case SF::Cookies: return CSIDL_COOKIES;
251 case SF::Desktop: return CSIDL_DESKTOP;
252 case SF::Favorites: return CSIDL_FAVORITES;
253 case SF::History: return CSIDL_HISTORY;
254 case SF::InternetCache: return CSIDL_INTERNET_CACHE;
255 case SF::LocalApplicationData: return CSIDL_LOCAL_APPDATA;
256 case SF::MyComputer: return CSIDL_DRIVES;
257 case SF::MyDocuments: return CSIDL_MYDOCUMENTS;
258 case SF::MyMusic: return CSIDL_MYMUSIC;
259 case SF::MyPictures: return CSIDL_MYPICTURES;
260 case SF::MyVideos: return CSIDL_MYVIDEO;
261 case SF::ProgramFiles: return CSIDL_PROGRAM_FILES;
262 case SF::Programs: return CSIDL_PROGRAMS;
263 case SF::Recent: return CSIDL_RECENT;
264 case SF::SendTo: return CSIDL_SENDTO;
265 case SF::StartMenu: return CSIDL_STARTMENU;
266 case SF::Startup: return CSIDL_STARTUP;
267 case SF::System: return CSIDL_SYSTEM;
268 case SF::Templates: return CSIDL_TEMPLATES;
269 case SF::UserProfile: return CSIDL_PROFILE;
270 default: return 0;
271 }
272 }
273#endif
274
276#if defined(_WIN32)
277 wchar_t buffer[MAX_PATH];
278 if (SHGetFolderPathW(NULL, GetCsidlForFolder(eFolder), NULL, 0, buffer) == S_OK) {
279 return String(WCharToUtf8(buffer).c_str());
280 }
281 return String("");
282#else
283 if (eFolder == SpecialFolder::UserProfile || eFolder == SpecialFolder::MyDocuments) return String(getenv("HOME"));
284 if (eFolder == SpecialFolder::LocalApplicationData) return String(getenv("HOME")) + "/.local/share";
285 return String("");
286#endif
287 }
288
290 std::vector<String> tempDrives;
291#if defined(_WIN32)
292 DWORD nDrives = ::GetLogicalDrives();
293 for (int iIndex = 0; iIndex < 26; iIndex++) {
294 if ((nDrives >> iIndex) & 1) {
295 char chDriveName[4] = { (char)('A' + iIndex), ':', '\\', 0 };
296 tempDrives.push_back(String(chDriveName));
297 }
298 }
299#else
300 tempDrives.push_back(String("/"));
301#endif
302 Array<String> result((int)tempDrives.size());
303 for (int iIndex = 0; iIndex < (int)tempDrives.size(); iIndex++) result[iIndex] = tempDrives[iIndex];
304 return result;
305 }
306
307 void Environment::SetEnvironmentVariable(const String& sVariable, const String& sValue) {
308#if defined(_WIN32)
309 std::wstring sWVar = Utf8ToWChar(sVariable.GetRawString());
310 std::wstring sWVal = Utf8ToWChar(sValue.GetRawString());
311 ::SetEnvironmentVariableW(sWVar.c_str(), sWVal.c_str());
312#else
313 setenv(sVariable.GetRawString(), sValue.GetRawString(), 1);
314#endif
315 }
316
318#if defined(_WIN32)
319 OSVERSIONINFOEXW info;
320 ZeroMemory(&info, sizeof(OSVERSIONINFOEXW));
321 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
322 GetVersionExW((LPOSVERSIONINFOW)&info);
323 return OperatingSystem(PlatformID::Win32NT, Version(info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber, 0));
324#else
325 struct utsname name;
326 uname(&name);
327 return OperatingSystem(PlatformID::Unix, Version(0, 0, 0, 0));
328#endif
329 }
330 }
331}
Provides information about, and means to manipulate, the current environment and platform.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition Array.h:29
Represents a collection of keys and values.
Definition Dictionary.h:66
void Add(const TKey &key, const TValue &value)
Definition Dictionary.h:244
static String GetSystemDirectory()
Gets the fully qualified path of the system directory.
static String GetUserName()
Gets the user name of the person who is currently logged on to the OS.
static String GetUserDomainName()
Gets the network domain name associated with the current user.
static Array< String > GetCommandLineArgs()
Returns a string array containing the command-line arguments for the current process.
static OperatingSystem GetOperatingSystem()
Gets an OperatingSystem object that contains the current platform identifier and version.
static int GetProcessorCount()
Gets the number of logical processors available on the current machine.
static String ExpandEnvironmentVariables(const String &sName)
Replaces the name of each environment variable embedded in the specified string with the string equiv...
SpecialFolder
Specifies enumerated constants used to retrieve directory paths to system special folders.
Definition Environment.h:37
static void Exit(int iExitCode)
Terminates this process and returns an exit code to the operating system.
static int64_t GetWorkingSet()
Gets the amount of physical memory mapped to the process context (Working Set in bytes).
static void SetEnvironmentVariable(const String &sVariable, const String &sValue)
Creates, modifies, or deletes an environment variable stored in the current process.
static String GetFolderPath(SpecialFolder eFolder)
Gets the path to the system special folder that is identified by the specified enumeration.
static String GetEnvironmentVariable(const String &sVariable)
Retrieves the value of an environment variable from the current process.
static Collections::Generic::Dictionary< String, String > GetEnvironmentVariables()
Retrieves all environment variable names and their values from the current process.
static Array< String > GetLogicalDrives()
Returns an array of string containing the names of the logical drives on the current computer.
static String GetCurrentDirectory()
Gets the fully qualified path of the current working directory.
static String GetMachineName()
Gets the NetBIOS / network name of this local computer.
static String GetNewLine()
Gets the newline string defined for this environment ("\r\n" on Windows, "\n" on POSIX).
static String GetOSVersion()
Gets an operating system version string representation.
Represents information about an operating system, such as the version and platform identifier.
OperatingSystem(PlatformID platform, const Version &version)
Initializes a new instance of the OperatingSystem class, using the specified platform identifier and ...
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
Definition String.h:74
String Substring(int iStartIndex) const
Definition String.cpp:659
bool StartsWith(const String &sPrefix) const
Definition String.cpp:610
bool EndsWith(char ch, bool bIgnoreCase) const
Definition String.cpp:315
String()
Initializes a new instance of the String class to an empty string.
Definition String.cpp:64
int IndexOf(const String &sSubstring) const
Definition String.cpp:341
const char * GetRawString() const
Definition String.cpp:230
Version()
Initializes a new instance of the Version class to 0.0.0.0.
Definition Version.cpp:77
std::string WCharToUtf8(const wchar_t *pWStr)
std::wstring Utf8ToWChar(const char *pUtf8Str)
static void ParseAndAddEnvEntry(const String &sLine, Collections::Generic::Dictionary< String, String > &result)
static int GetCsidlForFolder(Environment::SpecialFolder eFolder)
static std::vector< String > ReadCommandLineTokens()
@ Unix
Unix or Linux platform.
@ Win32NT
Windows NT, 2000, XP, Vista, 7, 8, 10, 11, or Windows Server.