mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public interface ISettingsPath
|
||||
{
|
||||
bool SettingsFolderExists(string powertoy);
|
||||
|
||||
void CreateSettingsFolder(string powertoy);
|
||||
|
||||
void DeleteSettings(string powertoy = "");
|
||||
|
||||
string GetSettingsPath(string powertoy, string fileName);
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
|
||||
<PackageReference Include="System.Text.Json" Version="4.7.2" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers">
|
||||
<Version>3.3.0</Version>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class SettingPath : ISettingsPath
|
||||
{
|
||||
private const string DefaultFileName = "settings.json";
|
||||
|
||||
private readonly IDirectory _directory;
|
||||
|
||||
private readonly IPath _path;
|
||||
|
||||
public SettingPath(IDirectory directory, IPath path)
|
||||
{
|
||||
_directory = directory ?? throw new ArgumentNullException(nameof(directory));
|
||||
_path = path ?? throw new ArgumentNullException(nameof(path));
|
||||
}
|
||||
|
||||
public bool SettingsFolderExists(string powertoy)
|
||||
{
|
||||
return _directory.Exists(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
public void CreateSettingsFolder(string powertoy)
|
||||
{
|
||||
_directory.CreateDirectory(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
public void DeleteSettings(string powertoy = "")
|
||||
{
|
||||
_directory.Delete(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
private static string LocalApplicationDataFolder()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get path to the json settings file.
|
||||
/// </summary>
|
||||
/// <returns>string path.</returns>
|
||||
public string GetSettingsPath(string powertoy, string fileName = DefaultFileName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(powertoy))
|
||||
{
|
||||
return _path.Combine(
|
||||
LocalApplicationDataFolder(),
|
||||
$"Microsoft\\PowerToys\\{fileName}");
|
||||
}
|
||||
|
||||
return _path.Combine(
|
||||
LocalApplicationDataFolder(),
|
||||
$"Microsoft\\PowerToys\\{powertoy}\\{fileName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
@@ -15,49 +16,34 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
private const string DefaultFileName = "settings.json";
|
||||
private const string DefaultModuleName = "";
|
||||
private IIOProvider _ioProvider;
|
||||
private readonly IFile _file;
|
||||
private readonly ISettingsPath _settingsPath;
|
||||
|
||||
public SettingsUtils(IIOProvider ioProvider)
|
||||
public SettingsUtils()
|
||||
: this(new FileSystem())
|
||||
{
|
||||
_ioProvider = ioProvider ?? throw new ArgumentNullException(nameof(ioProvider));
|
||||
}
|
||||
|
||||
private bool SettingsFolderExists(string powertoy)
|
||||
public SettingsUtils(IFileSystem fileSystem)
|
||||
: this(fileSystem?.File, new SettingPath(fileSystem?.Directory, fileSystem?.Path))
|
||||
{
|
||||
return _ioProvider.DirectoryExists(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
private void CreateSettingsFolder(string powertoy)
|
||||
public SettingsUtils(IFile file, ISettingsPath settingPath)
|
||||
{
|
||||
_ioProvider.CreateDirectory(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
public void DeleteSettings(string powertoy = "")
|
||||
{
|
||||
_ioProvider.DeleteDirectory(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get path to the json settings file.
|
||||
/// </summary>
|
||||
/// <returns>string path.</returns>
|
||||
public static string GetSettingsPath(string powertoy, string fileName = DefaultFileName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(powertoy))
|
||||
{
|
||||
return System.IO.Path.Combine(
|
||||
LocalApplicationDataFolder(),
|
||||
$"Microsoft\\PowerToys\\{fileName}");
|
||||
}
|
||||
|
||||
return System.IO.Path.Combine(
|
||||
LocalApplicationDataFolder(),
|
||||
$"Microsoft\\PowerToys\\{powertoy}\\{fileName}");
|
||||
_file = file ?? throw new ArgumentNullException(nameof(file));
|
||||
_settingsPath = settingPath;
|
||||
}
|
||||
|
||||
public bool SettingsExists(string powertoy = DefaultModuleName, string fileName = DefaultFileName)
|
||||
{
|
||||
return _ioProvider.FileExists(GetSettingsPath(powertoy, fileName));
|
||||
var settingsPath = _settingsPath.GetSettingsPath(powertoy, fileName);
|
||||
return _file.Exists(settingsPath);
|
||||
}
|
||||
|
||||
public void DeleteSettings(string powertoy = "")
|
||||
{
|
||||
_settingsPath.DeleteSettings(powertoy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -106,7 +92,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
// Look at issue https://github.com/microsoft/PowerToys/issues/6413 you'll see the file has a large sum of \0 to fill up a 4096 byte buffer for writing to disk
|
||||
// This, while not totally ideal, does work around the problem by trimming the end.
|
||||
// The file itself did write the content correctly but something is off with the actual end of the file, hence the 0x00 bug
|
||||
var jsonSettingsString = _ioProvider.ReadAllText(GetSettingsPath(powertoyFolderName, fileName)).Trim('\0');
|
||||
var jsonSettingsString = _file.ReadAllText(_settingsPath.GetSettingsPath(powertoyFolderName, fileName)).Trim('\0');
|
||||
return JsonSerializer.Deserialize<T>(jsonSettingsString);
|
||||
}
|
||||
|
||||
@@ -118,12 +104,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
if (jsonSettings != null)
|
||||
{
|
||||
if (!SettingsFolderExists(powertoy))
|
||||
if (!_settingsPath.SettingsFolderExists(powertoy))
|
||||
{
|
||||
CreateSettingsFolder(powertoy);
|
||||
_settingsPath.CreateSettingsFolder(powertoy);
|
||||
}
|
||||
|
||||
_ioProvider.WriteAllText(GetSettingsPath(powertoy, fileName), jsonSettings);
|
||||
_file.WriteAllText(_settingsPath.GetSettingsPath(powertoy, fileName), jsonSettings);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -137,10 +123,5 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private static string LocalApplicationDataFolder()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.CustomAction;
|
||||
@@ -13,6 +14,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
{
|
||||
public static class Helper
|
||||
{
|
||||
public static readonly IFileSystem FileSystem = new FileSystem();
|
||||
|
||||
public static bool AllowRunnerToForeground()
|
||||
{
|
||||
var result = false;
|
||||
@@ -47,22 +50,20 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
return sendCustomAction.ToJsonString();
|
||||
}
|
||||
|
||||
public static FileSystemWatcher GetFileWatcher(string moduleName, string fileName, Action onChangedCallback)
|
||||
public static IFileSystemWatcher GetFileWatcher(string moduleName, string fileName, Action onChangedCallback)
|
||||
{
|
||||
var path = Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{moduleName}");
|
||||
var path = FileSystem.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{moduleName}");
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
if (!FileSystem.Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
FileSystem.Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
var watcher = new FileSystemWatcher
|
||||
{
|
||||
Path = path,
|
||||
Filter = fileName,
|
||||
NotifyFilter = NotifyFilters.LastWrite,
|
||||
EnableRaisingEvents = true,
|
||||
};
|
||||
var watcher = FileSystem.FileSystemWatcher.CreateNew();
|
||||
watcher.Path = path;
|
||||
watcher.Filter = fileName;
|
||||
watcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
watcher.Changed += (o, e) => onChangedCallback();
|
||||
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
private static readonly string ApplicationLogPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\\PowerToys\\Settings Logs");
|
||||
|
||||
static Logger()
|
||||
|
||||
@@ -2,41 +2,61 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
{
|
||||
public class SystemIOProvider : IIOProvider
|
||||
{
|
||||
private readonly IDirectory _directory;
|
||||
private readonly IFile _file;
|
||||
|
||||
public SystemIOProvider()
|
||||
: this(new FileSystem())
|
||||
{
|
||||
}
|
||||
|
||||
public SystemIOProvider(IFileSystem fileSystem)
|
||||
: this(fileSystem?.Directory, fileSystem?.File)
|
||||
{
|
||||
}
|
||||
|
||||
private SystemIOProvider(IDirectory directory, IFile file)
|
||||
{
|
||||
_directory = directory ?? throw new ArgumentNullException(nameof(directory));
|
||||
_file = file ?? throw new ArgumentNullException(nameof(file));
|
||||
}
|
||||
|
||||
public bool CreateDirectory(string path)
|
||||
{
|
||||
var directioryInfo = Directory.CreateDirectory(path);
|
||||
var directioryInfo = _directory.CreateDirectory(path);
|
||||
return directioryInfo != null;
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string path)
|
||||
{
|
||||
Directory.Delete(path, recursive: true);
|
||||
_directory.Delete(path, recursive: true);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
{
|
||||
return Directory.Exists(path);
|
||||
return _directory.Exists(path);
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return File.Exists(path);
|
||||
return _file.Exists(path);
|
||||
}
|
||||
|
||||
public string ReadAllText(string path)
|
||||
{
|
||||
return File.ReadAllText(path);
|
||||
return _file.ReadAllText(path);
|
||||
}
|
||||
|
||||
public void WriteAllText(string path, string content)
|
||||
{
|
||||
File.WriteAllText(path, content);
|
||||
_file.WriteAllText(path, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
|
||||
{
|
||||
@@ -15,6 +13,9 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
|
||||
{
|
||||
public const string RootPathStubFiles = "..\\..\\..\\..\\src\\core\\Microsoft.PowerToys.Settings.UI.UnitTests\\BackwardsCompatibility\\TestFiles\\{0}\\Microsoft\\PowerToys\\{1}\\{2}";
|
||||
|
||||
// Using Ordinal since this is used internally for a path
|
||||
private static readonly Expression<Func<string, bool>> SettingsFilterExpression = s => s == null || s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
|
||||
|
||||
internal class MockSettingsRepository<T> : ISettingsRepository<T> where T : ISettingsConfig, new()
|
||||
{
|
||||
T _settingsConfig;
|
||||
@@ -43,46 +44,56 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
|
||||
}
|
||||
|
||||
|
||||
public static Mock<IIOProvider>GetModuleIOProvider(string version, string module, string fileName)
|
||||
public static Mock<IFile>GetModuleIOProvider(string version, string module, string fileName)
|
||||
{
|
||||
// Using StringComparison.Ordinal / CultureInfo.InvariantCulture since this is used internally
|
||||
var stubSettingsPath = string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, module, fileName);
|
||||
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains(module, StringComparison.Ordinal);
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOReadWithStubFile(stubSettingsPath, filterExpression);
|
||||
return mockIOProvider;
|
||||
|
||||
var stubSettingsPath = StubSettingsPath(version, module, fileName);
|
||||
Expression<Func<string, bool>> filterExpression = ModuleFilterExpression(module);
|
||||
return IIOProviderMocks.GetMockIOReadWithStubFile(stubSettingsPath, filterExpression);
|
||||
}
|
||||
|
||||
public static void VerifyModuleIOProviderWasRead(Mock<IIOProvider> provider, string module, int expectedCallCount)
|
||||
public static string StubGeneralSettingsPath(string version)
|
||||
{
|
||||
return StubSettingsPath(version, string.Empty, "settings.json");
|
||||
}
|
||||
|
||||
public static string StubSettingsPath(string version, string module, string fileName)
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, module, fileName);
|
||||
}
|
||||
|
||||
public static void VerifyModuleIOProviderWasRead(Mock<IFile> provider, string module, int expectedCallCount)
|
||||
{
|
||||
if(provider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
// Using Ordinal since this is used internally
|
||||
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains(module, StringComparison.Ordinal);
|
||||
Expression<Func<string, bool>> filterExpression = ModuleFilterExpression(module);
|
||||
|
||||
IIOProviderMocks.VerifyIOReadWithStubFile(provider, filterExpression, expectedCallCount);
|
||||
}
|
||||
|
||||
public static Mock<IIOProvider> GetGeneralSettingsIOProvider(string version)
|
||||
private static Expression<Func<string, bool>> ModuleFilterExpression(string module)
|
||||
{
|
||||
// Using StringComparison.Ordinal / CultureInfo.InvariantCulture since this is used internally for a path
|
||||
var stubGeneralSettingsPath = string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, string.Empty, "settings.json");
|
||||
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
|
||||
var mockGeneralIOProvider = IIOProviderMocks.GetMockIOReadWithStubFile(stubGeneralSettingsPath, filterExpression);
|
||||
return mockGeneralIOProvider;
|
||||
// Using Ordinal since this is used internally for a path
|
||||
return s => s == null || s.Contains(module, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static void VerifyGeneralSettingsIOProviderWasRead(Mock<IIOProvider> provider, int expectedCallCount)
|
||||
public static Mock<IFile> GetGeneralSettingsIOProvider(string version)
|
||||
{
|
||||
var stubGeneralSettingsPath = StubGeneralSettingsPath(version);
|
||||
return IIOProviderMocks.GetMockIOReadWithStubFile(stubGeneralSettingsPath, SettingsFilterExpression);
|
||||
}
|
||||
|
||||
public static void VerifyGeneralSettingsIOProviderWasRead(Mock<IFile> provider, int expectedCallCount)
|
||||
{
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
// Using Ordinal since this is used internally for a path
|
||||
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
|
||||
IIOProviderMocks.VerifyIOReadWithStubFile(provider, filterExpression, expectedCallCount);
|
||||
|
||||
IIOProviderMocks.VerifyIOReadWithStubFile(provider, SettingsFilterExpression, expectedCallCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="12.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.UnitTests.Mocks
|
||||
{
|
||||
@@ -41,6 +40,8 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.Mocks
|
||||
|
||||
|
||||
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
/// <summary>
|
||||
/// This method mocks an IO provider so that it will always return data at the savePath location.
|
||||
/// This mock is specific to a given module, and is verifiable that the stub file was read.
|
||||
@@ -48,25 +49,25 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.Mocks
|
||||
/// <param name="savePath">The path to the stub settings file</param>
|
||||
/// <param name="expectedPathSubstring">The substring in the path that identifies the module eg. Microsoft\\PowerToys\\ColorPicker</param>
|
||||
/// <returns></returns>
|
||||
internal static Mock<IIOProvider> GetMockIOReadWithStubFile(string savePath, Expression<Func<string, bool>> filterExpression)
|
||||
internal static Mock<IFile> GetMockIOReadWithStubFile(string savePath, Expression<Func<string, bool>> filterExpression)
|
||||
{
|
||||
string saveContent = File.ReadAllText(savePath);
|
||||
var mockIOProvider = new Mock<IIOProvider>();
|
||||
var fileMock = new Mock<IFile>();
|
||||
|
||||
|
||||
mockIOProvider.Setup(x => x.ReadAllText(It.Is<string>(filterExpression)))
|
||||
fileMock.Setup(x => x.ReadAllText(It.Is<string>(filterExpression)))
|
||||
.Returns(() => saveContent).Verifiable();
|
||||
|
||||
|
||||
mockIOProvider.Setup(x => x.FileExists(It.Is<string>(filterExpression)))
|
||||
fileMock.Setup(x => x.Exists(It.Is<string>(filterExpression)))
|
||||
.Returns(true);
|
||||
|
||||
return mockIOProvider;
|
||||
return fileMock;
|
||||
}
|
||||
|
||||
internal static void VerifyIOReadWithStubFile(Mock<IIOProvider> mockIOProvider, Expression<Func<string, bool>> filterExpression, int expectedCallCount)
|
||||
internal static void VerifyIOReadWithStubFile(Mock<IFile> fileMock, Expression<Func<string, bool>> filterExpression, int expectedCallCount)
|
||||
{
|
||||
mockIOProvider.Verify(x => x.ReadAllText(It.Is<string>(filterExpression)), Times.Exactly(expectedCallCount));
|
||||
fileMock.Verify(x => x.ReadAllText(It.Is<string>(filterExpression)), Times.Exactly(expectedCallCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ using System;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using Microsoft.PowerToys.Settings.UnitTest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
@@ -25,11 +25,8 @@ namespace CommonLibTest
|
||||
public void ToJsonStringShouldReturnValidJSONOfModelWhenSuccessful()
|
||||
{
|
||||
//Mock Disk access
|
||||
string saveContent = string.Empty;
|
||||
string savePath = string.Empty;
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
|
||||
var settingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var mockFileSystem = new MockFileSystem();
|
||||
var settingsUtils = new SettingsUtils(mockFileSystem);
|
||||
|
||||
// Arrange
|
||||
string file_name = "test\\BasePTModuleSettingsTest";
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
@@ -25,9 +26,9 @@ namespace CommonLibTest
|
||||
public void SaveSettingsSaveSettingsToFileWhenFilePathExists()
|
||||
{
|
||||
// Arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var settingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
|
||||
var mockFileSystem = new MockFileSystem();
|
||||
var settingsUtils = new SettingsUtils(mockFileSystem);
|
||||
|
||||
string file_name = "\\test";
|
||||
string file_contents_correct_json_content = "{\"name\":\"powertoy module name\",\"version\":\"powertoy version\"}";
|
||||
|
||||
@@ -45,8 +46,8 @@ namespace CommonLibTest
|
||||
public void SaveSettingsShouldCreateFileWhenFilePathIsNotFound()
|
||||
{
|
||||
// Arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var settingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var mockFileSystem = new MockFileSystem();
|
||||
var settingsUtils = new SettingsUtils(mockFileSystem);
|
||||
string file_name = "test\\Test Folder";
|
||||
string file_contents_correct_json_content = "{\"name\":\"powertoy module name\",\"version\":\"powertoy version\"}";
|
||||
|
||||
@@ -63,8 +64,8 @@ namespace CommonLibTest
|
||||
public void SettingsFolderExistsShouldReturnFalseWhenFilePathIsNotFound()
|
||||
{
|
||||
// Arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var settingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var mockFileSystem = new MockFileSystem();
|
||||
var settingsUtils = new SettingsUtils(mockFileSystem);
|
||||
string file_name_random = "test\\" + RandomString();
|
||||
string file_name_exists = "test\\exists";
|
||||
string file_contents_correct_json_content = "{\"name\":\"powertoy module name\",\"version\":\"powertoy version\"}";
|
||||
@@ -84,8 +85,8 @@ namespace CommonLibTest
|
||||
public void SettingsUtilsMustReturnDefaultItemWhenFileIsCorrupt()
|
||||
{
|
||||
// Arrange
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider("CorruptJson", string.Empty, "settings.json");
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var mockFileSystem = new MockFileSystem();
|
||||
var mockSettingsUtils = new SettingsUtils(mockFileSystem);
|
||||
|
||||
// Act
|
||||
TestClass settings = mockSettingsUtils.GetSettings<TestClass>(string.Empty);
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
|
||||
namespace ViewModelTests
|
||||
{
|
||||
@@ -27,11 +26,14 @@ namespace ViewModelTests
|
||||
{
|
||||
//Arrange
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, ColorPickerSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object, settingPathMock.Object);
|
||||
ColorPickerSettings originalSettings = mockSettingsUtils.GetSettings<ColorPickerSettings>(ColorPickerSettings.ModuleName);
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using CommonLibTest;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
@@ -33,13 +30,16 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0", "settings.json")]
|
||||
public void OriginalFilesModificationTest(string version, string fileName)
|
||||
{
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, FancyZonesSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
|
||||
var fileMock = BackCompatTestProperties.GetModuleIOProvider(version, FancyZonesSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(fileMock.Object, settingPathMock.Object);
|
||||
FancyZonesSettings originalSettings = mockSettingsUtils.GetSettings<FancyZonesSettings>(FancyZonesSettings.ModuleName);
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
var fancyZonesRepository = new BackCompatTestProperties.MockSettingsRepository<FancyZonesSettings>(mockSettingsUtils);
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace ViewModelTests
|
||||
|
||||
//Verify that the stub file was used
|
||||
var expectedCallCount = 2; //once via the view model, and once by the test (GetSettings<T>)
|
||||
BackCompatTestProperties.VerifyModuleIOProviderWasRead(mockIOProvider, FancyZonesSettings.ModuleName, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyModuleIOProviderWasRead(fileMock, FancyZonesSettings.ModuleName, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyGeneralSettingsIOProviderWasRead(mockGeneralIOProvider, expectedCallCount);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
@@ -12,7 +11,7 @@ using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using NuGet.Frameworks;
|
||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||
|
||||
namespace ViewModelTests
|
||||
{
|
||||
@@ -40,16 +39,20 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0")]
|
||||
public void OriginalFilesModificationTest(string version)
|
||||
{
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
var fileMock = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(fileMock.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
|
||||
|
||||
// Initialise View Model with test Config files
|
||||
// Arrange
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => 0;
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => 0;
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => 0;
|
||||
var viewModel = new GeneralViewModel(
|
||||
settingsRepository: generalSettingsRepository,
|
||||
runAsAdminText: "GeneralSettings_RunningAsAdminText",
|
||||
@@ -71,7 +74,7 @@ namespace ViewModelTests
|
||||
|
||||
//Verify that the stub file was used
|
||||
var expectedCallCount = 2; //once via the view model, and once by the test (GetSettings<T>)
|
||||
BackCompatTestProperties.VerifyGeneralSettingsIOProviderWasRead(mockGeneralIOProvider, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyGeneralSettingsIOProviderWasRead(fileMock, expectedCallCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -82,7 +85,7 @@ namespace ViewModelTests
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
@@ -119,7 +122,7 @@ namespace ViewModelTests
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
@@ -151,7 +154,7 @@ namespace ViewModelTests
|
||||
|
||||
// Arrange
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
@@ -184,7 +187,7 @@ namespace ViewModelTests
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
viewModel = new GeneralViewModel(
|
||||
SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
@@ -215,7 +218,7 @@ namespace ViewModelTests
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
@@ -20,16 +20,15 @@ namespace ViewModelTests
|
||||
[TestClass]
|
||||
public class ImageResizer
|
||||
{
|
||||
private Mock<ISettingsUtils> _mockGeneralSettingsUtils;
|
||||
|
||||
private Mock<ISettingsUtils> mockGeneralSettingsUtils;
|
||||
|
||||
private Mock<ISettingsUtils> mockImgResizerSettingsUtils;
|
||||
private Mock<ISettingsUtils> _mockImgResizerSettingsUtils;
|
||||
|
||||
[TestInitialize]
|
||||
public void SetUpStubSettingUtils()
|
||||
{
|
||||
mockGeneralSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<GeneralSettings>();
|
||||
mockImgResizerSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<ImageResizerSettings>();
|
||||
_mockGeneralSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<GeneralSettings>();
|
||||
_mockImgResizerSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<ImageResizerSettings>();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +43,17 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0", "settings.json")]
|
||||
public void OriginalFilesModificationTest(string version, string fileName)
|
||||
{
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, ImageResizerSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
|
||||
var fileMock = BackCompatTestProperties.GetModuleIOProvider(version, ImageResizerSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(fileMock.Object, settingPathMock.Object);
|
||||
|
||||
ImageResizerSettings originalSettings = mockSettingsUtils.GetSettings<ImageResizerSettings>(ImageResizerSettings.ModuleName);
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
var mockGeneralFileMock = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralFileMock.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
|
||||
// Initialise View Model with test Config files
|
||||
@@ -69,8 +72,8 @@ namespace ViewModelTests
|
||||
|
||||
//Verify that the stub file was used
|
||||
var expectedCallCount = 2; //once via the view model, and once by the test (GetSettings<T>)
|
||||
BackCompatTestProperties.VerifyModuleIOProviderWasRead(mockIOProvider, ImageResizerSettings.ModuleName, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyGeneralSettingsIOProviderWasRead(mockGeneralIOProvider, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyModuleIOProviderWasRead(fileMock, ImageResizerSettings.ModuleName, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyGeneralSettingsIOProviderWasRead(mockGeneralFileMock, expectedCallCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -85,7 +88,7 @@ namespace ViewModelTests
|
||||
};
|
||||
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockImgResizerSettingsUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(_mockImgResizerSettingsUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
|
||||
// act
|
||||
viewModel.IsEnabled = true;
|
||||
@@ -95,16 +98,16 @@ namespace ViewModelTests
|
||||
public void JPEGQualityLevelShouldSetValueToTenWhenSuccessful()
|
||||
{
|
||||
// arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var fileSystemMock = new MockFileSystem();
|
||||
var mockSettingsUtils = new SettingsUtils(fileSystemMock);
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
|
||||
// act
|
||||
viewModel.JPEGQualityLevel = 10;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
Assert.AreEqual(10, viewModel.JPEGQualityLevel);
|
||||
}
|
||||
|
||||
@@ -112,16 +115,16 @@ namespace ViewModelTests
|
||||
public void PngInterlaceOptionShouldSetValueToTenWhenSuccessful()
|
||||
{
|
||||
// arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var fileSystemMock = new MockFileSystem();
|
||||
var mockSettingsUtils = new SettingsUtils(fileSystemMock);
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
|
||||
// act
|
||||
viewModel.PngInterlaceOption = 10;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
Assert.AreEqual(10, viewModel.PngInterlaceOption);
|
||||
}
|
||||
|
||||
@@ -129,16 +132,16 @@ namespace ViewModelTests
|
||||
public void TiffCompressOptionShouldSetValueToTenWhenSuccessful()
|
||||
{
|
||||
// arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var fileSystemMock = new MockFileSystem();
|
||||
var mockSettingsUtils = new SettingsUtils(fileSystemMock);
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
|
||||
// act
|
||||
viewModel.TiffCompressOption = 10;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
Assert.AreEqual(10, viewModel.TiffCompressOption);
|
||||
}
|
||||
|
||||
@@ -146,17 +149,17 @@ namespace ViewModelTests
|
||||
public void FileNameShouldUpdateValueWhenSuccessful()
|
||||
{
|
||||
// arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var fileSystemMock = new MockFileSystem();
|
||||
var mockSettingsUtils = new SettingsUtils(fileSystemMock);
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
string expectedValue = "%1 (%3)";
|
||||
|
||||
// act
|
||||
viewModel.FileName = expectedValue;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
Assert.AreEqual(expectedValue, viewModel.FileName);
|
||||
}
|
||||
|
||||
@@ -175,7 +178,7 @@ namespace ViewModelTests
|
||||
.Verifiable();
|
||||
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(settingUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(settingUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
|
||||
// act
|
||||
viewModel.KeepDateModified = true;
|
||||
@@ -188,16 +191,16 @@ namespace ViewModelTests
|
||||
public void EncoderShouldUpdateValueWhenSuccessful()
|
||||
{
|
||||
// arrange
|
||||
var mockIOProvider = IIOProviderMocks.GetMockIOProviderForSaveLoadExists();
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var fileSystemMock = new MockFileSystem();
|
||||
var mockSettingsUtils = new SettingsUtils(fileSystemMock);
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
|
||||
// act
|
||||
viewModel.Encoder = 3;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
viewModel = new ImageResizerViewModel(mockSettingsUtils, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
Assert.AreEqual("163bcc30-e2e9-4f0b-961d-a3e9fdb788a3", viewModel.EncoderGuid);
|
||||
Assert.AreEqual(3, viewModel.Encoder);
|
||||
}
|
||||
@@ -208,7 +211,7 @@ namespace ViewModelTests
|
||||
// arrange
|
||||
var mockSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<ImageResizerSettings>();
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
int sizeOfOriginalArray = viewModel.Sizes.Count;
|
||||
|
||||
// act
|
||||
@@ -224,7 +227,7 @@ namespace ViewModelTests
|
||||
// arrange
|
||||
var mockSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<ImageResizerSettings>();
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel(mockSettingsUtils.Object, SettingsRepository<GeneralSettings>.GetInstance(_mockGeneralSettingsUtils.Object), SendMockIPCConfigMSG);
|
||||
int sizeOfOriginalArray = viewModel.Sizes.Count;
|
||||
ImageSize deleteCandidate = viewModel.Sizes.Where<ImageSize>(x => x.Id == 0).First();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using Moq;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
|
||||
using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility;
|
||||
using System.Globalization;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace ViewModelTests
|
||||
{
|
||||
@@ -52,13 +53,16 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0", "settings.json")]
|
||||
public void OriginalFilesModificationTest(string version, string fileName)
|
||||
{
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, PowerLauncherSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object, settingPathMock.Object);
|
||||
PowerLauncherSettings originalSettings = mockSettingsUtils.GetSettings<PowerLauncherSettings>(PowerLauncherSettings.ModuleName);
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
|
||||
// Initialise View Model with test Config files
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
@@ -40,13 +40,15 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0", "settings.json")]
|
||||
public void OriginalFilesModificationTest(string version, string fileName)
|
||||
{
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, PowerPreviewSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
var fileMock = BackCompatTestProperties.GetModuleIOProvider(version, PowerPreviewSettings.ModuleName, fileName);
|
||||
|
||||
var mockSettingsUtils = new SettingsUtils(fileMock.Object, settingPathMock.Object);
|
||||
PowerPreviewSettings originalSettings = mockSettingsUtils.GetSettings<PowerPreviewSettings>(PowerPreviewSettings.ModuleName);
|
||||
var repository = new BackCompatTestProperties.MockSettingsRepository<PowerPreviewSettings>(mockSettingsUtils);
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
|
||||
@@ -62,7 +64,7 @@ namespace ViewModelTests
|
||||
|
||||
//Verify that the stub file was used
|
||||
var expectedCallCount = 2; //once via the view model, and once by the test (GetSettings<T>)
|
||||
BackCompatTestProperties.VerifyModuleIOProviderWasRead(mockIOProvider, PowerPreviewSettings.ModuleName, expectedCallCount);
|
||||
BackCompatTestProperties.VerifyModuleIOProviderWasRead(fileMock, PowerPreviewSettings.ModuleName, expectedCallCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
@@ -40,12 +40,16 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0", "power-rename-settings.json")]
|
||||
public void OriginalFilesModificationTest(string version, string fileName)
|
||||
{
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, PowerRenameSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object, settingPathMock.Object);
|
||||
PowerRenameLocalProperties originalSettings = mockSettingsUtils.GetSettings<PowerRenameLocalProperties>(PowerRenameSettings.ModuleName);
|
||||
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
@@ -30,12 +29,13 @@ namespace ViewModelTests
|
||||
[DataRow("v0.22.0", "settings.json")]
|
||||
public void OriginalFilesModificationTest(string version, string fileName)
|
||||
{
|
||||
var settingPathMock = new Mock<ISettingsPath>();
|
||||
var mockIOProvider = BackCompatTestProperties.GetModuleIOProvider(version, ShortcutGuideSettings.ModuleName, fileName);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object);
|
||||
var mockSettingsUtils = new SettingsUtils(mockIOProvider.Object, settingPathMock.Object);
|
||||
ShortcutGuideSettings originalSettings = mockSettingsUtils.GetSettings<ShortcutGuideSettings>(ShortcutGuideSettings.ModuleName);
|
||||
|
||||
var mockGeneralIOProvider = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object);
|
||||
var mockGeneralSettingsUtils = new SettingsUtils(mockGeneralIOProvider.Object, settingPathMock.Object);
|
||||
GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettings<GeneralSettings>();
|
||||
var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
|
||||
var shortcutSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<ShortcutGuideSettings>(mockSettingsUtils);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Media;
|
||||
@@ -14,7 +13,7 @@ namespace Microsoft.PowerToys.Settings.UI.Converters
|
||||
{
|
||||
public sealed class ModuleEnabledToForegroundConverter : IValueConverter
|
||||
{
|
||||
private readonly ISettingsUtils settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
private readonly ISettingsUtils settingsUtils = new SettingsUtils();
|
||||
|
||||
private string selectedTheme = string.Empty;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO.Abstractions;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
@@ -15,7 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
|
||||
public ColorPickerPage()
|
||||
{
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new ColorPickerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public FancyZonesPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new FancyZonesViewModel(SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<FancyZonesSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
|
||||
// Load string resources
|
||||
ResourceLoader loader = ResourceLoader.GetForViewIndependentUse();
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
|
||||
ViewModel = new GeneralViewModel(
|
||||
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public ImageResizerPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new ImageResizerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
@@ -24,7 +24,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
private const string PowerToyName = "Keyboard Manager";
|
||||
|
||||
private readonly CoreDispatcher dispatcher;
|
||||
private readonly FileSystemWatcher watcher;
|
||||
private readonly IFileSystemWatcher watcher;
|
||||
|
||||
public KeyboardManagerViewModel ViewModel { get; }
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
dispatcher = Window.Current.Dispatcher;
|
||||
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new KeyboardManagerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, FilterRemapKeysList);
|
||||
|
||||
watcher = Helper.GetFileWatcher(
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public PowerLauncherPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new PowerLauncherViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, (int)Windows.System.VirtualKey.Space);
|
||||
DataContext = ViewModel;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public PowerPreviewPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new PowerPreviewViewModel(SettingsRepository<PowerPreviewSettings>.GetInstance(settingsUtils), SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public PowerRenamePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new PowerRenameViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new ShortcutGuideViewModel(SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<ShortcutGuideSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -225,6 +225,9 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions">
|
||||
<Version>12.2.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Windows.Interactivity.WPF">
|
||||
<Version>2.0.20525</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -5,23 +5,24 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace ColorPicker.Helpers
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
private static readonly string ApplicationLogPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ColorPicker");
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
private static readonly string ApplicationLogPath = _fileSystem.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ColorPicker");
|
||||
|
||||
static Logger()
|
||||
{
|
||||
if (!Directory.Exists(ApplicationLogPath))
|
||||
if (!_fileSystem.Directory.Exists(ApplicationLogPath))
|
||||
{
|
||||
Directory.CreateDirectory(ApplicationLogPath);
|
||||
_fileSystem.Directory.CreateDirectory(ApplicationLogPath);
|
||||
}
|
||||
|
||||
// Using InvariantCulture since this is used for a log file name
|
||||
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
|
||||
var logFilePath = _fileSystem.Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
|
||||
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using ColorPicker.Helpers;
|
||||
using Microsoft.Win32;
|
||||
|
||||
@@ -28,11 +28,13 @@ namespace ColorPicker.Mouse
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")]
|
||||
private const int SPIF_SENDCHANGE = 0x02;
|
||||
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
public static void SetColorPickerCursor()
|
||||
{
|
||||
BackupOriginalCursors();
|
||||
|
||||
var colorPickerCursorPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ColorPickerCursorName);
|
||||
var colorPickerCursorPath = _fileSystem.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ColorPickerCursorName);
|
||||
ChangeCursor(colorPickerCursorPath, ArrowRegistryName);
|
||||
ChangeCursor(colorPickerCursorPath, IBeamRegistryName);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Threading;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
@@ -20,14 +21,14 @@ namespace ColorPicker.Settings
|
||||
private const int MaxNumberOfRetry = 5;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Actually, call back is LoadSettingsFromJson")]
|
||||
private readonly FileSystemWatcher _watcher;
|
||||
private readonly IFileSystemWatcher _watcher;
|
||||
|
||||
private readonly object _loadingSettingsLock = new object();
|
||||
|
||||
[ImportingConstructor]
|
||||
public UserSettings()
|
||||
{
|
||||
_settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
_settingsUtils = new SettingsUtils();
|
||||
ChangeCursor = new SettingItem<bool>(true);
|
||||
ActivationShortcut = new SettingItem<string>(DefaultActivationShortcut);
|
||||
CopiedColorRepresentation = new SettingItem<ColorRepresentationType>(ColorRepresentationType.HEX);
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -41,6 +42,8 @@ namespace FancyZonesEditor
|
||||
private const string CrashReportDynamicAssemblyTag = "dynamic assembly doesn't have location";
|
||||
private const string CrashReportLocationNullTag = "location is null or empty";
|
||||
|
||||
private readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
public Settings ZoneSettings { get; }
|
||||
|
||||
public App()
|
||||
|
||||
@@ -250,6 +250,9 @@
|
||||
<PackageReference Include="MahApps.Metro">
|
||||
<Version>2.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions">
|
||||
<Version>12.2.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Text.Json">
|
||||
<Version>4.7.2</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace FancyZonesEditor.Models
|
||||
try
|
||||
{
|
||||
string jsonString = JsonSerializer.Serialize(jsonObj, options);
|
||||
File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
|
||||
FileSystem.File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
|
||||
@@ -237,7 +236,7 @@ namespace FancyZonesEditor.Models
|
||||
try
|
||||
{
|
||||
string jsonString = JsonSerializer.Serialize(jsonObj, options);
|
||||
File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
|
||||
FileSystem.File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
@@ -29,6 +30,8 @@ namespace FancyZonesEditor.Models
|
||||
// Manages common properties and base persistence
|
||||
public abstract class LayoutModel : INotifyPropertyChanged
|
||||
{
|
||||
protected static readonly IFileSystem FileSystem = new FileSystem();
|
||||
|
||||
// Localizable strings
|
||||
private const string ErrorMessageBoxTitle = "FancyZones Editor Exception Handler";
|
||||
private const string ErrorMessageBoxMessage = "Please report the bug to ";
|
||||
@@ -194,7 +197,7 @@ namespace FancyZonesEditor.Models
|
||||
try
|
||||
{
|
||||
string jsonString = JsonSerializer.Serialize(deletedLayouts, options);
|
||||
File.WriteAllText(Settings.DeletedCustomZoneSetsTmpFile, jsonString);
|
||||
FileSystem.File.WriteAllText(Settings.DeletedCustomZoneSetsTmpFile, jsonString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -209,7 +212,7 @@ namespace FancyZonesEditor.Models
|
||||
|
||||
try
|
||||
{
|
||||
FileStream inputStream = File.Open(Settings.FancyZonesSettingsFile, FileMode.Open);
|
||||
Stream inputStream = FileSystem.File.Open(Settings.FancyZonesSettingsFile, FileMode.Open);
|
||||
JsonDocument jsonObject = JsonDocument.Parse(inputStream, options: default);
|
||||
JsonElement.ArrayEnumerator customZoneSetsEnumerator = jsonObject.RootElement.GetProperty(CustomZoneSetsJsonTag).EnumerateArray();
|
||||
|
||||
@@ -437,7 +440,7 @@ namespace FancyZonesEditor.Models
|
||||
try
|
||||
{
|
||||
string jsonString = JsonSerializer.Serialize(zoneSet, options);
|
||||
File.WriteAllText(Settings.ActiveZoneSetTmpFile, jsonString);
|
||||
FileSystem.File.WriteAllText(Settings.ActiveZoneSetTmpFile, jsonString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
@@ -39,6 +40,8 @@ namespace FancyZonesEditor
|
||||
Debug,
|
||||
}
|
||||
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
private static CanvasLayoutModel _blankCustomModel;
|
||||
private readonly CanvasLayoutModel _focusModel;
|
||||
private readonly GridLayoutModel _rowsModel;
|
||||
@@ -137,7 +140,7 @@ namespace FancyZonesEditor
|
||||
|
||||
public Settings()
|
||||
{
|
||||
string tmpDirPath = Path.GetTempPath();
|
||||
string tmpDirPath = _fileSystem.Path.GetTempPath();
|
||||
|
||||
ActiveZoneSetTmpFile = tmpDirPath + ActiveZoneSetsTmpFileName;
|
||||
AppliedZoneSetTmpFile = tmpDirPath + AppliedZoneSetsTmpFileName;
|
||||
@@ -441,9 +444,9 @@ namespace FancyZonesEditor
|
||||
ActiveZoneSetUUid = NullUuidStr;
|
||||
JsonElement jsonObject = default(JsonElement);
|
||||
|
||||
if (File.Exists(Settings.ActiveZoneSetTmpFile))
|
||||
if (_fileSystem.File.Exists(Settings.ActiveZoneSetTmpFile))
|
||||
{
|
||||
FileStream inputStream = File.Open(Settings.ActiveZoneSetTmpFile, FileMode.Open);
|
||||
Stream inputStream = _fileSystem.File.Open(Settings.ActiveZoneSetTmpFile, FileMode.Open);
|
||||
jsonObject = JsonDocument.Parse(inputStream, options: default).RootElement;
|
||||
inputStream.Close();
|
||||
UniqueKey = jsonObject.GetProperty(DeviceIdJsonTag).GetString();
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
@@ -6,7 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Xunit;
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace ImageResizer.Test
|
||||
{
|
||||
internal static class AssertEx
|
||||
{
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
public static void All<T>(IEnumerable<T> collection, Action<T> action)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
@@ -24,7 +26,7 @@ namespace ImageResizer.Test
|
||||
|
||||
public static void Image(string path, Action<BitmapDecoder> action)
|
||||
{
|
||||
using (var stream = File.OpenRead(path))
|
||||
using (var stream = _fileSystem.File.OpenRead(path))
|
||||
{
|
||||
var image = BitmapDecoder.Create(
|
||||
stream,
|
||||
|
||||
@@ -69,6 +69,9 @@
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions">
|
||||
<Version>12.2.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\interop\interop.vcxproj" />
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ImageResizer.Properties;
|
||||
@@ -14,6 +15,8 @@ namespace ImageResizer.Models
|
||||
{
|
||||
public class ResizeBatch
|
||||
{
|
||||
private readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
public string DestinationDirectory { get; set; }
|
||||
|
||||
public ICollection<string> Files { get; } = new List<string>();
|
||||
@@ -71,7 +74,7 @@ namespace ImageResizer.Models
|
||||
catch (Exception ex)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
{
|
||||
errors.Add(new ResizeError { File = Path.GetFileName(file), Error = ex.Message });
|
||||
errors.Add(new ResizeError { File = _fileSystem.Path.GetFileName(file), Error = ex.Message });
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref completed);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
@@ -12,11 +13,14 @@ using System.Windows.Media.Imaging;
|
||||
using ImageResizer.Properties;
|
||||
using ImageResizer.Utilities;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
using FileSystem = Microsoft.VisualBasic.FileIO.FileSystem;
|
||||
|
||||
namespace ImageResizer.Models
|
||||
{
|
||||
internal class ResizeOperation
|
||||
{
|
||||
private readonly IFileSystem _fileSystem = new System.IO.Abstractions.FileSystem();
|
||||
|
||||
private readonly string _file;
|
||||
private readonly string _destinationDirectory;
|
||||
private readonly Settings _settings;
|
||||
@@ -31,7 +35,7 @@ namespace ImageResizer.Models
|
||||
public void Execute()
|
||||
{
|
||||
string path;
|
||||
using (var inputStream = File.OpenRead(_file))
|
||||
using (var inputStream = _fileSystem.File.OpenRead(_file))
|
||||
{
|
||||
var decoder = BitmapDecoder.Create(
|
||||
inputStream,
|
||||
@@ -87,8 +91,8 @@ namespace ImageResizer.Models
|
||||
}
|
||||
|
||||
path = GetDestinationPath(encoder);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
using (var outputStream = File.Open(path, FileMode.CreateNew, FileAccess.Write))
|
||||
_fileSystem.Directory.CreateDirectory(_fileSystem.Path.GetDirectoryName(path));
|
||||
using (var outputStream = _fileSystem.File.Open(path, FileMode.CreateNew, FileAccess.Write))
|
||||
{
|
||||
encoder.Save(outputStream);
|
||||
}
|
||||
@@ -96,13 +100,13 @@ namespace ImageResizer.Models
|
||||
|
||||
if (_settings.KeepDateModified)
|
||||
{
|
||||
File.SetLastWriteTimeUtc(path, File.GetLastWriteTimeUtc(_file));
|
||||
_fileSystem.File.SetLastWriteTimeUtc(path, _fileSystem.File.GetLastWriteTimeUtc(_file));
|
||||
}
|
||||
|
||||
if (_settings.Replace)
|
||||
{
|
||||
var backup = GetBackupPath();
|
||||
File.Replace(path, _file, backup, ignoreMetadataErrors: true);
|
||||
_fileSystem.File.Replace(path, _file, backup, ignoreMetadataErrors: true);
|
||||
FileSystem.DeleteFile(backup, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
|
||||
}
|
||||
}
|
||||
@@ -179,11 +183,11 @@ namespace ImageResizer.Models
|
||||
|
||||
private string GetDestinationPath(BitmapEncoder encoder)
|
||||
{
|
||||
var directory = _destinationDirectory ?? Path.GetDirectoryName(_file);
|
||||
var originalFileName = Path.GetFileNameWithoutExtension(_file);
|
||||
var directory = _destinationDirectory ?? _fileSystem.Path.GetDirectoryName(_file);
|
||||
var originalFileName = _fileSystem.Path.GetFileNameWithoutExtension(_file);
|
||||
|
||||
var supportedExtensions = encoder.CodecInfo.FileExtensions.Split(',');
|
||||
var extension = Path.GetExtension(_file);
|
||||
var extension = _fileSystem.Path.GetExtension(_file);
|
||||
if (!supportedExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
extension = supportedExtensions.FirstOrDefault();
|
||||
@@ -199,11 +203,11 @@ namespace ImageResizer.Models
|
||||
_settings.SelectedSize.Height,
|
||||
encoder.Frames[0].PixelWidth,
|
||||
encoder.Frames[0].PixelHeight);
|
||||
var path = Path.Combine(directory, fileName + extension);
|
||||
var path = _fileSystem.Path.Combine(directory, fileName + extension);
|
||||
var uniquifier = 1;
|
||||
while (File.Exists(path))
|
||||
while (_fileSystem.File.Exists(path))
|
||||
{
|
||||
path = Path.Combine(directory, fileName + " (" + uniquifier++ + ")" + extension);
|
||||
path = _fileSystem.Path.Combine(directory, fileName + " (" + uniquifier++ + ")" + extension);
|
||||
}
|
||||
|
||||
return path;
|
||||
@@ -211,15 +215,15 @@ namespace ImageResizer.Models
|
||||
|
||||
private string GetBackupPath()
|
||||
{
|
||||
var directory = Path.GetDirectoryName(_file);
|
||||
var fileName = Path.GetFileNameWithoutExtension(_file);
|
||||
var extension = Path.GetExtension(_file);
|
||||
var directory = _fileSystem.Path.GetDirectoryName(_file);
|
||||
var fileName = _fileSystem.Path.GetFileNameWithoutExtension(_file);
|
||||
var extension = _fileSystem.Path.GetExtension(_file);
|
||||
|
||||
var path = Path.Combine(directory, fileName + ".bak" + extension);
|
||||
var path = _fileSystem.Path.Combine(directory, fileName + ".bak" + extension);
|
||||
var uniquifier = 1;
|
||||
while (File.Exists(path))
|
||||
while (_fileSystem.File.Exists(path))
|
||||
{
|
||||
path = Path.Combine(directory, fileName + " (" + uniquifier++ + ")" + ".bak" + extension);
|
||||
path = _fileSystem.Path.Combine(directory, fileName + " (" + uniquifier++ + ")" + ".bak" + extension);
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
@@ -9,7 +9,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Threading;
|
||||
using System.Windows.Media.Imaging;
|
||||
using ImageResizer.Models;
|
||||
@@ -22,9 +22,11 @@ namespace ImageResizer.Properties
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public sealed partial class Settings : IDataErrorInfo, INotifyPropertyChanged
|
||||
{
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
// Used to synchronize access to the settings.json file
|
||||
private static Mutex _jsonMutex = new Mutex();
|
||||
private static string _settingsPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Microsoft", "PowerToys", "ImageResizer", "settings.json");
|
||||
private static string _settingsPath = _fileSystem.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Microsoft", "PowerToys", "ImageResizer", "settings.json");
|
||||
private string _fileNameFormat;
|
||||
private bool _shrinkOnly;
|
||||
private int _selectedSizeIndex;
|
||||
@@ -384,25 +386,25 @@ namespace ImageResizer.Properties
|
||||
jsonData += "}";
|
||||
|
||||
// Create directory if it doesn't exist
|
||||
FileInfo file = new FileInfo(SettingsPath);
|
||||
IFileInfo file = _fileSystem.FileInfo.FromFileName(SettingsPath);
|
||||
file.Directory.Create();
|
||||
|
||||
// write string to file
|
||||
File.WriteAllText(SettingsPath, jsonData);
|
||||
_fileSystem.File.WriteAllText(SettingsPath, jsonData);
|
||||
_jsonMutex.ReleaseMutex();
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
_jsonMutex.WaitOne();
|
||||
if (!File.Exists(SettingsPath))
|
||||
if (!_fileSystem.File.Exists(SettingsPath))
|
||||
{
|
||||
_jsonMutex.ReleaseMutex();
|
||||
Save();
|
||||
return;
|
||||
}
|
||||
|
||||
string jsonData = File.ReadAllText(SettingsPath);
|
||||
string jsonData = _fileSystem.File.ReadAllText(SettingsPath);
|
||||
JObject imageResizerSettings = JObject.Parse(jsonData);
|
||||
|
||||
// Replace the { "value": <Value> } with <Value> to match the Settings object format
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Plugin.Folder.Sources;
|
||||
using Microsoft.Plugin.Folder.Sources.Result;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Microsoft.Plugin.Folder.UnitTests
|
||||
@@ -17,117 +16,45 @@ namespace Microsoft.Plugin.Folder.UnitTests
|
||||
[TestFixture]
|
||||
public class InternalQueryFolderTests
|
||||
{
|
||||
private static readonly HashSet<string> DirectoryExist = new HashSet<string>()
|
||||
{
|
||||
@"c:",
|
||||
@"c:\",
|
||||
@"c:\Test\",
|
||||
@"c:\Test\A\",
|
||||
@"c:\Test\b\",
|
||||
};
|
||||
|
||||
private static readonly HashSet<string> FilesExist = new HashSet<string>()
|
||||
{
|
||||
@"c:\bla.txt",
|
||||
@"c:\Test\test.txt",
|
||||
@"c:\Test\more-test.png",
|
||||
};
|
||||
|
||||
private static Mock<IQueryFileSystemInfo> _queryFileSystemInfoMock;
|
||||
private static IQueryFileSystemInfo _queryFileSystemInfoMock;
|
||||
private static MockFileSystem _fileSystem;
|
||||
|
||||
[SetUp]
|
||||
public void SetupMock()
|
||||
{
|
||||
var queryFileSystemInfoMock = new Mock<IQueryFileSystemInfo>();
|
||||
queryFileSystemInfoMock.Setup(r => r.Exists(It.IsAny<string>()))
|
||||
.Returns<string>(path => ContainsDirectory(path));
|
||||
|
||||
queryFileSystemInfoMock.Setup(r => r.MatchFileSystemInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Returns<string, string, bool>(MatchFileSystemInfo);
|
||||
|
||||
_queryFileSystemInfoMock = queryFileSystemInfoMock;
|
||||
}
|
||||
|
||||
// Windows supports C:\\\\\ => C:\
|
||||
private static bool ContainsDirectory(string path)
|
||||
{
|
||||
return DirectoryExist.Contains(TrimDirectoryEnd(path));
|
||||
}
|
||||
|
||||
private static string TrimDirectoryEnd(string path)
|
||||
{
|
||||
var trimEnd = path.TrimEnd('\\');
|
||||
|
||||
if (path.EndsWith('\\'))
|
||||
// Note: This mock filesystem adds a 'c:\temp' directory.
|
||||
_fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>()
|
||||
{
|
||||
trimEnd += '\\';
|
||||
}
|
||||
{ @"c:\bla.txt", new MockFileData(string.Empty) },
|
||||
{ @"c:\Test\test.txt", new MockFileData(string.Empty) },
|
||||
{ @"c:\Test\more-test.png", new MockFileData(string.Empty) },
|
||||
{ @"c:\Test\A\deep-nested.png", new MockFileData(string.Empty) },
|
||||
{ @"c:\Test\b\", new MockDirectoryData() },
|
||||
});
|
||||
|
||||
return trimEnd;
|
||||
}
|
||||
|
||||
private static IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive)
|
||||
{
|
||||
Func<string, bool> folderSearchFunc;
|
||||
Func<string, bool> fileSearchFunc;
|
||||
switch (isRecursive)
|
||||
{
|
||||
case false:
|
||||
// Using Ordinal since this is internal
|
||||
folderSearchFunc = s => s.Equals(search, StringComparison.Ordinal);
|
||||
|
||||
var regexSearch = TrimDirectoryEnd(search);
|
||||
|
||||
fileSearchFunc = s => Regex.IsMatch(s, $"^{Regex.Escape(regexSearch)}[^\\\\]*$");
|
||||
break;
|
||||
case true:
|
||||
// Using Ordinal since this is internal
|
||||
folderSearchFunc = s => s.StartsWith(search, StringComparison.Ordinal);
|
||||
fileSearchFunc = s => s.StartsWith(search, StringComparison.Ordinal);
|
||||
break;
|
||||
}
|
||||
|
||||
var directories = DirectoryExist.Where(s => folderSearchFunc(s))
|
||||
.Select(dir => new DisplayFileInfo()
|
||||
{
|
||||
Type = DisplayType.Directory,
|
||||
FullName = dir,
|
||||
});
|
||||
|
||||
var files = FilesExist.Where(s => fileSearchFunc(s))
|
||||
.Select(file => new DisplayFileInfo()
|
||||
{
|
||||
Type = DisplayType.File,
|
||||
FullName = file,
|
||||
});
|
||||
|
||||
return directories.Concat(files);
|
||||
_queryFileSystemInfoMock = new QueryFileSystemInfo(_fileSystem.DirectoryInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Query_ThrowsException_WhenCalledNull()
|
||||
{
|
||||
// Setup
|
||||
var queryInternalDirectory = new QueryInternalDirectory(new FolderSettings(), _queryFileSystemInfoMock.Object);
|
||||
var queryInternalDirectory = new QueryInternalDirectory(new FolderSettings(), _queryFileSystemInfoMock, _fileSystem.Directory);
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentNullException>(() => queryInternalDirectory.Query(null).ToArray());
|
||||
}
|
||||
|
||||
[TestCase(@"c", 0, 0, false, Reason = "String empty is nothing")]
|
||||
[TestCase(@"c:", 1, 1, false, Reason = "Root without \\")]
|
||||
[TestCase(@"c:\", 1, 1, false, Reason = "Normal root")]
|
||||
[TestCase(@"c:\Test", 1, 2, false, Reason = "Select yourself")]
|
||||
[TestCase(@"c:\>", 2, 2, true, Reason = "Max Folder test recursive")]
|
||||
[TestCase(@"c:\Test>", 2, 2, true, Reason = "2 Folders recursive")]
|
||||
[TestCase(@"c:\not-exist", 1, 1, false, Reason = "Folder not exist, return root")]
|
||||
[TestCase(@"c:\not-exist>", 2, 2, true, Reason = "Folder not exist, return root recursive")]
|
||||
[TestCase(@"c:", 2, 1, false, Reason = "Root without \\")]
|
||||
[TestCase(@"c:\", 2, 1, false, Reason = "Normal root")]
|
||||
[TestCase(@"c:\Test", 2, 2, false, Reason = "Select yourself")]
|
||||
[TestCase(@"c:\not-exist", 2, 1, false, Reason = "Folder not exist, return root")]
|
||||
[TestCase(@"c:\not-exist\not-exist2", 0, 0, false, Reason = "Folder not exist, return root")]
|
||||
[TestCase(@"c:\not-exist\not-exist2>", 0, 0, false, Reason = "Folder not exist, return root recursive")]
|
||||
[TestCase(@"c:\bla.t", 1, 1, false, Reason = "Partial match file")]
|
||||
[TestCase(@"c:\bla.t", 2, 1, false, Reason = "Partial match file")]
|
||||
public void Query_WhenCalled(string search, int folders, int files, bool truncated)
|
||||
{
|
||||
const int maxFolderSetting = 2;
|
||||
const int maxFolderSetting = 3;
|
||||
|
||||
// Setup
|
||||
var folderSettings = new FolderSettings()
|
||||
@@ -136,7 +63,42 @@ namespace Microsoft.Plugin.Folder.UnitTests
|
||||
MaxFolderResults = maxFolderSetting,
|
||||
};
|
||||
|
||||
var queryInternalDirectory = new QueryInternalDirectory(folderSettings, _queryFileSystemInfoMock.Object);
|
||||
var queryInternalDirectory = new QueryInternalDirectory(folderSettings, _queryFileSystemInfoMock, _fileSystem.Directory);
|
||||
|
||||
// Act
|
||||
var isDriveOrSharedFolder = queryInternalDirectory.Query(search)
|
||||
.ToLookup(r => r.GetType());
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(files, isDriveOrSharedFolder[typeof(FileItemResult)].Count(), "File count doesn't match");
|
||||
Assert.AreEqual(folders, isDriveOrSharedFolder[typeof(FolderItemResult)].Count(), "folder count doesn't match");
|
||||
|
||||
// Always check if there is less than max folders
|
||||
Assert.LessOrEqual(isDriveOrSharedFolder[typeof(FileItemResult)].Count(), maxFolderSetting, "Files are not limited");
|
||||
Assert.LessOrEqual(isDriveOrSharedFolder[typeof(FolderItemResult)].Count(), maxFolderSetting, "Folders are not limited");
|
||||
|
||||
// Checks if CreateOpenCurrentFolder is displayed
|
||||
Assert.AreEqual(Math.Min(folders + files, 1), isDriveOrSharedFolder[typeof(CreateOpenCurrentFolderResult)].Count(), "CreateOpenCurrentFolder displaying is incorrect");
|
||||
|
||||
Assert.AreEqual(truncated, isDriveOrSharedFolder[typeof(TruncatedItemResult)].Count() == 1, "CreateOpenCurrentFolder displaying is incorrect");
|
||||
}
|
||||
|
||||
[TestCase(@"c:\>", 3, 3, true, Reason = "Max Folder test recursive")]
|
||||
[TestCase(@"c:\Test>", 3, 3, true, Reason = "2 Folders recursive")]
|
||||
[TestCase(@"c:\not-exist>", 3, 3, true, Reason = "Folder not exist, return root recursive")]
|
||||
[TestCase(@"c:\not-exist\not-exist2>", 0, 0, false, Reason = "Folder not exist, return root recursive")]
|
||||
public void Query_Recursive_WhenCalled(string search, int folders, int files, bool truncated)
|
||||
{
|
||||
const int maxFolderSetting = 3;
|
||||
|
||||
// Setup
|
||||
var folderSettings = new FolderSettings()
|
||||
{
|
||||
MaxFileResults = maxFolderSetting,
|
||||
MaxFolderResults = maxFolderSetting,
|
||||
};
|
||||
|
||||
var queryInternalDirectory = new QueryInternalDirectory(folderSettings, _queryFileSystemInfoMock, _fileSystem.Directory);
|
||||
|
||||
// Act
|
||||
var isDriveOrSharedFolder = queryInternalDirectory.Query(search)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<PackageReference Include="nunit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="12.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
@@ -17,6 +17,7 @@ namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
internal class ContextMenuLoader : IContextMenu
|
||||
{
|
||||
private readonly IFileSystem _fileSystem = new FileSystem();
|
||||
private readonly PluginInitContext _context;
|
||||
|
||||
public ContextMenuLoader(PluginInitContext context)
|
||||
@@ -76,7 +77,7 @@ namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
if (record.Type == ResultType.File)
|
||||
{
|
||||
Helper.OpenInConsole(Path.GetDirectoryName(record.FullPath));
|
||||
Helper.OpenInConsole(_fileSystem.Path.GetDirectoryName(record.FullPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using ManagedCommon;
|
||||
@@ -21,9 +22,10 @@ namespace Microsoft.Plugin.Folder
|
||||
public const string DeleteFileFolderImagePath = "Images\\delete.dark.png";
|
||||
public const string CopyImagePath = "Images\\copy.dark.png";
|
||||
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
private static readonly PluginJsonStorage<FolderSettings> _storage = new PluginJsonStorage<FolderSettings>();
|
||||
private static readonly FolderSettings _settings = _storage.Load();
|
||||
private static readonly IQueryInternalDirectory _internalDirectory = new QueryInternalDirectory(_settings, new QueryFileSystemInfo());
|
||||
private static readonly IQueryInternalDirectory _internalDirectory = new QueryInternalDirectory(_settings, new QueryFileSystemInfo(_fileSystem.DirectoryInfo), _fileSystem.Directory);
|
||||
private static readonly FolderHelper _folderHelper = new FolderHelper(new DriveInformation(), new FolderLinksSettings(_settings));
|
||||
|
||||
private static readonly ICollection<IFolderProcessor> _processors = new IFolderProcessor[]
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
|
||||
<PackageReference Include="System.Runtime" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -2,17 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
public class SearchResult
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Wox.Infrastructure.FileSystemHelper;
|
||||
|
||||
namespace Microsoft.Plugin.Folder.Sources
|
||||
{
|
||||
public interface IQueryFileSystemInfo : IDirectoryWrapper
|
||||
public interface IQueryFileSystemInfo
|
||||
{
|
||||
IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive);
|
||||
}
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Plugin.Folder.Sources
|
||||
{
|
||||
internal class DriveInformation : IDriveInformation
|
||||
{
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
private static readonly List<string> DriverNames = InitialDriverList().ToList();
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
|
||||
private static IEnumerable<string> InitialDriverList()
|
||||
{
|
||||
var directorySeparatorChar = System.IO.Path.DirectorySeparatorChar;
|
||||
|
||||
// Using InvariantCulture since this is internal
|
||||
return DriveInfo.GetDrives()
|
||||
var directorySeparatorChar = _fileSystem.Path.DirectorySeparatorChar;
|
||||
return _fileSystem.DriveInfo.GetDrives()
|
||||
.Select(driver => driver.Name.ToLower(CultureInfo.InvariantCulture).TrimEnd(directorySeparatorChar));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,20 +2,26 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using Wox.Infrastructure.FileSystemHelper;
|
||||
|
||||
namespace Microsoft.Plugin.Folder.Sources
|
||||
{
|
||||
public class QueryFileSystemInfo : DirectoryWrapper, IQueryFileSystemInfo
|
||||
public class QueryFileSystemInfo : IQueryFileSystemInfo
|
||||
{
|
||||
private readonly IDirectoryInfoFactory _directoryInfoFactory;
|
||||
|
||||
public QueryFileSystemInfo(IDirectoryInfoFactory directoryInfoFactory)
|
||||
{
|
||||
_directoryInfoFactory = directoryInfoFactory;
|
||||
}
|
||||
|
||||
public IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive)
|
||||
{
|
||||
// search folder and add results
|
||||
var directoryInfo = new DirectoryInfo(search);
|
||||
var directoryInfo = _directoryInfoFactory.FromDirectoryName(search);
|
||||
var fileSystemInfos = directoryInfo.EnumerateFileSystemInfos(incompleteName, new EnumerationOptions()
|
||||
{
|
||||
MatchType = MatchType.Win32,
|
||||
@@ -30,7 +36,7 @@ namespace Microsoft.Plugin.Folder.Sources
|
||||
.Select(CreateDisplayFileInfo);
|
||||
}
|
||||
|
||||
private static DisplayFileInfo CreateDisplayFileInfo(FileSystemInfo fileSystemInfo)
|
||||
private static DisplayFileInfo CreateDisplayFileInfo(IFileSystemInfo fileSystemInfo)
|
||||
{
|
||||
return new DisplayFileInfo()
|
||||
{
|
||||
@@ -40,9 +46,9 @@ namespace Microsoft.Plugin.Folder.Sources
|
||||
};
|
||||
}
|
||||
|
||||
private static DisplayType GetDisplayType(FileSystemInfo fileSystemInfo)
|
||||
private static DisplayType GetDisplayType(IFileSystemInfo fileSystemInfo)
|
||||
{
|
||||
if (fileSystemInfo is DirectoryInfo)
|
||||
if (fileSystemInfo is IDirectoryInfo)
|
||||
{
|
||||
return DisplayType.Directory;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using ManagedCommon;
|
||||
using Microsoft.Plugin.Folder.Sources.Result;
|
||||
@@ -18,6 +19,7 @@ namespace Microsoft.Plugin.Folder.Sources
|
||||
{
|
||||
private readonly FolderSettings _settings;
|
||||
private readonly IQueryFileSystemInfo _queryFileSystemInfo;
|
||||
private readonly IDirectory _directory;
|
||||
|
||||
private static readonly HashSet<char> SpecialSearchChars = new HashSet<char>
|
||||
{
|
||||
@@ -26,10 +28,11 @@ namespace Microsoft.Plugin.Folder.Sources
|
||||
|
||||
private static string _warningIconPath;
|
||||
|
||||
public QueryInternalDirectory(FolderSettings folderSettings, IQueryFileSystemInfo queryFileSystemInfo)
|
||||
public QueryInternalDirectory(FolderSettings folderSettings, IQueryFileSystemInfo queryFileSystemInfo, IDirectory directory)
|
||||
{
|
||||
_settings = folderSettings;
|
||||
_queryFileSystemInfo = queryFileSystemInfo;
|
||||
_directory = directory;
|
||||
}
|
||||
|
||||
private static bool HasSpecialChars(string search)
|
||||
@@ -47,7 +50,7 @@ namespace Microsoft.Plugin.Folder.Sources
|
||||
private (string search, string incompleteName) Process(string search)
|
||||
{
|
||||
string incompleteName = string.Empty;
|
||||
if (HasSpecialChars(search) || !_queryFileSystemInfo.Exists($@"{search}\"))
|
||||
if (HasSpecialChars(search) || !_directory.Exists($@"{search}\"))
|
||||
{
|
||||
// if folder doesn't exist, we want to take the last part and use it afterwards to help the user
|
||||
// find the right folder.
|
||||
@@ -64,7 +67,7 @@ namespace Microsoft.Plugin.Folder.Sources
|
||||
incompleteName = search.Substring(index + 1)
|
||||
.ToLower(CultureInfo.InvariantCulture) + "*";
|
||||
search = search.Substring(0, index + 1);
|
||||
if (!_queryFileSystemInfo.Exists(search))
|
||||
if (!_directory.Exists(search))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Plugin;
|
||||
|
||||
@@ -13,15 +13,27 @@ namespace Microsoft.Plugin.Folder.Sources.Result
|
||||
{
|
||||
private static readonly IShellAction ShellAction = new ShellAction();
|
||||
|
||||
private readonly IPath _path;
|
||||
|
||||
public FileItemResult()
|
||||
: this(new FileSystem().Path)
|
||||
{
|
||||
}
|
||||
|
||||
private FileItemResult(IPath path)
|
||||
{
|
||||
_path = path;
|
||||
}
|
||||
|
||||
public string FilePath { get; set; }
|
||||
|
||||
public string Title => Path.GetFileName(FilePath);
|
||||
public string Title => _path.GetFileName(FilePath);
|
||||
|
||||
public string Search { get; set; }
|
||||
|
||||
public Wox.Plugin.Result Create(IPublicAPI contextApi)
|
||||
{
|
||||
var result = new Wox.Plugin.Result(StringMatcher.FuzzySearch(Search, Path.GetFileName(FilePath)).MatchData)
|
||||
var result = new Wox.Plugin.Result(StringMatcher.FuzzySearch(Search, _path.GetFileName(FilePath)).MatchData)
|
||||
{
|
||||
Title = Title,
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@@ -19,6 +19,8 @@ namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
internal class ContextMenuLoader : IContextMenu
|
||||
{
|
||||
private readonly IPath _path = new FileSystem().Path;
|
||||
|
||||
private readonly PluginInitContext _context;
|
||||
|
||||
public enum ResultType
|
||||
@@ -41,7 +43,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
var contextMenus = new List<ContextMenuResult>();
|
||||
if (selectedResult.ContextData is SearchResult record)
|
||||
{
|
||||
ResultType type = Path.HasExtension(record.Path) ? ResultType.File : ResultType.Folder;
|
||||
ResultType type = _path.HasExtension(record.Path) ? ResultType.File : ResultType.Folder;
|
||||
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
@@ -95,7 +97,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
Helper.OpenInConsole(Path.GetDirectoryName(record.Path));
|
||||
Helper.OpenInConsole(_path.GetDirectoryName(record.Path));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -147,7 +149,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
// Function to test if the file can be run as admin
|
||||
private bool CanFileBeRunAsAdmin(string path)
|
||||
{
|
||||
string fileExtension = Path.GetExtension(path);
|
||||
string fileExtension = _path.GetExtension(path);
|
||||
foreach (string extension in appExtensions)
|
||||
{
|
||||
// Using OrdinalIgnoreCase since this is internal
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Controls;
|
||||
@@ -24,6 +24,8 @@ namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin
|
||||
{
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
// This variable contains metadata about the Plugin
|
||||
private PluginInitContext _context;
|
||||
|
||||
@@ -38,7 +40,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
private readonly WindowsSearchAPI _api = new WindowsSearchAPI(_search);
|
||||
|
||||
// To obtain information regarding the drives that are indexed
|
||||
private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper(), new DriveInfoWrapper());
|
||||
private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper(), new DriveDetection.DriveInfoWrapper());
|
||||
|
||||
// Reserved keywords in oleDB
|
||||
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$|^.*[<>].*$";
|
||||
@@ -117,7 +119,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
string workingDir = null;
|
||||
if (_settings.UseLocationAsWorkingDir)
|
||||
{
|
||||
workingDir = Path.GetDirectoryName(path);
|
||||
workingDir = _fileSystem.Path.GetDirectoryName(path);
|
||||
}
|
||||
|
||||
Result r = new Result();
|
||||
@@ -151,7 +153,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
r.ContextData = searchResult;
|
||||
|
||||
// If the result is a directory, then it's display should show a directory.
|
||||
if (Directory.Exists(path))
|
||||
if (_fileSystem.Directory.Exists(path))
|
||||
{
|
||||
r.QueryTextDisplay = path;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using Microsoft.Plugin.Program.Programs;
|
||||
using Microsoft.Plugin.Program.Storage;
|
||||
@@ -209,7 +210,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Created, "directory", path);
|
||||
|
||||
// File.ReadAllLines must be mocked for url applications
|
||||
var mockFile = new Mock<IFileWrapper>();
|
||||
var mockFile = new Mock<IFile>();
|
||||
mockFile.Setup(m => m.ReadAllLines(It.IsAny<string>())).Returns(new string[] { "URL=steam://rungameid/1258080", "IconFile=iconFile" });
|
||||
Win32Program.FileWrapper = mockFile.Object;
|
||||
|
||||
@@ -256,7 +257,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path);
|
||||
|
||||
// File.ReadAllLines must be mocked for url applications
|
||||
var mockFile = new Mock<IFileWrapper>();
|
||||
var mockFile = new Mock<IFile>();
|
||||
mockFile.Setup(m => m.ReadAllLines(It.IsAny<string>())).Returns(new string[] { "URL=steam://rungameid/1258080", "IconFile=iconFile" });
|
||||
Win32Program.FileWrapper = mockFile.Object;
|
||||
|
||||
@@ -279,7 +280,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
RenamedEventArgs e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath);
|
||||
|
||||
// File.ReadAllLines must be mocked for url applications
|
||||
var mockFile = new Mock<IFileWrapper>();
|
||||
var mockFile = new Mock<IFile>();
|
||||
mockFile.Setup(m => m.ReadAllLines(It.IsAny<string>())).Returns(new string[] { "URL=steam://rungameid/1258080", "IconFile=iconFile" });
|
||||
Win32Program.FileWrapper = mockFile.Object;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Microsoft.Plugin.Program
|
||||
{
|
||||
@@ -16,11 +16,13 @@ namespace Microsoft.Plugin.Program
|
||||
/// </remarks>
|
||||
public class ProgramSource
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
|
||||
private string name;
|
||||
|
||||
public string Location { get; set; }
|
||||
|
||||
public string Name { get => name ?? new DirectoryInfo(Location).Name; set => name = value; }
|
||||
public string Name { get => name ?? FileSystem.DirectoryInfo.FromDirectoryName(Location).Name; set => name = value; }
|
||||
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -19,6 +19,8 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
[Serializable]
|
||||
public partial class UWP
|
||||
{
|
||||
private static readonly IPath Path = new FileSystem().Path;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string FullName { get; }
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -31,6 +32,10 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
[Serializable]
|
||||
public class UWPApplication : IProgram
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
public string AppListEntry { get; set; }
|
||||
|
||||
public string UniqueIdentifier { get; set; }
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
@@ -20,12 +21,18 @@ using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.FileSystemHelper;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
using DirectoryWrapper = Wox.Infrastructure.FileSystemHelper.DirectoryWrapper;
|
||||
|
||||
namespace Microsoft.Plugin.Program.Programs
|
||||
{
|
||||
[Serializable]
|
||||
public class Win32Program : IProgram
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string UniqueIdentifier { get; set; }
|
||||
@@ -57,7 +64,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
// Wrappers for File Operations
|
||||
public static IFileVersionInfoWrapper FileVersionInfoWrapper { get; set; } = new FileVersionInfoWrapper();
|
||||
|
||||
public static IFileWrapper FileWrapper { get; set; } = new FileWrapper();
|
||||
public static IFile FileWrapper { get; set; } = new FileSystem().File;
|
||||
|
||||
public static IShellLinkHelper Helper { get; set; } = new ShellLinkHelper();
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Wox.Plugin.Logger;
|
||||
@@ -17,6 +18,9 @@ namespace Microsoft.Plugin.Program.Storage
|
||||
{
|
||||
internal class Win32ProgramRepository : ListRepository<Programs.Win32Program>, IProgramRepository
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
||||
private const string LnkExtension = ".lnk";
|
||||
private const string UrlExtension = ".url";
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Input;
|
||||
@@ -23,6 +24,11 @@ namespace Microsoft.Plugin.Shell
|
||||
{
|
||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
private readonly ShellPluginSettings _settings;
|
||||
private readonly PluginJsonStorage<ShellPluginSettings> _storage;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text;
|
||||
using ManagedCommon;
|
||||
using Microsoft.Plugin.Uri.UriHelper;
|
||||
@@ -17,6 +17,10 @@ namespace Microsoft.Plugin.Uri
|
||||
{
|
||||
public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IDisposable
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
private readonly ExtendedUriParser _uriParser;
|
||||
private readonly UriResolver _uriResolver;
|
||||
private readonly PluginJsonStorage<UriSettings> _storage;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -29,6 +30,10 @@ namespace PowerLauncher.Helper
|
||||
public static class SingleInstance<TApplication>
|
||||
where TApplication : Application, ISingleInstanceApp
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
/// <summary>
|
||||
/// String delimiter used in channel names.
|
||||
/// </summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
@@ -21,6 +22,9 @@ namespace PowerLauncher
|
||||
{
|
||||
internal partial class ReportWindow
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
public ReportWindow(Exception exception)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Threading;
|
||||
using System.Windows.Input;
|
||||
using ManagedCommon;
|
||||
@@ -26,14 +27,14 @@ namespace PowerLauncher
|
||||
|
||||
private const int MaxRetries = 10;
|
||||
private static readonly object _watcherSyncObject = new object();
|
||||
private readonly FileSystemWatcher _watcher;
|
||||
private readonly IFileSystemWatcher _watcher;
|
||||
private readonly PowerToysRunSettings _settings;
|
||||
|
||||
private readonly ThemeManager _themeManager;
|
||||
|
||||
public SettingsWatcher(PowerToysRunSettings settings, ThemeManager themeManager)
|
||||
{
|
||||
_settingsUtils = new SettingsUtils(new SystemIOProvider());
|
||||
_settingsUtils = new SettingsUtils();
|
||||
_settings = settings;
|
||||
_themeManager = themeManager;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
@@ -15,6 +15,11 @@ namespace Wox.Core.Plugin
|
||||
{
|
||||
internal abstract class PluginConfig
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
private const string PluginConfigName = "plugin.json";
|
||||
private static readonly List<PluginMetadata> PluginMetadatas = new List<PluginMetadata>();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
@@ -15,6 +16,11 @@ namespace Wox.Core.Plugin
|
||||
{
|
||||
internal class PluginInstaller
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
internal static void Install(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
@@ -35,7 +41,7 @@ namespace Wox.Core.Plugin
|
||||
}
|
||||
|
||||
PluginMetadata plugin = GetMetadataFromJson(tempFolder);
|
||||
if (plugin == null || plugin.Name == null)
|
||||
if (plugin?.Name == null)
|
||||
{
|
||||
MessageBox.Show("Install failed: plugin config is invalid");
|
||||
return;
|
||||
@@ -196,7 +202,7 @@ namespace Wox.Core.Plugin
|
||||
{
|
||||
if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName)))
|
||||
{
|
||||
using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName))
|
||||
using (Stream streamWriter = File.Create(strDirectory + directoryName + fileName))
|
||||
{
|
||||
byte[] data = new byte[2048];
|
||||
while (true)
|
||||
|
||||
@@ -6,7 +6,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
@@ -23,6 +23,9 @@ namespace Wox.Core.Plugin
|
||||
/// </summary>
|
||||
public static class PluginManager
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
private static IEnumerable<PluginPair> _contextMenuPlugins = new List<PluginPair>();
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,18 +4,27 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Wox.Infrastructure.FileSystemHelper
|
||||
{
|
||||
public class FileVersionInfoWrapper : IFileVersionInfoWrapper
|
||||
{
|
||||
private readonly IFile _file;
|
||||
|
||||
public FileVersionInfoWrapper()
|
||||
: this(new FileSystem().File)
|
||||
{
|
||||
}
|
||||
|
||||
public FileVersionInfoWrapper(IFile file)
|
||||
{
|
||||
_file = file;
|
||||
}
|
||||
|
||||
public FileVersionInfo GetVersionInfo(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
if (_file.Exists(path))
|
||||
{
|
||||
return FileVersionInfo.GetVersionInfo(path);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Wox.Infrastructure.FileSystemHelper
|
||||
{
|
||||
public class FileWrapper : IFileWrapper
|
||||
{
|
||||
public FileWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
public string[] ReadAllLines(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.ReadAllLines(path);
|
||||
}
|
||||
catch (System.Exception ex) when (ex is SecurityException || ex is UnauthorizedAccessException || ex is IOException)
|
||||
{
|
||||
Log.Info($"Unable to read File: {path}| {ex.Message}", GetType());
|
||||
|
||||
return new string[] { string.Empty };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Wox.Infrastructure.FileSystemHelper
|
||||
{
|
||||
public interface IFileWrapper
|
||||
{
|
||||
string[] ReadAllLines(string path);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
@@ -14,6 +14,12 @@ namespace Wox.Infrastructure
|
||||
{
|
||||
public static class Helper
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
private static readonly IFileInfoFactory FileInfo = FileSystem.FileInfo;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
/// <summary>
|
||||
/// http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy
|
||||
/// </summary>
|
||||
@@ -54,8 +60,8 @@ namespace Wox.Infrastructure
|
||||
}
|
||||
else
|
||||
{
|
||||
var time1 = new FileInfo(bundledDataPath).LastWriteTimeUtc;
|
||||
var time2 = new FileInfo(dataPath).LastWriteTimeUtc;
|
||||
var time1 = FileInfo.FromFileName(bundledDataPath).LastWriteTimeUtc;
|
||||
var time2 = FileInfo.FromFileName(dataPath).LastWriteTimeUtc;
|
||||
if (time1 != time2)
|
||||
{
|
||||
File.Copy(bundledDataPath, dataPath, true);
|
||||
|
||||
@@ -6,7 +6,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
@@ -21,6 +21,11 @@ namespace Wox.Infrastructure.Image
|
||||
{
|
||||
public static class ImageLoader
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
private static readonly ImageCache ImageCache = new ImageCache();
|
||||
private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
@@ -24,6 +24,9 @@ namespace Wox.Infrastructure.Image
|
||||
|
||||
public static class WindowsThumbnailProvider
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
||||
// Based on https://stackoverflow.com/questions/21751747/extract-thumbnail-for-any-file-in-windows
|
||||
private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
@@ -19,18 +20,28 @@ namespace Wox.Infrastructure.Storage
|
||||
/// </summary>
|
||||
public class BinaryStorage<T> : IStorage<T>
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
// This storage helper returns whether or not to delete the binary storage items
|
||||
private const int _binaryStorage = 0;
|
||||
private StoragePowerToysVersionInfo _storageHelper;
|
||||
|
||||
public BinaryStorage(string filename)
|
||||
: this(filename, new FileSystem())
|
||||
{
|
||||
}
|
||||
|
||||
public BinaryStorage(string filename, IFileSystem fileSystem)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
const string directoryName = "Cache";
|
||||
var directoryPath = Path.Combine(Constant.DataDirectory, directoryName);
|
||||
var path = _fileSystem.Path;
|
||||
var directoryPath = path.Combine(Constant.DataDirectory, directoryName);
|
||||
Helper.ValidateDirectory(directoryPath);
|
||||
|
||||
const string fileSuffix = ".cache";
|
||||
FilePath = Path.Combine(directoryPath, $"{filename}{fileSuffix}");
|
||||
FilePath = path.Combine(directoryPath, $"{filename}{fileSuffix}");
|
||||
}
|
||||
|
||||
public string FilePath { get; }
|
||||
@@ -42,17 +53,17 @@ namespace Wox.Infrastructure.Storage
|
||||
// Depending on the version number of the previously installed PT Run, delete the cache if it is found to be incompatible
|
||||
if (_storageHelper.ClearCache)
|
||||
{
|
||||
if (File.Exists(FilePath))
|
||||
if (_fileSystem.File.Exists(FilePath))
|
||||
{
|
||||
File.Delete(FilePath);
|
||||
_fileSystem.File.Delete(FilePath);
|
||||
|
||||
Log.Info($"Deleting cached data at <{FilePath}>", GetType());
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(FilePath))
|
||||
if (_fileSystem.File.Exists(FilePath))
|
||||
{
|
||||
if (new FileInfo(FilePath).Length == 0)
|
||||
if (_fileSystem.FileInfo.FromFileName(FilePath).Length == 0)
|
||||
{
|
||||
Log.Error($"Zero length cache file <{FilePath}>", GetType());
|
||||
|
||||
@@ -60,7 +71,7 @@ namespace Wox.Infrastructure.Storage
|
||||
return defaultData;
|
||||
}
|
||||
|
||||
using (var stream = new FileStream(FilePath, FileMode.Open))
|
||||
using (var stream = _fileSystem.FileStream.Create(FilePath, FileMode.Open))
|
||||
{
|
||||
var d = Deserialize(stream, defaultData);
|
||||
return d;
|
||||
@@ -76,7 +87,7 @@ namespace Wox.Infrastructure.Storage
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")]
|
||||
private T Deserialize(FileStream stream, T defaultData)
|
||||
private T Deserialize(Stream stream, T defaultData)
|
||||
{
|
||||
// http://stackoverflow.com/questions/2120055/binaryformatter-deserialize-gives-serializationexception
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
@@ -15,6 +16,10 @@ namespace Wox.Infrastructure.Storage
|
||||
/// </summary>
|
||||
public class JsonStorage<T>
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
private readonly JsonSerializerSettings _serializerSettings;
|
||||
private T _data;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Infrastructure.Storage
|
||||
@@ -10,6 +10,9 @@ namespace Wox.Infrastructure.Storage
|
||||
public class PluginJsonStorage<T> : JsonStorage<T>
|
||||
where T : new()
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
||||
public PluginJsonStorage()
|
||||
{
|
||||
// C# related, add python related below
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Wox.Infrastructure.Storage
|
||||
{
|
||||
public class StoragePowerToysVersionInfo
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
// This detail is accessed by the storage items and is used to decide if the cache must be deleted or not
|
||||
public bool ClearCache { get; set; }
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Infrastructure.Storage
|
||||
@@ -10,6 +10,9 @@ namespace Wox.Infrastructure.Storage
|
||||
public class WoxJsonStorage<T> : JsonStorage<T>
|
||||
where T : new()
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
||||
public WoxJsonStorage()
|
||||
{
|
||||
var directoryPath = Path.Combine(Constant.DataDirectory, DirectoryName);
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="NLog.Schema" Version="4.7.4" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
|
||||
<PackageReference Include="System.Runtime" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Wox.Plugin
|
||||
@@ -26,6 +26,10 @@ namespace Wox.Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
public const string ExeFileName = "PowerLauncher";
|
||||
public const string ModuleLocation = "Microsoft\\PowerToys\\PowerToys Run";
|
||||
public const string Plugins = "Plugins";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
@@ -13,6 +13,10 @@ namespace Wox.Plugin.Logger
|
||||
{
|
||||
public static class Log
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
public const string DirectoryName = "Logs";
|
||||
|
||||
public static string CurrentLogDirectory { get; }
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Wox.Plugin
|
||||
@@ -12,6 +12,9 @@ namespace Wox.Plugin
|
||||
[JsonObject(MemberSerialization.OptOut)]
|
||||
public class PluginMetadata : BaseModel
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
||||
private string _pluginDirectory;
|
||||
|
||||
private List<string> _actionKeywords;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace Wox.Plugin
|
||||
{
|
||||
public class Result
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
||||
private string _title;
|
||||
private ToolTipData _toolTipData;
|
||||
private string _pluginDirectory;
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Wox.Plugin.Logger;
|
||||
using Wox.Plugin.Properties;
|
||||
|
||||
namespace Wox.Plugin.SharedCommands
|
||||
{
|
||||
public static class FilesFolders
|
||||
{
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")]
|
||||
public static void Copy(this string sourcePath, string targetPath)
|
||||
{
|
||||
// Get the subdirectories for the specified directory.
|
||||
DirectoryInfo dir = new DirectoryInfo(sourcePath);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException(
|
||||
"Source directory does not exist or could not be found: "
|
||||
+ sourcePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
|
||||
// If the destination directory doesn't exist, create it.
|
||||
if (!Directory.Exists(targetPath))
|
||||
{
|
||||
Directory.CreateDirectory(targetPath);
|
||||
}
|
||||
|
||||
// Get the files in the directory and copy them to the new location.
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
string temppath = Path.Combine(targetPath, file.Name);
|
||||
file.CopyTo(temppath, false);
|
||||
}
|
||||
|
||||
// Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy
|
||||
foreach (DirectoryInfo subdir in dirs)
|
||||
{
|
||||
string temppath = Path.Combine(targetPath, subdir.Name);
|
||||
Copy(subdir.FullName, temppath);
|
||||
}
|
||||
}
|
||||
#pragma warning disable CS0168 // Variable is declared but never used. Due to #if debug vs release statement
|
||||
catch (Exception e)
|
||||
#pragma warning restore CS0168 // Variable is declared but never used
|
||||
{
|
||||
string error = $"Copying path {targetPath} has failed";
|
||||
Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType);
|
||||
#if DEBUG
|
||||
throw;
|
||||
#else
|
||||
// Using CurrentCulture since this is user facing
|
||||
System.Windows.MessageBox.Show(string.Format(CultureInfo.CurrentCulture, Resources.filesfolder_copy_failed, targetPath));
|
||||
RemoveFolder(targetPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")]
|
||||
public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fromDir = new DirectoryInfo(fromPath);
|
||||
var toDir = new DirectoryInfo(toPath);
|
||||
|
||||
if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != toDir.GetFiles("*", SearchOption.AllDirectories).Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != toDir.GetDirectories("*", SearchOption.AllDirectories).Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#pragma warning disable CS0168 // Variable is declared but never used. Due to #if debug vs release statement
|
||||
catch (Exception e)
|
||||
#pragma warning restore CS0168 // Variable is declared but never used
|
||||
{
|
||||
string error = $"Unable to verify folders and files between {fromPath} and {toPath}";
|
||||
Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType);
|
||||
#if DEBUG
|
||||
throw;
|
||||
#else
|
||||
// Using CurrentCulture since this is user facing
|
||||
System.Windows.MessageBox.Show(string.Format(CultureInfo.CurrentCulture, Resources.filesfolder_verifybothfolderfilesequal_failed, fromPath, toPath));
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")]
|
||||
public static void RemoveFolder(this string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
}
|
||||
#pragma warning disable CS0168 // Variable is declared but never used. Due to #if debug vs release statement
|
||||
catch (Exception e)
|
||||
#pragma warning restore CS0168 // Variable is declared but never used
|
||||
{
|
||||
string error = $"Not able to delete folder {path}";
|
||||
Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType);
|
||||
#if DEBUG
|
||||
throw;
|
||||
#else
|
||||
// Using CurrentCulture since this is user facing
|
||||
System.Windows.MessageBox.Show(string.Format(CultureInfo.CurrentCulture, Resources.filesfolder_removefolder_failed, path));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Wox.Plugin.SharedCommands
|
||||
{
|
||||
public static class SearchWeb
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens search in a new browser. If no browser path is passed in then Chrome is used.
|
||||
/// Leave browser path blank to use Chrome.
|
||||
/// </summary>
|
||||
public static void NewBrowserWindow(this Uri url, string browserPath)
|
||||
{
|
||||
if (url == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
}
|
||||
|
||||
var browserExecutableName = browserPath?
|
||||
.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
|
||||
.Last();
|
||||
|
||||
var browser = string.IsNullOrEmpty(browserExecutableName) ? "chrome" : browserPath;
|
||||
|
||||
// Internet Explorer will open url in new browser window, and does not take the --new-window parameter
|
||||
var browserArguments = browserExecutableName == "iexplore.exe" ? url.AbsoluteUri : "--new-window " + url.AbsoluteUri;
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start(browser, browserArguments);
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = url.AbsoluteUri,
|
||||
UseShellExecute = true,
|
||||
};
|
||||
Process.Start(psi);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens search as a tab in the default browser chosen in Windows settings.
|
||||
/// </summary>
|
||||
public static void NewTabInBrowser(this Uri url, string browserPath)
|
||||
{
|
||||
if (url == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(browserPath))
|
||||
{
|
||||
Process.Start(browserPath, url.AbsoluteUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
Process.Start(url.AbsoluteUri);
|
||||
}
|
||||
}
|
||||
|
||||
// This error may be thrown for Process.Start(browserPath, url)
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
Process.Start(url.AbsoluteUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Extensions.Figures;
|
||||
using Markdig.Extensions.Tables;
|
||||
|
||||
@@ -137,6 +137,9 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions">
|
||||
<Version>12.2.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
@@ -21,6 +21,10 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
/// </summary>
|
||||
public class MarkdownPreviewHandlerControl : FormHandlerControl
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
/// <summary>
|
||||
/// Extension to modify markdown AST.
|
||||
/// </summary>
|
||||
|
||||
@@ -148,6 +148,9 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions">
|
||||
<Version>12.2.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user