Skip to content

Commit 0513e63

Browse files
committed
Moved the logs directory from %USERPROFILE%\ShellAnything\Logs to %LOCALAPPDATA%\ShellAnything\logs. #108
1 parent 84140ab commit 0513e63

File tree

6 files changed

+128
-20
lines changed

6 files changed

+128
-20
lines changed

CHANGES

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
Changes for 0.10.0
22

3-
* **Breaking change:** The _Configuration Files_ directory has moved from `%USERPROFILE%\ShellAnything` to `%USERPROFILE%\ShellAnything\configurations`. On first application launch, Configuration Files in the old directory will move to the new directory automatically. Other files in `%USERPROFILE%\ShellAnything` will not be moved.
3+
* **Breaking change:** The _Configuration Files_ directory has moved from `%USERPROFILE%\ShellAnything` to `%USERPROFILE%\ShellAnything\configurations`. Configuration Files in the old directory will move to the new directory automatically on application first launch. Other files in `%USERPROFILE%\ShellAnything` will not be moved.
4+
* **Breaking change:** The _logs_ directory has moved from `%USERPROFILE%\ShellAnything\Logs` to `%LOCALAPPDATA%\ShellAnything\logs`. The previous logs directory will be removed on application first launch.
45
* ShellAnything has a new high-resolution logo icon!
56
* Shellanything now features verbose logging mode and command line arguments debugging tools.
67
* ShellAnything now packages icons from [icons8/flat-color-icons](https://github.com/icons8/flat-color-icons).
78

89
Fixes:
910
* Fixed issue #6 : (twice) Right-click on a directory with Windows Explorer in the left panel shows the menus twice.
1011
* Fixed issue #31 : (twice) Error in logs for CContextMenu::GetCommandString()
12+
* Fixed issue #108: Separate location for log files ? (and exclusions?)
1113
* Fixed issue #109: Implement default and verbose logging.
1214
* Fixed issue #110: Create a simple command line arguments debugging application.
1315
* Fixed issue #148: Can't uninstall.

UserManual.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,9 +2651,7 @@ ShellAnything provides logging support for troubleshooting and debugging command
26512651

26522652
The logging directory is unique for each users of the system.
26532653

2654-
The log files are stored in `C:\Users\%USERNAME%\ShellAnything\Logs` directory where `%USERNAME%` matches your current login username.
2655-
For example, the user `JohnSmith` can find his own ShellAnything log files in directory `C:\Users\JohnSmith\ShellAnything\Logs`.
2656-
2654+
The log files are stored in `%LOCALAPPDATA%\ShellAnything\logs` directory. For example, the user `JohnSmith` can find his own ShellAnything log files in directory `C:\Users\JohnSmith\AppData\Local\ShellAnything\logs`.
26572655

26582656

26592657
### Filename Format ###

src/core/App.cpp

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,14 @@ namespace shellanything
163163
return false;
164164
}
165165

166+
std::string App::GetLegacyLogsDirectory()
167+
{
168+
//get home directory of the user
169+
std::string home_dir = ra::user::GetHomeDirectoryUtf8();
170+
std::string legacy_dir = home_dir + "\\" + app_name + "\\Logs";
171+
return legacy_dir;
172+
}
173+
166174
std::string App::GetLogDirectory()
167175
{
168176
//Issue #10 - Change the log directory if run from the unit tests executable
@@ -195,21 +203,30 @@ namespace shellanything
195203
//This DLL is most probably executed by the shell (File Explorer).
196204

197205
//By default, GLOG will output log files in %TEMP% directory.
198-
//However, I prefer to use %USERPROFILE%\ShellAnything\logs
199-
std::string log_dir = ra::user::GetHomeDirectoryUtf8();
200-
if (!log_dir.empty())
206+
207+
// Issue #108. Log files should be stored in %LOCALAPPDATA%\ShellAnything\logs
208+
std::string localappdata_dir = ra::environment::GetEnvironmentVariableUtf8("LOCALAPPDATA");
209+
if (!localappdata_dir.empty() && ra::filesystem::DirectoryExistsUtf8(localappdata_dir.c_str()))
210+
{
211+
std::string log_dir = localappdata_dir + "\\" + app_name + "\\logs";
212+
if (IsValidLogDirectory(log_dir))
213+
return log_dir;
214+
}
215+
216+
// Fallback to %USERPROFILE%\ShellAnything\logs
217+
std::string home_dir = ra::user::GetHomeDirectoryUtf8();
218+
if (!home_dir.empty() && ra::filesystem::DirectoryExistsUtf8(home_dir.c_str()))
201219
{
202220
//We got the %USERPROFILE% directory.
203-
//Now add our custom path to it
204-
log_dir.append("\\" + app_name + "\\logs");
221+
std::string log_dir = home_dir + "\\" + app_name + "\\logs";
205222
if (IsValidLogDirectory(log_dir))
206223
return log_dir;
207224
}
208225

209226
//Failed getting HOME directory.
210227
//Fallback to using %TEMP%.
211-
log_dir = ra::environment::GetEnvironmentVariableUtf8("TEMP");
212-
return log_dir;
228+
std::string temp_dir = ra::environment::GetEnvironmentVariableUtf8("TEMP");
229+
return temp_dir;
213230
}
214231

215232
std::string App::GetLegacyConfigurationsDirectory()
@@ -329,16 +346,17 @@ namespace shellanything
329346
}
330347
}
331348

332-
void App::ClearLegacyConfigurationDirectory(const std::string& legacy_dir)
349+
void App::ClearLegacyConfigurationDirectory()
333350
{
351+
const std::string legacy_config_dir = GetLegacyConfigurationsDirectory();
334352
const std::string config_dir = GetConfigurationsDirectory();
335-
if (legacy_dir == config_dir)
353+
if (legacy_config_dir == config_dir)
336354
return; // nothing to do
337355

338356
// Search for xml files directly under legacy_dir
339357
ra::strings::StringVector files;
340358
static const int depth = 0; // Do not search recursively
341-
bool success = ra::filesystem::FindFilesUtf8(files, legacy_dir.c_str(), depth);
359+
bool success = ra::filesystem::FindFilesUtf8(files, legacy_config_dir.c_str(), depth);
342360
if (!success)
343361
return; // aborted
344362

@@ -366,18 +384,65 @@ namespace shellanything
366384
}
367385
}
368386

387+
void App::ClearLegacyLogsDirectory()
388+
{
389+
const std::string legacy_logs_dir = GetLegacyLogsDirectory();
390+
391+
// Search for log files directly under legacy_logs_dir
392+
ra::strings::StringVector files;
393+
static const int depth = 0; // Do not search recursively
394+
bool success = ra::filesystem::FindFilesUtf8(files, legacy_logs_dir.c_str(), depth);
395+
if (!success)
396+
return; // aborted
397+
398+
// for each file found
399+
for (size_t i = 0; i < files.size(); i++)
400+
{
401+
const std::string& file_path = files[i];
402+
403+
// Is that a configuration file ?
404+
if (LoggerHelper::IsValidLogFile(file_path))
405+
{
406+
// It does not belongs there.
407+
// Delete the file
408+
SA_LOG(INFO) << "Deleting old legacy log file '" << file_path << "'.";
409+
bool deleted = ra::filesystem::DeleteFileUtf8(file_path.c_str());
410+
if (!deleted)
411+
{
412+
SA_LOG(ERROR) << "Failed deleting old legacy log file '" << file_path << "'.";
413+
}
414+
}
415+
}
416+
417+
// Check if the directory is empty.
418+
// We need to make this check before calling ra::filesystel::DeleteDirectory() because the
419+
// DeleteDirectory function will automatically delete remaining files in order to delete the directory.
420+
// We need to make sure the directory is empty first.
421+
bool empty = ra::filesystem::IsDirectoryEmptyUtf8(legacy_logs_dir);
422+
if (empty)
423+
{
424+
// Now it is safe to delete the directory
425+
SA_LOG(INFO) << "Deleting old legacy log directory '" << legacy_logs_dir << "'.";
426+
ra::filesystem::DeleteDirectoryUtf8(legacy_logs_dir.c_str());
427+
}
428+
else
429+
{
430+
SA_LOG(ERROR) << "Skipped deleting old legacy log directory '" << legacy_logs_dir << "'. The directory is not empty. The directory likely contains files that are not log files.";
431+
}
432+
}
433+
369434
void App::InitConfigManager()
370435
{
371436
shellanything::ConfigManager& cmgr = shellanything::ConfigManager::GetInstance();
372437

373-
std::string legacy_dir = GetLegacyConfigurationsDirectory();
374438
std::string config_dir = GetConfigurationsDirectory();
375439

376440
bool first_run = IsFirstApplicationRun(app_name, app_version);
377441
if (first_run)
378442
{
379443
SA_LOG(INFO) << "First application launch.";
380-
ClearLegacyConfigurationDirectory(legacy_dir); // Issue #108 moved Configuration Files directory to a new location.
444+
ClearLegacyConfigurationDirectory(); // Issue #108 moved Configuration Files directory to a new location.
445+
ClearLegacyLogsDirectory(); // Issue #108 delete previous logs directory.
381446
InstallDefaultConfigurations(config_dir);
382447
}
383448

@@ -394,10 +459,10 @@ namespace shellanything
394459
//get home directory of the user
395460
std::string home_dir = ra::user::GetHomeDirectoryUtf8();
396461
std::string config_dir = GetConfigurationsDirectory();
397-
std::string log_dir = ra::unicode::AnsiToUtf8(GetLogDirectory());
462+
std::string log_dir = GetLogDirectory();
398463

399464
SA_LOG(INFO) << "HOME directory : " << home_dir.c_str();
400-
SA_LOG(INFO) << "Config directory : " << config_dir.c_str();
465+
SA_LOG(INFO) << "CONFIG directory : " << config_dir.c_str();
401466
SA_LOG(INFO) << "LOG directory : " << log_dir.c_str();
402467

403468
//define global properties

src/core/App.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ namespace shellanything
182182
/// <returns>Returns true if application is loaded in a test environment. Returns false otherwise.</returns>
183183
bool IsTestingEnvironment();
184184

185+
/// <summary>
186+
/// Get the application's legacy log directory. The returned directory has write access.
187+
/// </summary>
188+
/// <returns>Returns the path of the legacy directory that was used by the logging framework.</returns>
189+
std::string GetLegacyLogsDirectory();
190+
185191
/// <summary>
186192
/// Get the application's log directory. The returned directory has write access.
187193
/// </summary>
@@ -242,9 +248,16 @@ namespace shellanything
242248
void InstallDefaultConfigurations(const std::string& dest_dir);
243249

244250
/// <summary>
245-
/// Moved any Configuration Files from the given legacy directory to the official configurations directory.
251+
/// Moved any Configuration Files from the legacy directory to the official configurations directory.
252+
/// The term legacy refers to version 0.9.0 and older.
253+
/// </summary>
254+
void ClearLegacyConfigurationDirectory();
255+
256+
/// <summary>
257+
/// Delete any log files from the legacy logs directory.
258+
/// The term legacy refers to version 0.9.0 and older.
246259
/// </summary>
247-
void ClearLegacyConfigurationDirectory(const std::string& legacy_dir);
260+
void ClearLegacyLogsDirectory();
248261

249262
/// <summary>
250263
/// Initialize the Configuration Manager to the user's stall the original configuration files to the specified destination directory.

src/core/LoggerHelper.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <string>
3131

3232
#include "rapidassist/strings.h"
33+
#include "rapidassist/filesystem_utf8.h"
34+
#include "rapidassist/unicode.h"
3335

3436
namespace shellanything
3537
{
@@ -127,6 +129,27 @@ namespace shellanything
127129
return has_vebose_logging;
128130
}
129131

132+
bool LoggerHelper::IsValidLogFile(const std::string& path)
133+
{
134+
std::string file_extension = ra::filesystem::GetFileExtention(path);
135+
file_extension = ra::strings::Uppercase(file_extension);
136+
137+
if (file_extension != "LOG")
138+
return false;
139+
140+
// Peek at the file for validating content
141+
std::string data;
142+
bool peeked = ra::filesystem::PeekFileUtf8(path, 1024 * 1024, data);
143+
if (!peeked)
144+
return false;
145+
146+
bool valid = ra::unicode::IsValidUtf8(data.c_str());
147+
if (!valid)
148+
return false; // the file might contain binary data
149+
150+
return true;
151+
}
152+
130153
// ------------------------------------------------------------------------------------------------------------------------------------------------------------
131154
// ------------------------------------------------------------------------------------------------------------------------------------------------------------
132155

src/core/LoggerHelper.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ namespace shellanything
6666
/// <returns>Returns true when verbose logging is enabled. Returns false otherwise.</returns>
6767
static bool IsVerboseLoggingEnabled();
6868

69+
/// <summary>
70+
/// Detect if a given file is a valid log file.
71+
/// </summary>
72+
/// <param name="path">The file path to check</param>
73+
/// <returns>Returns true if the file is a valid log file. Returns false otherwise.</returns>
74+
static bool IsValidLogFile(const std::string& path);
75+
6976
private:
7077
ILoggerService::LOG_LEVEL mLevel;
7178
bool mIsVerboseStream;

0 commit comments

Comments
 (0)