diff --git a/Library/ConfigParser.cpp b/Library/ConfigParser.cpp index e317cbea..2d835cf1 100644 --- a/Library/ConfigParser.cpp +++ b/Library/ConfigParser.cpp @@ -53,9 +53,23 @@ CConfigParser::~CConfigParser() ** ** */ -void CConfigParser::Initialize(LPCTSTR filename) +void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter) { m_Filename = filename; + + m_Variables.clear(); + + // Set the paths as default variables + if (pRainmeter) + { + m_Variables[L"PROGRAMPATH"] = pRainmeter->GetPath(); + m_Variables[L"SETTINGSPATH"] = pRainmeter->GetSettingsPath(); + m_Variables[L"SKINSPATH"] = pRainmeter->GetSkinPath(); + m_Variables[L"PLUGINSPATH"] = pRainmeter->GetPluginPath(); + m_Variables[L"CURRENTPATH"] = CRainmeter::ExtractPath(filename); + m_Variables[L"ADDONSPATH"] = pRainmeter->GetPath() + L"Addons\\"; + } + ReadVariables(); } @@ -72,7 +86,6 @@ void CConfigParser::ReadVariables() int bufferSize = 4096; bool loop; - m_Variables.clear(); do { loop = false; @@ -175,21 +188,7 @@ const std::wstring& CConfigParser::ReadString(LPCTSTR section, LPCTSTR key, LPCT } } - if (result.find(L'%') != std::wstring::npos) - { - WCHAR buffer[4096]; // lets hope the buffer is large enough... - - // Expand the environment variables - DWORD ret = ExpandEnvironmentStrings(result.c_str(), buffer, 4096); - if (ret != 0 && ret < 4096) - { - result = buffer; - } - else - { - DebugLog(L"Unable to expand the environment strings."); - } - } + result = CRainmeter::ExpandEnvironmentVariables(result); // Check for variables (#VAR#) size_t start = 0; diff --git a/Library/ConfigParser.h b/Library/ConfigParser.h index c3bb68f7..aa0992b3 100644 --- a/Library/ConfigParser.h +++ b/Library/ConfigParser.h @@ -24,13 +24,15 @@ #include #include +class CRainmeter; + class CConfigParser { public: CConfigParser(); ~CConfigParser(); - void Initialize(LPCTSTR filename); + void Initialize(LPCTSTR filename, CRainmeter* pRainmeter); const std::wstring& ReadString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue); double ReadFloat(LPCTSTR section, LPCTSTR key, double defValue); diff --git a/Library/Litestep.cpp b/Library/Litestep.cpp index 1e32bba2..9a3e2d14 100644 --- a/Library/Litestep.cpp +++ b/Library/Litestep.cpp @@ -375,12 +375,7 @@ HINSTANCE ExecuteCommand(HWND Owner, LPCTSTR szCommand, int nShowCmd, LPCTSTR sz return instance; } - std::wstring dir; - size_t dirPos = command.rfind(L"\\"); - if (dirPos != std::wstring::npos) - { - dir = command.substr(0, dirPos); - } + std::wstring dir = CRainmeter::ExtractPath(command); SHELLEXECUTEINFO si; memset(&si, 0, sizeof(si)); diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index a6582b22..14d9cc9e 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -1157,7 +1157,7 @@ void CMeterWindow::ReadConfig() m_SavePosition = true; // Default value CConfigParser parser; - parser.Initialize(iniFile.c_str()); + parser.Initialize(iniFile.c_str(), m_Rainmeter); for (int i = 0; i < 2; i++) { @@ -1285,7 +1285,7 @@ void CMeterWindow::ReadSkin() iniFile += L"\\"; iniFile += m_SkinIniFile; - m_Parser.Initialize(iniFile.c_str()); + m_Parser.Initialize(iniFile.c_str(), m_Rainmeter); // Global settings diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index e1d9e7b2..d9017e57 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -669,25 +669,17 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) if(!c_DummyLitestep) InitalizeLitestep(); - m_Path = tmpName; - m_PluginPath = tmpName; - m_PluginPath += L"Plugins\\"; - m_IniFile = m_Path + L"Rainmeter.ini"; - m_SkinPath = m_Path + L"Skins\\"; - bool bDefaultIniLocation = false; - // If the ini file doesn't exist in the program folder store it to the %APPDATA% instead so that things work better in Vista/Win7 - if (_waccess(m_IniFile.c_str(), 0) == -1) + if (c_CmdLine.empty()) { - WCHAR buffer[4096]; // lets hope the buffer is large enough... + m_Path = tmpName; + m_IniFile = m_Path + L"Rainmeter.ini"; - // Expand the environment variables - DWORD ret = ExpandEnvironmentStrings(L"%APPDATA%\\Rainmeter\\", buffer, 4096); - if (ret != 0 && ret < 4096) + // If the ini file doesn't exist in the program folder store it to the %APPDATA% instead so that things work better in Vista/Win7 + if (_waccess(m_IniFile.c_str(), 0) == -1) { - m_IniFile = buffer; - m_IniFile += L"rainmeter.ini"; + m_IniFile = ExpandEnvironmentVariables(L"%APPDATA%\\Rainmeter\\Rainmeter.ini"); bDefaultIniLocation = true; // If the ini file doesn't exist in the %APPDATA% either, create a default rainmeter.ini file. @@ -697,12 +689,46 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) } } } + else + { + // The command line defines the location of Rainmeter.ini (or whatever it calls it). + std::wstring iniFile = c_CmdLine; + if (iniFile[0] == L'\"' && iniFile[iniFile.length() - 1] == L'\"') + { + iniFile = iniFile.substr(1, iniFile.length() - 2); + } + + iniFile = ExpandEnvironmentVariables(iniFile); + + if (iniFile[iniFile.length() - 1] == L'\\') + { + iniFile += L"Rainmeter.ini"; + } + else if (iniFile.substr(iniFile.length() - 4) != L".ini") + { + iniFile += L"\\Rainmeter.ini"; + } + + m_Path = ExtractPath(iniFile); + m_IniFile = iniFile; + + // If the ini file doesn't exist in the %APPDATA% either, create a default rainmeter.ini file. + if (_waccess(m_IniFile.c_str(), 0) == -1) + { + CreateDefaultConfigFile(m_IniFile); + } + bDefaultIniLocation = true; + } + + m_PluginPath = tmpName; + m_PluginPath += L"Plugins\\"; + m_SkinPath = m_Path + L"Skins\\"; // Read the skin folder from the ini file WCHAR tmpSz[MAX_LINE_LENGTH]; if (GetPrivateProfileString(L"Rainmeter", L"SkinPath", L"", tmpSz, MAX_LINE_LENGTH, m_IniFile.c_str()) > 0) { - m_SkinPath = tmpSz; + m_SkinPath = ExpandEnvironmentVariables(tmpSz); } else if (bDefaultIniLocation) { @@ -890,11 +916,41 @@ void CRainmeter::CreateDefaultConfigFile(std::wstring strFile) CreateDirectory(strPath.c_str(), NULL); } - std::ofstream out(strFile.c_str(), std::ios::out); - if (out) + std::wstring defaultIni = GetPath() + L"Default.ini"; + if (_waccess(defaultIni.c_str(), 0) == -1) { - out << std::string("[Rainmeter]\n\n[TrayMeasure]\nMeasure=CPU\n\n[Tranquil\\System]\nActive=1\n"); - out.close(); + // The default.ini wasn't found -> create new + std::ofstream out(strFile.c_str(), std::ios::out); + if (out) + { + out << std::string("[Rainmeter]\n\n[TrayMeasure]\nMeasure=CPU\n\n[Tranquil\\System]\nActive=1\n"); + out.close(); + } + } + else + { + // The folder was created successfully which means that it wasn't available yet. + // Copy the default skin to the Skins folder + std::wstring strFrom(defaultIni); + std::wstring strTo(GetIniFile()); + + // The strings must end with double nul + strFrom.append(L"0"); + strFrom[strFrom.size() - 1] = L'\0'; + strTo.append(L"0"); + strTo[strTo.size() - 1] = L'\0'; + + SHFILEOPSTRUCT fo = {0}; + fo.wFunc = FO_COPY; + fo.pFrom = strFrom.c_str(); + fo.pTo = strTo.c_str(); + fo.fFlags = FOF_NO_UI; + + int result = SHFileOperation(&fo); + if (result != 0) + { + DebugLog(L"Unable to copy the default settings file %i", result); + } } } @@ -1425,7 +1481,7 @@ void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow) void CRainmeter::ReadGeneralSettings(std::wstring& iniFile) { CConfigParser parser; - parser.Initialize(iniFile.c_str()); + parser.Initialize(iniFile.c_str(), this); if (m_TrayWindow) { @@ -1926,14 +1982,12 @@ void CRainmeter::TestSettingsFile(bool bDefaultIniLocation) if (!bDefaultIniLocation) { - WCHAR buffer[4096] = {0}; // lets hope the buffer is large enough... - // Expand the environment variables - ExpandEnvironmentStrings(L"%APPDATA%\\Rainmeter\\", buffer, 4096); + std::wstring strTarget = ExpandEnvironmentVariables(L"%APPDATA%\\Rainmeter\\"); error += L"You should quit Rainmeter and move the settings file from\n\n"; error += m_IniFile; error += L"\n\nto\n\n"; - error += buffer; + error += strTarget; error += L"\n\nAlternatively you can also just remove the file and\n"; error += L"it will be automatically recreated to the correct location\n"; error += L"when Rainmeter is restarted the next time (you\'ll lose your\n"; @@ -1953,4 +2007,34 @@ void CRainmeter::TestSettingsFile(bool bDefaultIniLocation) { DebugLog(L"The rainmeter.ini file is writable."); } -} \ No newline at end of file +} + +std::wstring CRainmeter::ExtractPath(const std::wstring& strFilePath) +{ + size_t pos = strFilePath.rfind(L"\\"); + if (pos != std::wstring::npos) + { + return strFilePath.substr(0, pos + 1); + } + return L"."; +} + +std::wstring CRainmeter::ExpandEnvironmentVariables(const std::wstring strPath) +{ + if (strPath.find(L'%') != std::wstring::npos) + { + WCHAR buffer[4096]; // lets hope the buffer is large enough... + + // Expand the environment variables + DWORD ret = ExpandEnvironmentStrings(strPath.c_str(), buffer, 4096); + if (ret != 0 && ret < 4096) + { + return buffer; + } + else + { + DebugLog(L"Unable to expand the environment strings for string: %s", strPath.c_str()); + } + } + return strPath; +} diff --git a/Library/Rainmeter.h b/Library/Rainmeter.h index 51784391..2a0d094a 100644 --- a/Library/Rainmeter.h +++ b/Library/Rainmeter.h @@ -121,6 +121,7 @@ public: const std::wstring& GetLogFile() { return m_LogFile; }; const std::wstring& GetSkinPath() { return m_SkinPath; }; const std::wstring& GetPluginPath() { return m_PluginPath; }; + std::wstring GetSettingsPath() { return ExtractPath(m_IniFile); }; const std::wstring& GetConfigEditor() { return m_ConfigEditor; }; const std::wstring& GetStatsDate() { return m_StatsDate; }; @@ -158,6 +159,8 @@ public: void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow); static PLATFORM IsNT(); + static std::wstring ExtractPath(const std::wstring& strFilePath); + static std::wstring ExpandEnvironmentVariables(const std::wstring strPath); private: void CreateMeterWindow(std::wstring path, std::wstring config, std::wstring iniFile); diff --git a/revision-number.h b/revision-number.h index 79e8ea33..f449038e 100644 --- a/revision-number.h +++ b/revision-number.h @@ -1,2 +1,2 @@ #pragma once -const int revision_number = 89; \ No newline at end of file +const int revision_number = 93; \ No newline at end of file