├── .media ├── Icon.ico ├── Icon.png ├── Icon.psd ├── Preview.jpg ├── console.png ├── gui_1.png ├── gui_2.png ├── gui_3.png ├── gui_4.png ├── DarkSkin.jpg └── LightSkin.jpg ├── src ├── UnityDarkSkin.App │ ├── Assets │ │ └── Icon.ico │ ├── Core │ │ ├── ApplicationData.cs │ │ ├── MessageHelper.cs │ │ ├── DataManager.cs │ │ ├── ThreadHelper.cs │ │ ├── JsonUtility.cs │ │ └── IOHelper.cs │ ├── App.xaml.cs │ ├── UnityDarkSkin.App.csproj │ ├── Views │ │ ├── FilesListWindow.xaml │ │ ├── FilesListWindow.xaml.cs │ │ ├── MainWindow.xaml │ │ └── MainWindow.xaml.cs │ ├── app.manifest │ └── App.xaml ├── UnityDarkSkin.Lib │ ├── UnityDarkSkin.Lib.csproj │ ├── Version.cs │ ├── Versions.cs │ └── Patcher.cs └── UnityDarkSkin.sln ├── LICENSE ├── readme.md ├── .github └── workflows │ └── build.yml └── .gitignore /.media/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/Icon.ico -------------------------------------------------------------------------------- /.media/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/Icon.png -------------------------------------------------------------------------------- /.media/Icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/Icon.psd -------------------------------------------------------------------------------- /.media/Preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/Preview.jpg -------------------------------------------------------------------------------- /.media/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/console.png -------------------------------------------------------------------------------- /.media/gui_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/gui_1.png -------------------------------------------------------------------------------- /.media/gui_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/gui_2.png -------------------------------------------------------------------------------- /.media/gui_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/gui_3.png -------------------------------------------------------------------------------- /.media/gui_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/gui_4.png -------------------------------------------------------------------------------- /.media/DarkSkin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/DarkSkin.jpg -------------------------------------------------------------------------------- /.media/LightSkin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/.media/LightSkin.jpg -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Assets/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluschenko/unity-dark-skin/HEAD/src/UnityDarkSkin.App/Assets/Icon.ico -------------------------------------------------------------------------------- /src/UnityDarkSkin.Lib/UnityDarkSkin.Lib.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Core/ApplicationData.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace UnityDarkSkin.Core 4 | { 5 | [DataContract] 6 | public class ApplicationData 7 | { 8 | [DataMember] 9 | public double WindowWidth; 10 | 11 | [DataMember] 12 | public double WindowHeight; 13 | } 14 | } -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace UnityDarkSkin.App 10 | { 11 | public partial class App : Application 12 | { 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.Lib/Version.cs: -------------------------------------------------------------------------------- 1 | namespace UnityDarkSkin.Lib 2 | { 3 | public class Version 4 | { 5 | private readonly string _name; 6 | public readonly byte[] LightBytes; 7 | public readonly byte[] DarkBytes; 8 | 9 | public Version(string name, byte[] lightBytes, byte[] darkBytes) 10 | { 11 | _name = name; 12 | LightBytes = lightBytes; 13 | DarkBytes = darkBytes; 14 | } 15 | 16 | public byte[] GetBytes(ThemeType skin) 17 | { 18 | return skin == ThemeType.Light ? LightBytes : DarkBytes; 19 | } 20 | 21 | public override string ToString() 22 | { 23 | return _name; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/UnityDarkSkin.App.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WinExe 5 | net5.0-windows 6 | true 7 | app.manifest 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Views/FilesListWindow.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | Lorem ipsum 0 14 | Lorem ipsum 1 15 | Lorem ipsum 2 16 | Lorem ipsum 3 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Core/MessageHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace UnityDarkSkin.Core 5 | { 6 | /// 7 | /// Easy templating of System.Windows.MessageBox 8 | /// 9 | public class MessageHelper 10 | { 11 | /// Info message box 12 | public static void Alert(string text, string title = "Alert") => 13 | MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Information); 14 | 15 | /// Warning message box 16 | public static void Warning(string text, string title = "Warning") => 17 | MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Warning); 18 | 19 | /// Error message box 20 | public static void Error(string text, string title = "Error") => 21 | MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Error); 22 | 23 | /// Displayes exception content 24 | public static void ThrowException(Exception exception) => 25 | Error(exception.ToString(), exception.GetType().Name); 26 | } 27 | } -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Core/DataManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace UnityDarkSkin.Core 5 | { 6 | public class DataManager 7 | { 8 | private string Path { get; set; } 9 | 10 | public DataManager(string path) 11 | { 12 | Path = path; 13 | } 14 | 15 | public T Load(Action onError) 16 | { 17 | if (File.Exists(Path)) 18 | { 19 | try 20 | { 21 | string data = File.ReadAllText(Path); 22 | return JsonUtility.FromJson(data); 23 | } 24 | catch (Exception ex) 25 | { 26 | onError?.Invoke(ex); 27 | } 28 | } 29 | 30 | return Activator.CreateInstance(); 31 | } 32 | 33 | public void Save(T obj, Action onError) 34 | { 35 | try 36 | { 37 | string data = JsonUtility.ToJson(obj); 38 | File.WriteAllText(Path, data); 39 | } 40 | catch (Exception ex) 41 | { 42 | onError?.Invoke(ex); 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Core/ThreadHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace UnityDarkSkin.Core 6 | { 7 | // Singleton thread manager 8 | public static class ThreadHelper 9 | { 10 | private static Thread _thread; 11 | private static readonly Queue Actions = new Queue(); 12 | 13 | private static void Init() 14 | { 15 | if (_thread == null) 16 | { 17 | _thread = new Thread(ThreadProc) {IsBackground = true}; 18 | _thread.Start(); 19 | } 20 | } 21 | 22 | private static void ThreadProc() 23 | { 24 | while (true) 25 | { 26 | if (Actions.Count > 0) 27 | { 28 | Actions.Dequeue()?.Invoke(); 29 | } 30 | else 31 | { 32 | Thread.Sleep(1); 33 | } 34 | } 35 | } 36 | 37 | public static void Invoke(Action action) 38 | { 39 | if (action != null) 40 | { 41 | Init(); 42 | Actions.Enqueue(action); 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Views/FilesListWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | 5 | /* 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using System.Windows.Data; 12 | using System.Windows.Documents; 13 | using System.Windows.Input; 14 | using System.Windows.Media; 15 | using System.Windows.Media.Imaging; 16 | using System.Windows.Shapes; 17 | */ 18 | 19 | namespace UnityDarkSkin.App 20 | { 21 | public partial class FilesListWindow : Window 22 | { 23 | public FilesListWindow(MainWindow Main, string[] files, Action onSelect) 24 | { 25 | InitializeComponent(); 26 | 27 | FilesList.Children.Clear(); 28 | foreach (string file in files) 29 | { 30 | ComboBoxItem item = new ComboBoxItem() { Content = file, ToolTip = file }; 31 | item.MouseDoubleClick += (sender, args) => { 32 | onSelect?.Invoke(file); 33 | // 34 | Close(); 35 | Main.Focus(); 36 | }; 37 | 38 | FilesList.Children.Add(item); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Core/JsonUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using System.Runtime.Serialization.Json; 5 | 6 | namespace UnityDarkSkin.Core 7 | { 8 | public class JsonUtility 9 | { 10 | public static string ToJson(object obj) 11 | { 12 | if (obj == null) 13 | return ""; 14 | 15 | var jsonFormatter = new DataContractJsonSerializer(obj.GetType()); 16 | 17 | using var stream = new MemoryStream(); 18 | jsonFormatter.WriteObject(stream, obj); 19 | return Encoding.UTF8.GetString(stream.ToArray()); 20 | } 21 | 22 | public static object FromJson(string json, Type type) 23 | { 24 | if (string.IsNullOrEmpty(json)) 25 | return null; 26 | if (type == null) 27 | throw new ArgumentNullException(nameof(type)); 28 | 29 | using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); 30 | DataContractJsonSerializer jsonFormatter = new DataContractJsonSerializer(type); 31 | return jsonFormatter.ReadObject(stream); 32 | } 33 | 34 | public static T FromJson(string json) 35 | { 36 | return (T) FromJson(json, typeof(T)); 37 | } 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # UnityDarkSkin 2 | 3 | ![](src/UnityDarkSkin.App/Assets/Icon.ico) 4 | 5 | [![.NET Core Desktop](https://github.com/Gluschenko/UnityDarkSkin/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/Gluschenko/UnityDarkSkin/actions/workflows/build.yml) 6 | 7 | ## About 8 | 9 | This tool makes Dark Theme in Unity Editor and turns it back to 'terrible' Light Theme, if you wish. It's being useful for Unity Personal, where theme settings are disabled by default. **It is not a crack! It's simply changing a couple of bits in Editor.exe** 10 | 11 | ## Usage 12 | 13 | 1. Compile `UnityDarkSkin.App` with Visual Studio 14 | 2. Run an executable file as **Administrator** 15 | 16 | ## Projects 17 | 18 | | Project | .NET version | Role | Description | 19 | | --- | --- | --- | --- | 20 | | UnityDarkSkin.App | Core 5.0 | WPF application | Advanced functionality via UI | 21 | | UnityDarkSkin.Lib | Core 5.0 | Patcher library | Versions data (byte records) | 22 | 23 | ## Requirements 24 | 25 | * Windows 10 (on newer) 26 | * Visual Studio 2019 (or newer) 27 | * .NET 5.0 SDK 28 | 29 | ## Supported versions 30 | 31 | | Version | Status | Tested on | 32 | | :--- | :---: | :--- | 33 | | 5.3 | ✅ | 5.3.5f1 | 34 | | 5.4 | ✅ | 5.4 | 35 | | 2017.2 | ✅ | 2017.2 | 36 | | 2018.2 | ✅ | 2018.2 | 37 | | 2018.3 | ✅ | 2018.3.0f2 | 38 | | 2018.4 | ✅ | 2018.4.24f1 (LTS) | 39 | | 2019.1 | ✅ | 2019.1.0f2 | 40 | | 2019.2 | ✅ | 2019.2.0f1, 2019.2.14f1 | 41 | | 2019.3 | ✅ | 2019.3.0f1 | 42 | | 2020.1 | ✅ | 2020.1.0f1 | 43 | 44 | ✅ - Supported | ⚠️ - Work in progress | ❌ - Not supported 45 | 46 | ## How it works 47 | 48 | | Before | After | 49 | | :---: | :---: | 50 | | ![Default theme](.media/LightSkin.jpg) | ![Dark theme](.media/DarkSkin.jpg) | 51 | 52 | ## Showcase 53 | 54 | | UnityDarkSkin.App | UnityDarkSkin | 55 | | :---: | :---: | 56 | | ![GUI](.media/gui_1.png) | ![Console](.media/console.png) | 57 | | ![GUI](.media/gui_2.png) | | 58 | | ![GUI](.media/gui_3.png) | | 59 | | ![GUI](.media/gui_4.png) | | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28729.10 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnityDarkSkin.App", "UnityDarkSkin.App\UnityDarkSkin.App.csproj", "{9D3C51BB-1491-407B-94DE-8F0916DA34FC}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnityDarkSkin.Lib", "UnityDarkSkin.Lib\UnityDarkSkin.Lib.csproj", "{7BD8B9A9-3504-4481-953D-D9A43EFDE3D4}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".docs", ".docs", "{17471794-99F6-4302-8F16-88F899C9B25F}" 11 | ProjectSection(SolutionItems) = preProject 12 | ..\readme.md = ..\readme.md 13 | EndProjectSection 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".deploy", ".deploy", "{FCA0ED07-3A9D-4258-BE03-8B79602F8587}" 16 | ProjectSection(SolutionItems) = preProject 17 | ..\.github\workflows\build.yml = ..\.github\workflows\build.yml 18 | EndProjectSection 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {9D3C51BB-1491-407B-94DE-8F0916DA34FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {9D3C51BB-1491-407B-94DE-8F0916DA34FC}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {9D3C51BB-1491-407B-94DE-8F0916DA34FC}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {9D3C51BB-1491-407B-94DE-8F0916DA34FC}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {7BD8B9A9-3504-4481-953D-D9A43EFDE3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {7BD8B9A9-3504-4481-953D-D9A43EFDE3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {7BD8B9A9-3504-4481-953D-D9A43EFDE3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {7BD8B9A9-3504-4481-953D-D9A43EFDE3D4}.Release|Any CPU.Build.0 = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {AC86378C-BEF8-4CEC-AA0A-2AE818DB23D5} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: .NET Core Desktop 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | runs-on: windows-latest 13 | env: 14 | ROOT: ./src 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: 📂 Setup .NET Core 19 | uses: actions/setup-dotnet@v1 20 | with: 21 | dotnet-version: 5.0.x 22 | 23 | - name: 📂 Files 24 | working-directory: ${{env.ROOT}} 25 | run: ls -R 26 | 27 | - name: 🚀 Building UnityDarkSkin.App 28 | working-directory: ${{env.ROOT}}/UnityDarkSkin.App 29 | run: dotnet publish -c RELEASE -o out 30 | 31 | - uses: actions/upload-artifact@v2 32 | with: 33 | name: builds 34 | path: ${{env.ROOT}}/**/out 35 | retention-days: 1 36 | 37 | deploy: 38 | 39 | runs-on: ubuntu-latest 40 | needs: build 41 | if: github.ref == 'refs/heads/master' 42 | env: 43 | ROOT: ./src 44 | NUGET_AUTH_TOKEN: ${{secrets.token}} 45 | 46 | steps: 47 | - uses: actions/checkout@v2 48 | 49 | - uses: actions/download-artifact@v2 50 | with: 51 | name: builds 52 | path: ${{env.ROOT}} 53 | 54 | - name: 📂 Setup .NET Core 55 | uses: actions/setup-dotnet@v1 56 | with: 57 | dotnet-version: 5.0.x 58 | 59 | - name: 📂 Pack UnityDarkSkin.App 60 | working-directory: ${{env.ROOT}}/UnityDarkSkin.App/out 61 | run: | 62 | sudo apt-get update 63 | sudo apt-get install zip 64 | zip -r -9 ./UnityDarkSkin.App.zip ./* 65 | 66 | - name: 📂 Files 67 | working-directory: ${{env.ROOT}} 68 | run: ls -R 69 | 70 | - name: Get current date 71 | id: date 72 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')" 73 | 74 | - name: Create Draft Release 75 | id: create_release 76 | uses: actions/create-release@v1 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | with: 80 | tag_name: ${{ steps.date.outputs.date }} 81 | release_name: Shapshot ${{ steps.date.outputs.date }} 82 | draft: true 83 | prerelease: false 84 | 85 | - uses: actions/upload-release-asset@v1.0.1 86 | env: 87 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 88 | with: 89 | upload_url: ${{ steps.create_release.outputs.upload_url }} 90 | asset_path: ./src/UnityDarkSkin.App/out/UnityDarkSkin.App.zip 91 | asset_name: UnityDarkSkin.App.zip 92 | asset_content_type: application/zip 93 | 94 | - uses: eregon/publish-release@v1 95 | env: 96 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 97 | with: 98 | release_id: ${{ steps.create_release.outputs.id }} 99 | 100 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Core/IOHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Microsoft.WindowsAPICodePack.Dialogs; 6 | 7 | namespace UnityDarkSkin.Core 8 | { 9 | public class IOHelper 10 | { 11 | public static void OpenFolderDialog(string initialDirectory, Action onDone = null, Action onCancel = null) 12 | { 13 | using var dialog = new CommonOpenFileDialog { InitialDirectory = initialDirectory, IsFolderPicker = true }; 14 | OpenDialog(dialog, onDone, onCancel); 15 | } 16 | 17 | public static void OpenFileDialog(string initialDirectory, Action onDone = null, Action onCancel = null) 18 | { 19 | using var dialog = new CommonOpenFileDialog { InitialDirectory = initialDirectory }; 20 | OpenDialog(dialog, onDone, onCancel); 21 | } 22 | 23 | public static void OpenDialog(CommonOpenFileDialog dialog, Action onDone, Action onCancel = null) 24 | { 25 | var result = dialog.ShowDialog(); 26 | 27 | switch (result) 28 | { 29 | case CommonFileDialogResult.Ok: 30 | onDone?.Invoke(dialog.FileName); 31 | break; 32 | case CommonFileDialogResult.Cancel: 33 | onCancel?.Invoke(); 34 | break; 35 | } 36 | } 37 | 38 | // 39 | 40 | public static string[] SearchFile(string directory, string fileName, bool recursive = true, bool containsName = false) 41 | { 42 | var files = new List(); 43 | InternalSearchFile(ref files, directory, fileName, recursive, containsName); 44 | return files.ToArray(); 45 | } 46 | 47 | private static void InternalSearchFile(ref List files, string directory, string fileName, bool recursive, bool containsName) 48 | { 49 | if (Directory.Exists(directory)) 50 | { 51 | var subDirs = Array.Empty(); 52 | var matchingFiles = Array.Empty(); 53 | 54 | try 55 | { 56 | subDirs = Directory.GetDirectories(directory); 57 | // 58 | Func search; 59 | if (containsName) 60 | search = (p) => Path.GetFileName(p).Contains(fileName); 61 | else 62 | search = (p) => Path.GetFileName(p).Equals(fileName); 63 | 64 | matchingFiles = Directory.GetFiles(directory).Where(search).ToArray(); 65 | files.AddRange(matchingFiles); 66 | } 67 | catch 68 | { 69 | // Don't care 70 | } 71 | // 72 | 73 | if (recursive) 74 | { 75 | foreach (string dir in subDirs) 76 | { 77 | InternalSearchFile(ref files, dir, fileName, recursive, containsName); 78 | } 79 | } 80 | } 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 53 | 60 | 61 | 62 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/UnityDarkSkin.App/Views/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 47 | 51 | 52 | 53 | 54 |