├── .gitignore ├── LICENSE ├── README.md ├── UnityLauncher.sln └── UnityLauncher ├── App.config ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Form2.Designer.cs ├── Form2.cs ├── Form2.resx ├── PreviousVersion.txt ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── Tools.cs ├── UnityLauncher.csproj └── unitylauncher.ico /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 UnityCoder.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Note: New Dark Theme WPF version is here : https://github.com/unitycoder/UnityLauncherPro 2 | 3 | ### this old winforms version is no longer updated! 4 | 5 | # UnityLauncher 6 | 7 | Handle all your Unity versions and Projects easily! 8 | 9 | # Features 10 | - Automagically Open Projects with Correct Unity Version 11 | - Display Recent Projects list with last modified date and project version info 12 | - Quickly Explore Project Folder 13 | - List installed Unity versions, can easily Run, Explore installation folder, View release notes 14 | - Download Missing Unity Versions Easily 15 | - Can be used from commandline `UnityLauncher.exe -projectPath "c:/project/path/"` 16 | - Can add custom Explorer context menu item to launch folder as a project: https://github.com/unitycoder/UnityLauncher/wiki/Adding-Explorer-Context-Menu 17 | - Use custom launcher arguments per project! 18 | - Show project git branch info 19 | - List of custom package folders (quicly explore them and then can import packages) 20 | - Show list of available Unity versions/updates 21 | 22 | # Instructions 23 | - Download, Run 24 | - At first run you need to setup "root installations folder" (All Unity installations will be scanned under this folder) 25 | - Recent projects list is fetched from registry (Project version and date is checked from those project folders) 26 | - Select row from the list and click "Launch" (Launches unity with that project) or "Explore" (opens Explorer to that folder) 27 | 28 | # Keyboard Shortcuts 29 | - When recent list is selected: Enter = Launch selected, F5 = refresh recent list 30 | - Project filter field: Esc - clear search 31 | 32 | # Download 33 | https://github.com/unitycoder/UnityLauncher/releases 34 | 35 | # Sources 36 | Project is created with VS2017 (and .net4.5) 37 | 38 | # Reporting Bugs / Requests 39 | https://github.com/unitycoder/UnityLauncher/issues 40 | 41 | # Unity Forum Thread 42 | https://forum.unity3d.com/threads/unitylauncher-launch-correct-unity-versions-for-each-project-automatically.488718/ 43 | 44 | # Images 45 | ![image](https://user-images.githubusercontent.com/5438317/35776535-65794550-09d9-11e8-925a-6b799d1a7b7f.png) 46 | 47 | ![image](https://user-images.githubusercontent.com/5438317/35776559-d4ecb8ae-09d9-11e8-90e9-a01e662367f7.png) 48 | 49 | ![image](https://user-images.githubusercontent.com/5438317/35776539-7b5a63a4-09d9-11e8-825b-956110d98499.png) 50 | 51 | ![image](https://user-images.githubusercontent.com/5438317/35776544-85f7c1f8-09d9-11e8-8ab7-ee08d01ebef3.png) 52 | 53 | ![image](https://user-images.githubusercontent.com/5438317/56789044-ac867c80-6809-11e9-9187-b998dbed0d0d.png) 54 | 55 | ![image](https://user-images.githubusercontent.com/5438317/35776575-01c720bc-09da-11e8-99d1-f6e4ad3c0fab.png) 56 | 57 | # Special Thanks (for fixes, updates, pull requests) 58 | - https://github.com/851marc 59 | - https://github.com/KyleOrth 60 | - https://github.com/Raebyn 61 | - Ville Tuhkanen 62 | - https://github.com/geo-at-github 63 | - https://github.com/yschuurmans 64 | -------------------------------------------------------------------------------- /UnityLauncher.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.6 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityLauncher", "UnityLauncher\UnityLauncher.csproj", "{C48990D2-A403-4E0E-80A2-A5D06FC77663}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {C48990D2-A403-4E0E-80A2-A5D06FC77663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {C48990D2-A403-4E0E-80A2-A5D06FC77663}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {C48990D2-A403-4E0E-80A2-A5D06FC77663}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {C48990D2-A403-4E0E-80A2-A5D06FC77663}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /UnityLauncher/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | C:\Program Files\ 18 | 19 | 20 | 21 | 22 | True 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | True 32 | 33 | 34 | False 35 | 36 | 37 | 600 38 | 39 | 40 | 650 41 | 42 | 43 | False 44 | 45 | 46 | False 47 | 48 | 49 | False 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /UnityLauncher/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace UnityLauncher 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 33 | this.tabControl1 = new System.Windows.Forms.TabControl(); 34 | this.tabProjects = new System.Windows.Forms.TabPage(); 35 | this.lblClearSearchField = new System.Windows.Forms.Label(); 36 | this.btnBrowseForProject = new System.Windows.Forms.Button(); 37 | this.btnRefreshProjectList = new System.Windows.Forms.Button(); 38 | this.tbSearchBar = new System.Windows.Forms.TextBox(); 39 | this.btnUpgradeProject = new System.Windows.Forms.Button(); 40 | this.btnRunUnityOnly = new System.Windows.Forms.Button(); 41 | this.btnOpenUnityFolder = new System.Windows.Forms.Button(); 42 | this.btnLaunch = new System.Windows.Forms.Button(); 43 | this.gridRecent = new System.Windows.Forms.DataGridView(); 44 | this._project = new System.Windows.Forms.DataGridViewTextBoxColumn(); 45 | this._version = new System.Windows.Forms.DataGridViewTextBoxColumn(); 46 | this._path = new System.Windows.Forms.DataGridViewTextBoxColumn(); 47 | this._dateModified = new System.Windows.Forms.DataGridViewTextBoxColumn(); 48 | this._launchArguments = new System.Windows.Forms.DataGridViewTextBoxColumn(); 49 | this._gitBranch = new System.Windows.Forms.DataGridViewTextBoxColumn(); 50 | this.tabUnitys = new System.Windows.Forms.TabPage(); 51 | this.btn_refreshUnityList = new System.Windows.Forms.Button(); 52 | this.btnOpenReleasePage = new System.Windows.Forms.Button(); 53 | this.btnExploreUnity = new System.Windows.Forms.Button(); 54 | this.btnLaunchUnity = new System.Windows.Forms.Button(); 55 | this.gridUnityList = new System.Windows.Forms.DataGridView(); 56 | this._unityVersion = new System.Windows.Forms.DataGridViewTextBoxColumn(); 57 | this._unityPath = new System.Windows.Forms.DataGridViewTextBoxColumn(); 58 | this._unityInstallDate = new System.Windows.Forms.DataGridViewTextBoxColumn(); 59 | this._Platforms = new System.Windows.Forms.DataGridViewTextBoxColumn(); 60 | this.tabPackages = new System.Windows.Forms.TabPage(); 61 | this.btnAddAssetStoreFolder = new System.Windows.Forms.Button(); 62 | this.btnExplorePackageFolder = new System.Windows.Forms.Button(); 63 | this.btnAddPackageFolder = new System.Windows.Forms.Button(); 64 | this.btnRemovePackFolder = new System.Windows.Forms.Button(); 65 | this.label3 = new System.Windows.Forms.Label(); 66 | this.lstPackageFolders = new System.Windows.Forms.ListBox(); 67 | this.tabUpdates = new System.Windows.Forms.TabPage(); 68 | this.btnDownloadNewUnity = new System.Windows.Forms.Button(); 69 | this.tbSearchUpdates = new System.Windows.Forms.TextBox(); 70 | this.btnOpenUpdateWebsite = new System.Windows.Forms.Button(); 71 | this.btnFetchUnityVersions = new System.Windows.Forms.Button(); 72 | this.gridUnityUpdates = new System.Windows.Forms.DataGridView(); 73 | this._Date = new System.Windows.Forms.DataGridViewTextBoxColumn(); 74 | this._UnityUpdateVersion = new System.Windows.Forms.DataGridViewTextBoxColumn(); 75 | this.tabSettings = new System.Windows.Forms.TabPage(); 76 | this.btnPlayerLogFolder = new System.Windows.Forms.Button(); 77 | this.btnOpenLogcatCmd = new System.Windows.Forms.Button(); 78 | this.chkDarkSkin = new System.Windows.Forms.CheckBox(); 79 | this.btnCheckUpdates = new System.Windows.Forms.Button(); 80 | this.linkProjectGithub = new System.Windows.Forms.LinkLabel(); 81 | this.linkArgumentsDocs = new System.Windows.Forms.LinkLabel(); 82 | this.chkShowGitBranchColumn = new System.Windows.Forms.CheckBox(); 83 | this.label5 = new System.Windows.Forms.Label(); 84 | this.chkShowLauncherArgumentsColumn = new System.Windows.Forms.CheckBox(); 85 | this.ChkQuitAfterOpen = new System.Windows.Forms.CheckBox(); 86 | this.btnOpenLogFolder = new System.Windows.Forms.Button(); 87 | this.chkQuitAfterCommandline = new System.Windows.Forms.CheckBox(); 88 | this.btnAddRegister = new System.Windows.Forms.Button(); 89 | this.btnRemoveRegister = new System.Windows.Forms.Button(); 90 | this.label4 = new System.Windows.Forms.Label(); 91 | this.label2 = new System.Windows.Forms.Label(); 92 | this.chkMinimizeToTaskbar = new System.Windows.Forms.CheckBox(); 93 | this.label1 = new System.Windows.Forms.Label(); 94 | this.btnAddUnityFolder = new System.Windows.Forms.Button(); 95 | this.btnRemoveInstallFolder = new System.Windows.Forms.Button(); 96 | this.lstRootFolders = new System.Windows.Forms.ListBox(); 97 | this.lbl_unityCount = new System.Windows.Forms.Label(); 98 | this.btnRefresh = new System.Windows.Forms.Button(); 99 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 100 | this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); 101 | this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); 102 | this.btnAddPackFolder = new System.Windows.Forms.Button(); 103 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 104 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 105 | this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); 106 | this.tabControl1.SuspendLayout(); 107 | this.tabProjects.SuspendLayout(); 108 | ((System.ComponentModel.ISupportInitialize)(this.gridRecent)).BeginInit(); 109 | this.tabUnitys.SuspendLayout(); 110 | ((System.ComponentModel.ISupportInitialize)(this.gridUnityList)).BeginInit(); 111 | this.tabPackages.SuspendLayout(); 112 | this.tabUpdates.SuspendLayout(); 113 | ((System.ComponentModel.ISupportInitialize)(this.gridUnityUpdates)).BeginInit(); 114 | this.tabSettings.SuspendLayout(); 115 | this.statusStrip1.SuspendLayout(); 116 | this.SuspendLayout(); 117 | // 118 | // tabControl1 119 | // 120 | this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 121 | | System.Windows.Forms.AnchorStyles.Left) 122 | | System.Windows.Forms.AnchorStyles.Right))); 123 | this.tabControl1.Controls.Add(this.tabProjects); 124 | this.tabControl1.Controls.Add(this.tabUnitys); 125 | this.tabControl1.Controls.Add(this.tabPackages); 126 | this.tabControl1.Controls.Add(this.tabUpdates); 127 | this.tabControl1.Controls.Add(this.tabSettings); 128 | this.tabControl1.Location = new System.Drawing.Point(0, 12); 129 | this.tabControl1.Name = "tabControl1"; 130 | this.tabControl1.SelectedIndex = 0; 131 | this.tabControl1.Size = new System.Drawing.Size(588, 575); 132 | this.tabControl1.TabIndex = 6; 133 | this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); 134 | // 135 | // tabProjects 136 | // 137 | this.tabProjects.Controls.Add(this.lblClearSearchField); 138 | this.tabProjects.Controls.Add(this.btnBrowseForProject); 139 | this.tabProjects.Controls.Add(this.btnRefreshProjectList); 140 | this.tabProjects.Controls.Add(this.tbSearchBar); 141 | this.tabProjects.Controls.Add(this.btnUpgradeProject); 142 | this.tabProjects.Controls.Add(this.btnRunUnityOnly); 143 | this.tabProjects.Controls.Add(this.btnOpenUnityFolder); 144 | this.tabProjects.Controls.Add(this.btnLaunch); 145 | this.tabProjects.Controls.Add(this.gridRecent); 146 | this.tabProjects.Location = new System.Drawing.Point(4, 22); 147 | this.tabProjects.Name = "tabProjects"; 148 | this.tabProjects.Size = new System.Drawing.Size(580, 549); 149 | this.tabProjects.TabIndex = 0; 150 | this.tabProjects.Text = "Projects"; 151 | this.tabProjects.UseVisualStyleBackColor = true; 152 | // 153 | // lblClearSearchField 154 | // 155 | this.lblClearSearchField.AutoSize = true; 156 | this.lblClearSearchField.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 157 | this.lblClearSearchField.ForeColor = System.Drawing.Color.DarkGray; 158 | this.lblClearSearchField.Location = new System.Drawing.Point(448, 8); 159 | this.lblClearSearchField.Name = "lblClearSearchField"; 160 | this.lblClearSearchField.Size = new System.Drawing.Size(12, 13); 161 | this.lblClearSearchField.TabIndex = 24; 162 | this.lblClearSearchField.Text = "x"; 163 | this.lblClearSearchField.Click += new System.EventHandler(this.lblClearSearchField_Click); 164 | this.lblClearSearchField.MouseEnter += new System.EventHandler(this.lblClearSearchField_MouseEnter); 165 | this.lblClearSearchField.MouseLeave += new System.EventHandler(this.lblClearSearchField_MouseLeave); 166 | // 167 | // btnBrowseForProject 168 | // 169 | this.btnBrowseForProject.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 170 | this.btnBrowseForProject.Location = new System.Drawing.Point(469, 3); 171 | this.btnBrowseForProject.Name = "btnBrowseForProject"; 172 | this.btnBrowseForProject.Size = new System.Drawing.Size(80, 23); 173 | this.btnBrowseForProject.TabIndex = 23; 174 | this.btnBrowseForProject.Text = "+ Add Project"; 175 | this.toolTip1.SetToolTip(this.btnBrowseForProject, "Browse for a Project"); 176 | this.btnBrowseForProject.UseVisualStyleBackColor = true; 177 | this.btnBrowseForProject.Click += new System.EventHandler(this.btnBrowseForProject_Click); 178 | // 179 | // btnRefreshProjectList 180 | // 181 | this.btnRefreshProjectList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 182 | this.btnRefreshProjectList.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 183 | this.btnRefreshProjectList.Location = new System.Drawing.Point(555, 3); 184 | this.btnRefreshProjectList.Name = "btnRefreshProjectList"; 185 | this.btnRefreshProjectList.Size = new System.Drawing.Size(22, 23); 186 | this.btnRefreshProjectList.TabIndex = 22; 187 | this.btnRefreshProjectList.Text = "⟳"; 188 | this.toolTip1.SetToolTip(this.btnRefreshProjectList, "Refresh Unity Installations List"); 189 | this.btnRefreshProjectList.UseCompatibleTextRendering = true; 190 | this.btnRefreshProjectList.UseVisualStyleBackColor = true; 191 | this.btnRefreshProjectList.Click += new System.EventHandler(this.btnRefreshProjectList_Click); 192 | // 193 | // tbSearchBar 194 | // 195 | this.tbSearchBar.Location = new System.Drawing.Point(3, 5); 196 | this.tbSearchBar.Name = "tbSearchBar"; 197 | this.tbSearchBar.Size = new System.Drawing.Size(460, 20); 198 | this.tbSearchBar.TabIndex = 0; 199 | this.tbSearchBar.TextChanged += new System.EventHandler(this.FilterRecentProject); 200 | // 201 | // btnUpgradeProject 202 | // 203 | this.btnUpgradeProject.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 204 | this.btnUpgradeProject.Location = new System.Drawing.Point(3, 511); 205 | this.btnUpgradeProject.Name = "btnUpgradeProject"; 206 | this.btnUpgradeProject.Size = new System.Drawing.Size(98, 35); 207 | this.btnUpgradeProject.TabIndex = 4; 208 | this.btnUpgradeProject.Text = "Upgrade Project"; 209 | this.toolTip1.SetToolTip(this.btnUpgradeProject, "Open File Explorer"); 210 | this.btnUpgradeProject.UseVisualStyleBackColor = true; 211 | this.btnUpgradeProject.Click += new System.EventHandler(this.btnUpgradeProject_Click); 212 | // 213 | // btnRunUnityOnly 214 | // 215 | this.btnRunUnityOnly.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 216 | this.btnRunUnityOnly.Location = new System.Drawing.Point(105, 511); 217 | this.btnRunUnityOnly.Name = "btnRunUnityOnly"; 218 | this.btnRunUnityOnly.Size = new System.Drawing.Size(67, 35); 219 | this.btnRunUnityOnly.TabIndex = 5; 220 | this.btnRunUnityOnly.Text = "Run Unity"; 221 | this.toolTip1.SetToolTip(this.btnRunUnityOnly, "Open File Explorer"); 222 | this.btnRunUnityOnly.UseVisualStyleBackColor = true; 223 | this.btnRunUnityOnly.Click += new System.EventHandler(this.btnRunUnityOnly_Click); 224 | // 225 | // btnOpenUnityFolder 226 | // 227 | this.btnOpenUnityFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 228 | this.btnOpenUnityFolder.Location = new System.Drawing.Point(510, 511); 229 | this.btnOpenUnityFolder.Name = "btnOpenUnityFolder"; 230 | this.btnOpenUnityFolder.Size = new System.Drawing.Size(67, 35); 231 | this.btnOpenUnityFolder.TabIndex = 3; 232 | this.btnOpenUnityFolder.Text = "Explore"; 233 | this.toolTip1.SetToolTip(this.btnOpenUnityFolder, "Open File Explorer"); 234 | this.btnOpenUnityFolder.UseVisualStyleBackColor = true; 235 | this.btnOpenUnityFolder.Click += new System.EventHandler(this.btn_openFolder_Click); 236 | // 237 | // btnLaunch 238 | // 239 | this.btnLaunch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 240 | this.btnLaunch.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 241 | this.btnLaunch.Location = new System.Drawing.Point(176, 511); 242 | this.btnLaunch.Name = "btnLaunch"; 243 | this.btnLaunch.Size = new System.Drawing.Size(330, 35); 244 | this.btnLaunch.TabIndex = 2; 245 | this.btnLaunch.Text = "Launch Project"; 246 | this.toolTip1.SetToolTip(this.btnLaunch, "Launch selected project"); 247 | this.btnLaunch.UseVisualStyleBackColor = true; 248 | this.btnLaunch.Click += new System.EventHandler(this.btnLaunch_Click); 249 | // 250 | // gridRecent 251 | // 252 | this.gridRecent.AllowUserToAddRows = false; 253 | this.gridRecent.AllowUserToDeleteRows = false; 254 | this.gridRecent.AllowUserToResizeRows = false; 255 | this.gridRecent.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 256 | | System.Windows.Forms.AnchorStyles.Left) 257 | | System.Windows.Forms.AnchorStyles.Right))); 258 | this.gridRecent.CausesValidation = false; 259 | this.gridRecent.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 260 | this.gridRecent.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 261 | this._project, 262 | this._version, 263 | this._path, 264 | this._dateModified, 265 | this._launchArguments, 266 | this._gitBranch}); 267 | this.gridRecent.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnF2; 268 | this.gridRecent.Location = new System.Drawing.Point(3, 30); 269 | this.gridRecent.MultiSelect = false; 270 | this.gridRecent.Name = "gridRecent"; 271 | this.gridRecent.RowHeadersWidth = 18; 272 | this.gridRecent.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 273 | this.gridRecent.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 274 | this.gridRecent.ShowCellErrors = false; 275 | this.gridRecent.ShowCellToolTips = false; 276 | this.gridRecent.Size = new System.Drawing.Size(574, 475); 277 | this.gridRecent.StandardTab = true; 278 | this.gridRecent.TabIndex = 1; 279 | this.gridRecent.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridRecent_CellEndEdit); 280 | this.gridRecent.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.GridRecent_CellMouseDoubleClick); 281 | this.gridRecent.KeyDown += new System.Windows.Forms.KeyEventHandler(this.gridRecent_KeyDown); 282 | // 283 | // _project 284 | // 285 | this._project.HeaderText = "Project"; 286 | this._project.Name = "_project"; 287 | this._project.ReadOnly = true; 288 | this._project.Resizable = System.Windows.Forms.DataGridViewTriState.True; 289 | this._project.Width = 150; 290 | // 291 | // _version 292 | // 293 | this._version.HeaderText = "Version"; 294 | this._version.Name = "_version"; 295 | this._version.ReadOnly = true; 296 | this._version.Width = 72; 297 | // 298 | // _path 299 | // 300 | this._path.HeaderText = "Path"; 301 | this._path.Name = "_path"; 302 | this._path.ReadOnly = true; 303 | this._path.Resizable = System.Windows.Forms.DataGridViewTriState.True; 304 | this._path.Width = 185; 305 | // 306 | // _dateModified 307 | // 308 | this._dateModified.HeaderText = "Modified"; 309 | this._dateModified.Name = "_dateModified"; 310 | this._dateModified.ReadOnly = true; 311 | this._dateModified.Resizable = System.Windows.Forms.DataGridViewTriState.True; 312 | this._dateModified.Width = 120; 313 | // 314 | // _launchArguments 315 | // 316 | this._launchArguments.HeaderText = "Arguments"; 317 | this._launchArguments.Name = "_launchArguments"; 318 | // 319 | // _gitBranch 320 | // 321 | this._gitBranch.HeaderText = "GITBranch"; 322 | this._gitBranch.Name = "_gitBranch"; 323 | this._gitBranch.ReadOnly = true; 324 | // 325 | // tabUnitys 326 | // 327 | this.tabUnitys.Controls.Add(this.btn_refreshUnityList); 328 | this.tabUnitys.Controls.Add(this.btnOpenReleasePage); 329 | this.tabUnitys.Controls.Add(this.btnExploreUnity); 330 | this.tabUnitys.Controls.Add(this.btnLaunchUnity); 331 | this.tabUnitys.Controls.Add(this.gridUnityList); 332 | this.tabUnitys.Location = new System.Drawing.Point(4, 22); 333 | this.tabUnitys.Name = "tabUnitys"; 334 | this.tabUnitys.Size = new System.Drawing.Size(580, 549); 335 | this.tabUnitys.TabIndex = 1; 336 | this.tabUnitys.Text = "Unitys"; 337 | this.tabUnitys.UseVisualStyleBackColor = true; 338 | // 339 | // btn_refreshUnityList 340 | // 341 | this.btn_refreshUnityList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 342 | this.btn_refreshUnityList.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 343 | this.btn_refreshUnityList.Location = new System.Drawing.Point(555, 3); 344 | this.btn_refreshUnityList.Name = "btn_refreshUnityList"; 345 | this.btn_refreshUnityList.Size = new System.Drawing.Size(22, 23); 346 | this.btn_refreshUnityList.TabIndex = 21; 347 | this.btn_refreshUnityList.Text = "⟳"; 348 | this.toolTip1.SetToolTip(this.btn_refreshUnityList, "Refresh Unity Installations List"); 349 | this.btn_refreshUnityList.UseCompatibleTextRendering = true; 350 | this.btn_refreshUnityList.UseVisualStyleBackColor = true; 351 | this.btn_refreshUnityList.Click += new System.EventHandler(this.btnRefresh_Click); 352 | // 353 | // btnOpenReleasePage 354 | // 355 | this.btnOpenReleasePage.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 356 | this.btnOpenReleasePage.Location = new System.Drawing.Point(411, 511); 357 | this.btnOpenReleasePage.Name = "btnOpenReleasePage"; 358 | this.btnOpenReleasePage.Size = new System.Drawing.Size(80, 35); 359 | this.btnOpenReleasePage.TabIndex = 17; 360 | this.btnOpenReleasePage.Text = "Release Notes"; 361 | this.toolTip1.SetToolTip(this.btnOpenReleasePage, "Open File Explorer"); 362 | this.btnOpenReleasePage.UseVisualStyleBackColor = true; 363 | this.btnOpenReleasePage.Click += new System.EventHandler(this.btnOpenReleasePage_Click); 364 | // 365 | // btnExploreUnity 366 | // 367 | this.btnExploreUnity.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 368 | this.btnExploreUnity.Location = new System.Drawing.Point(497, 511); 369 | this.btnExploreUnity.Name = "btnExploreUnity"; 370 | this.btnExploreUnity.Size = new System.Drawing.Size(80, 35); 371 | this.btnExploreUnity.TabIndex = 16; 372 | this.btnExploreUnity.Text = "Explore"; 373 | this.toolTip1.SetToolTip(this.btnExploreUnity, "Open File Explorer"); 374 | this.btnExploreUnity.UseVisualStyleBackColor = true; 375 | this.btnExploreUnity.Click += new System.EventHandler(this.btnExploreUnity_Click); 376 | // 377 | // btnLaunchUnity 378 | // 379 | this.btnLaunchUnity.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 380 | this.btnLaunchUnity.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 381 | this.btnLaunchUnity.Location = new System.Drawing.Point(3, 511); 382 | this.btnLaunchUnity.Name = "btnLaunchUnity"; 383 | this.btnLaunchUnity.Size = new System.Drawing.Size(402, 35); 384 | this.btnLaunchUnity.TabIndex = 15; 385 | this.btnLaunchUnity.Text = "Run Unity"; 386 | this.toolTip1.SetToolTip(this.btnLaunchUnity, "Launch selected project"); 387 | this.btnLaunchUnity.UseVisualStyleBackColor = true; 388 | this.btnLaunchUnity.Click += new System.EventHandler(this.btnLaunchUnity_Click); 389 | // 390 | // gridUnityList 391 | // 392 | this.gridUnityList.AllowUserToAddRows = false; 393 | this.gridUnityList.AllowUserToDeleteRows = false; 394 | this.gridUnityList.AllowUserToResizeColumns = false; 395 | this.gridUnityList.AllowUserToResizeRows = false; 396 | this.gridUnityList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 397 | | System.Windows.Forms.AnchorStyles.Left) 398 | | System.Windows.Forms.AnchorStyles.Right))); 399 | this.gridUnityList.CausesValidation = false; 400 | this.gridUnityList.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 401 | this.gridUnityList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 402 | this._unityVersion, 403 | this._unityPath, 404 | this._unityInstallDate, 405 | this._Platforms}); 406 | this.gridUnityList.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 407 | this.gridUnityList.Location = new System.Drawing.Point(3, 27); 408 | this.gridUnityList.MultiSelect = false; 409 | this.gridUnityList.Name = "gridUnityList"; 410 | this.gridUnityList.ReadOnly = true; 411 | this.gridUnityList.RowHeadersWidth = 15; 412 | this.gridUnityList.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 413 | this.gridUnityList.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 414 | this.gridUnityList.ShowCellErrors = false; 415 | this.gridUnityList.ShowCellToolTips = false; 416 | this.gridUnityList.ShowEditingIcon = false; 417 | this.gridUnityList.Size = new System.Drawing.Size(574, 478); 418 | this.gridUnityList.StandardTab = true; 419 | this.gridUnityList.TabIndex = 10; 420 | this.gridUnityList.KeyDown += new System.Windows.Forms.KeyEventHandler(this.unityGridView_KeyDown); 421 | // 422 | // _unityVersion 423 | // 424 | this._unityVersion.HeaderText = "Version"; 425 | this._unityVersion.MinimumWidth = 120; 426 | this._unityVersion.Name = "_unityVersion"; 427 | this._unityVersion.ReadOnly = true; 428 | this._unityVersion.Width = 120; 429 | // 430 | // _unityPath 431 | // 432 | this._unityPath.HeaderText = "Path"; 433 | this._unityPath.MinimumWidth = 300; 434 | this._unityPath.Name = "_unityPath"; 435 | this._unityPath.ReadOnly = true; 436 | this._unityPath.Resizable = System.Windows.Forms.DataGridViewTriState.False; 437 | this._unityPath.Width = 300; 438 | // 439 | // _unityInstallDate 440 | // 441 | this._unityInstallDate.HeaderText = "Installed"; 442 | this._unityInstallDate.Name = "_unityInstallDate"; 443 | this._unityInstallDate.ReadOnly = true; 444 | this._unityInstallDate.Width = 120; 445 | // 446 | // _Platforms 447 | // 448 | this._Platforms.HeaderText = "Platforms"; 449 | this._Platforms.Name = "_Platforms"; 450 | this._Platforms.ReadOnly = true; 451 | // 452 | // tabPackages 453 | // 454 | this.tabPackages.Controls.Add(this.btnAddAssetStoreFolder); 455 | this.tabPackages.Controls.Add(this.btnExplorePackageFolder); 456 | this.tabPackages.Controls.Add(this.btnAddPackageFolder); 457 | this.tabPackages.Controls.Add(this.btnRemovePackFolder); 458 | this.tabPackages.Controls.Add(this.label3); 459 | this.tabPackages.Controls.Add(this.lstPackageFolders); 460 | this.tabPackages.Location = new System.Drawing.Point(4, 22); 461 | this.tabPackages.Name = "tabPackages"; 462 | this.tabPackages.Size = new System.Drawing.Size(580, 549); 463 | this.tabPackages.TabIndex = 4; 464 | this.tabPackages.Text = "My Packages"; 465 | this.tabPackages.UseVisualStyleBackColor = true; 466 | // 467 | // btnAddAssetStoreFolder 468 | // 469 | this.btnAddAssetStoreFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 470 | this.btnAddAssetStoreFolder.Location = new System.Drawing.Point(416, 232); 471 | this.btnAddAssetStoreFolder.Name = "btnAddAssetStoreFolder"; 472 | this.btnAddAssetStoreFolder.Size = new System.Drawing.Size(142, 23); 473 | this.btnAddAssetStoreFolder.TabIndex = 29; 474 | this.btnAddAssetStoreFolder.Text = "Add AssetStore Folder"; 475 | this.btnAddAssetStoreFolder.UseVisualStyleBackColor = true; 476 | this.btnAddAssetStoreFolder.Click += new System.EventHandler(this.btnAddAssetStoreFolder_Click); 477 | // 478 | // btnExplorePackageFolder 479 | // 480 | this.btnExplorePackageFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 481 | | System.Windows.Forms.AnchorStyles.Right))); 482 | this.btnExplorePackageFolder.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 483 | this.btnExplorePackageFolder.Location = new System.Drawing.Point(3, 511); 484 | this.btnExplorePackageFolder.Name = "btnExplorePackageFolder"; 485 | this.btnExplorePackageFolder.Size = new System.Drawing.Size(574, 35); 486 | this.btnExplorePackageFolder.TabIndex = 28; 487 | this.btnExplorePackageFolder.Text = "Explore"; 488 | this.toolTip1.SetToolTip(this.btnExplorePackageFolder, "Open File Explorer"); 489 | this.btnExplorePackageFolder.UseVisualStyleBackColor = true; 490 | this.btnExplorePackageFolder.Click += new System.EventHandler(this.btnExplorePackageFolder_Click); 491 | // 492 | // btnAddPackageFolder 493 | // 494 | this.btnAddPackageFolder.Location = new System.Drawing.Point(19, 232); 495 | this.btnAddPackageFolder.Name = "btnAddPackageFolder"; 496 | this.btnAddPackageFolder.Size = new System.Drawing.Size(75, 23); 497 | this.btnAddPackageFolder.TabIndex = 27; 498 | this.btnAddPackageFolder.Text = "Add Folder"; 499 | this.btnAddPackageFolder.UseVisualStyleBackColor = true; 500 | this.btnAddPackageFolder.Click += new System.EventHandler(this.btnAddPackageFolder_Click); 501 | // 502 | // btnRemovePackFolder 503 | // 504 | this.btnRemovePackFolder.Location = new System.Drawing.Point(100, 232); 505 | this.btnRemovePackFolder.Name = "btnRemovePackFolder"; 506 | this.btnRemovePackFolder.Size = new System.Drawing.Size(104, 23); 507 | this.btnRemovePackFolder.TabIndex = 26; 508 | this.btnRemovePackFolder.Text = "Remove Folder"; 509 | this.btnRemovePackFolder.UseVisualStyleBackColor = true; 510 | this.btnRemovePackFolder.Click += new System.EventHandler(this.btnRemovePackFolder_Click); 511 | // 512 | // label3 513 | // 514 | this.label3.AutoSize = true; 515 | this.label3.Enabled = false; 516 | this.label3.Location = new System.Drawing.Point(16, 24); 517 | this.label3.Name = "label3"; 518 | this.label3.Size = new System.Drawing.Size(104, 13); 519 | this.label3.TabIndex = 25; 520 | this.label3.Text = "My Package Folders"; 521 | // 522 | // lstPackageFolders 523 | // 524 | this.lstPackageFolders.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 525 | | System.Windows.Forms.AnchorStyles.Right))); 526 | this.lstPackageFolders.FormattingEnabled = true; 527 | this.lstPackageFolders.Location = new System.Drawing.Point(19, 40); 528 | this.lstPackageFolders.Name = "lstPackageFolders"; 529 | this.lstPackageFolders.Size = new System.Drawing.Size(539, 186); 530 | this.lstPackageFolders.TabIndex = 21; 531 | // 532 | // tabUpdates 533 | // 534 | this.tabUpdates.Controls.Add(this.btnDownloadNewUnity); 535 | this.tabUpdates.Controls.Add(this.tbSearchUpdates); 536 | this.tabUpdates.Controls.Add(this.btnOpenUpdateWebsite); 537 | this.tabUpdates.Controls.Add(this.btnFetchUnityVersions); 538 | this.tabUpdates.Controls.Add(this.gridUnityUpdates); 539 | this.tabUpdates.Location = new System.Drawing.Point(4, 22); 540 | this.tabUpdates.Name = "tabUpdates"; 541 | this.tabUpdates.Size = new System.Drawing.Size(580, 549); 542 | this.tabUpdates.TabIndex = 5; 543 | this.tabUpdates.Text = "Updates"; 544 | this.tabUpdates.UseVisualStyleBackColor = true; 545 | // 546 | // btnDownloadNewUnity 547 | // 548 | this.btnDownloadNewUnity.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 549 | this.btnDownloadNewUnity.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 550 | this.btnDownloadNewUnity.Location = new System.Drawing.Point(3, 511); 551 | this.btnDownloadNewUnity.Name = "btnDownloadNewUnity"; 552 | this.btnDownloadNewUnity.Size = new System.Drawing.Size(239, 35); 553 | this.btnDownloadNewUnity.TabIndex = 25; 554 | this.btnDownloadNewUnity.Text = "Download in Browser"; 555 | this.toolTip1.SetToolTip(this.btnDownloadNewUnity, "Open Release Page"); 556 | this.btnDownloadNewUnity.UseVisualStyleBackColor = true; 557 | this.btnDownloadNewUnity.Click += new System.EventHandler(this.btnDownloadNewUnity_Click); 558 | // 559 | // tbSearchUpdates 560 | // 561 | this.tbSearchUpdates.Location = new System.Drawing.Point(3, 5); 562 | this.tbSearchUpdates.Name = "tbSearchUpdates"; 563 | this.tbSearchUpdates.Size = new System.Drawing.Size(460, 20); 564 | this.tbSearchUpdates.TabIndex = 8; 565 | this.tbSearchUpdates.TextChanged += new System.EventHandler(this.FilterUnityUpdates); 566 | // 567 | // btnOpenUpdateWebsite 568 | // 569 | this.btnOpenUpdateWebsite.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 570 | this.btnOpenUpdateWebsite.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 571 | this.btnOpenUpdateWebsite.Location = new System.Drawing.Point(248, 511); 572 | this.btnOpenUpdateWebsite.Name = "btnOpenUpdateWebsite"; 573 | this.btnOpenUpdateWebsite.Size = new System.Drawing.Size(329, 35); 574 | this.btnOpenUpdateWebsite.TabIndex = 24; 575 | this.btnOpenUpdateWebsite.Text = "Open Website"; 576 | this.toolTip1.SetToolTip(this.btnOpenUpdateWebsite, "Open Release Page"); 577 | this.btnOpenUpdateWebsite.UseVisualStyleBackColor = true; 578 | this.btnOpenUpdateWebsite.Click += new System.EventHandler(this.btnOpenUpdateWebsite_Click); 579 | // 580 | // btnFetchUnityVersions 581 | // 582 | this.btnFetchUnityVersions.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 583 | this.btnFetchUnityVersions.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 584 | this.btnFetchUnityVersions.Location = new System.Drawing.Point(555, 3); 585 | this.btnFetchUnityVersions.Name = "btnFetchUnityVersions"; 586 | this.btnFetchUnityVersions.Size = new System.Drawing.Size(22, 23); 587 | this.btnFetchUnityVersions.TabIndex = 23; 588 | this.btnFetchUnityVersions.Text = "⟳"; 589 | this.toolTip1.SetToolTip(this.btnFetchUnityVersions, "Fetch list of Unity Updates"); 590 | this.btnFetchUnityVersions.UseCompatibleTextRendering = true; 591 | this.btnFetchUnityVersions.UseVisualStyleBackColor = true; 592 | this.btnFetchUnityVersions.Click += new System.EventHandler(this.btnFetchUnityVersions_Click); 593 | // 594 | // gridUnityUpdates 595 | // 596 | this.gridUnityUpdates.AllowUserToAddRows = false; 597 | this.gridUnityUpdates.AllowUserToDeleteRows = false; 598 | this.gridUnityUpdates.AllowUserToResizeColumns = false; 599 | this.gridUnityUpdates.AllowUserToResizeRows = false; 600 | this.gridUnityUpdates.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 601 | | System.Windows.Forms.AnchorStyles.Left) 602 | | System.Windows.Forms.AnchorStyles.Right))); 603 | this.gridUnityUpdates.CausesValidation = false; 604 | this.gridUnityUpdates.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 605 | this.gridUnityUpdates.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 606 | this._Date, 607 | this._UnityUpdateVersion}); 608 | this.gridUnityUpdates.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 609 | this.gridUnityUpdates.Location = new System.Drawing.Point(3, 30); 610 | this.gridUnityUpdates.MultiSelect = false; 611 | this.gridUnityUpdates.Name = "gridUnityUpdates"; 612 | this.gridUnityUpdates.ReadOnly = true; 613 | this.gridUnityUpdates.RowHeadersWidth = 18; 614 | this.gridUnityUpdates.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 615 | this.gridUnityUpdates.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 616 | this.gridUnityUpdates.ShowCellErrors = false; 617 | this.gridUnityUpdates.ShowCellToolTips = false; 618 | this.gridUnityUpdates.ShowEditingIcon = false; 619 | this.gridUnityUpdates.Size = new System.Drawing.Size(574, 475); 620 | this.gridUnityUpdates.StandardTab = true; 621 | this.gridUnityUpdates.TabIndex = 22; 622 | // 623 | // _Date 624 | // 625 | this._Date.HeaderText = "Date"; 626 | this._Date.MinimumWidth = 100; 627 | this._Date.Name = "_Date"; 628 | this._Date.ReadOnly = true; 629 | this._Date.Resizable = System.Windows.Forms.DataGridViewTriState.False; 630 | // 631 | // _UnityUpdateVersion 632 | // 633 | this._UnityUpdateVersion.HeaderText = "Version"; 634 | this._UnityUpdateVersion.MinimumWidth = 350; 635 | this._UnityUpdateVersion.Name = "_UnityUpdateVersion"; 636 | this._UnityUpdateVersion.ReadOnly = true; 637 | this._UnityUpdateVersion.Width = 350; 638 | // 639 | // tabSettings 640 | // 641 | this.tabSettings.Controls.Add(this.btnPlayerLogFolder); 642 | this.tabSettings.Controls.Add(this.btnOpenLogcatCmd); 643 | this.tabSettings.Controls.Add(this.chkDarkSkin); 644 | this.tabSettings.Controls.Add(this.btnCheckUpdates); 645 | this.tabSettings.Controls.Add(this.linkProjectGithub); 646 | this.tabSettings.Controls.Add(this.linkArgumentsDocs); 647 | this.tabSettings.Controls.Add(this.chkShowGitBranchColumn); 648 | this.tabSettings.Controls.Add(this.label5); 649 | this.tabSettings.Controls.Add(this.chkShowLauncherArgumentsColumn); 650 | this.tabSettings.Controls.Add(this.ChkQuitAfterOpen); 651 | this.tabSettings.Controls.Add(this.btnOpenLogFolder); 652 | this.tabSettings.Controls.Add(this.chkQuitAfterCommandline); 653 | this.tabSettings.Controls.Add(this.btnAddRegister); 654 | this.tabSettings.Controls.Add(this.btnRemoveRegister); 655 | this.tabSettings.Controls.Add(this.label4); 656 | this.tabSettings.Controls.Add(this.label2); 657 | this.tabSettings.Controls.Add(this.chkMinimizeToTaskbar); 658 | this.tabSettings.Controls.Add(this.label1); 659 | this.tabSettings.Controls.Add(this.btnAddUnityFolder); 660 | this.tabSettings.Controls.Add(this.btnRemoveInstallFolder); 661 | this.tabSettings.Controls.Add(this.lstRootFolders); 662 | this.tabSettings.Controls.Add(this.lbl_unityCount); 663 | this.tabSettings.Controls.Add(this.btnRefresh); 664 | this.tabSettings.Location = new System.Drawing.Point(4, 22); 665 | this.tabSettings.Name = "tabSettings"; 666 | this.tabSettings.Size = new System.Drawing.Size(580, 549); 667 | this.tabSettings.TabIndex = 3; 668 | this.tabSettings.Text = "Settings"; 669 | this.tabSettings.UseVisualStyleBackColor = true; 670 | // 671 | // btnPlayerLogFolder 672 | // 673 | this.btnPlayerLogFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 674 | this.btnPlayerLogFolder.Location = new System.Drawing.Point(328, 300); 675 | this.btnPlayerLogFolder.Name = "btnPlayerLogFolder"; 676 | this.btnPlayerLogFolder.Size = new System.Drawing.Size(119, 23); 677 | this.btnPlayerLogFolder.TabIndex = 43; 678 | this.btnPlayerLogFolder.Text = "Player.log Folder"; 679 | this.btnPlayerLogFolder.UseVisualStyleBackColor = true; 680 | this.btnPlayerLogFolder.Click += new System.EventHandler(this.btnPlayerLogFolder_Click); 681 | // 682 | // btnOpenLogcatCmd 683 | // 684 | this.btnOpenLogcatCmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 685 | this.btnOpenLogcatCmd.Location = new System.Drawing.Point(453, 271); 686 | this.btnOpenLogcatCmd.Name = "btnOpenLogcatCmd"; 687 | this.btnOpenLogcatCmd.Size = new System.Drawing.Size(119, 23); 688 | this.btnOpenLogcatCmd.TabIndex = 42; 689 | this.btnOpenLogcatCmd.Text = "ADB logcat (cmd)"; 690 | this.toolTip1.SetToolTip(this.btnOpenLogcatCmd, "adb logcat -s Unity ActivityManager PackageManager dalvikvm DEBUG -v color"); 691 | this.btnOpenLogcatCmd.UseVisualStyleBackColor = true; 692 | this.btnOpenLogcatCmd.Click += new System.EventHandler(this.btnOpenLogcatCmd_Click); 693 | // 694 | // chkDarkSkin 695 | // 696 | this.chkDarkSkin.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 697 | this.chkDarkSkin.AutoSize = true; 698 | this.chkDarkSkin.Location = new System.Drawing.Point(20, 443); 699 | this.chkDarkSkin.Name = "chkDarkSkin"; 700 | this.chkDarkSkin.Size = new System.Drawing.Size(85, 17); 701 | this.chkDarkSkin.TabIndex = 41; 702 | this.chkDarkSkin.Text = "Dark Theme"; 703 | this.chkDarkSkin.UseVisualStyleBackColor = true; 704 | this.chkDarkSkin.CheckedChanged += new System.EventHandler(this.chkDarkSkin_CheckedChanged); 705 | // 706 | // btnCheckUpdates 707 | // 708 | this.btnCheckUpdates.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 709 | this.btnCheckUpdates.Location = new System.Drawing.Point(415, 495); 710 | this.btnCheckUpdates.Name = "btnCheckUpdates"; 711 | this.btnCheckUpdates.Size = new System.Drawing.Size(157, 23); 712 | this.btnCheckUpdates.TabIndex = 40; 713 | this.btnCheckUpdates.Text = "Open Github Releases Page"; 714 | this.btnCheckUpdates.UseVisualStyleBackColor = true; 715 | this.btnCheckUpdates.Click += new System.EventHandler(this.btnCheckUpdates_Click); 716 | // 717 | // linkProjectGithub 718 | // 719 | this.linkProjectGithub.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 720 | this.linkProjectGithub.AutoSize = true; 721 | this.linkProjectGithub.LinkArea = new System.Windows.Forms.LinkArea(20, 6); 722 | this.linkProjectGithub.LinkBehavior = System.Windows.Forms.LinkBehavior.AlwaysUnderline; 723 | this.linkProjectGithub.Location = new System.Drawing.Point(434, 532); 724 | this.linkProjectGithub.Name = "linkProjectGithub"; 725 | this.linkProjectGithub.Size = new System.Drawing.Size(138, 17); 726 | this.linkProjectGithub.TabIndex = 39; 727 | this.linkProjectGithub.TabStop = true; 728 | this.linkProjectGithub.Text = "Visit UnityLauncher Github"; 729 | this.linkProjectGithub.UseCompatibleTextRendering = true; 730 | this.linkProjectGithub.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkProjectGithub_LinkClicked); 731 | // 732 | // linkArgumentsDocs 733 | // 734 | this.linkArgumentsDocs.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 735 | this.linkArgumentsDocs.AutoSize = true; 736 | this.linkArgumentsDocs.LinkArea = new System.Windows.Forms.LinkArea(1, 4); 737 | this.linkArgumentsDocs.LinkBehavior = System.Windows.Forms.LinkBehavior.AlwaysUnderline; 738 | this.linkArgumentsDocs.Location = new System.Drawing.Point(385, 375); 739 | this.linkArgumentsDocs.Name = "linkArgumentsDocs"; 740 | this.linkArgumentsDocs.Size = new System.Drawing.Size(36, 17); 741 | this.linkArgumentsDocs.TabIndex = 38; 742 | this.linkArgumentsDocs.TabStop = true; 743 | this.linkArgumentsDocs.Text = "(docs)"; 744 | this.linkArgumentsDocs.UseCompatibleTextRendering = true; 745 | this.linkArgumentsDocs.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkArgumentsDocs_LinkClicked); 746 | // 747 | // chkShowGitBranchColumn 748 | // 749 | this.chkShowGitBranchColumn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 750 | this.chkShowGitBranchColumn.AutoSize = true; 751 | this.chkShowGitBranchColumn.Location = new System.Drawing.Point(266, 397); 752 | this.chkShowGitBranchColumn.Name = "chkShowGitBranchColumn"; 753 | this.chkShowGitBranchColumn.Size = new System.Drawing.Size(76, 17); 754 | this.chkShowGitBranchColumn.TabIndex = 36; 755 | this.chkShowGitBranchColumn.Text = "Git Branch"; 756 | this.chkShowGitBranchColumn.UseVisualStyleBackColor = true; 757 | this.chkShowGitBranchColumn.CheckedChanged += new System.EventHandler(this.checkShowGitBranchColumn_CheckedChanged); 758 | // 759 | // label5 760 | // 761 | this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 762 | this.label5.AutoSize = true; 763 | this.label5.Enabled = false; 764 | this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 765 | this.label5.Location = new System.Drawing.Point(263, 349); 766 | this.label5.Name = "label5"; 767 | this.label5.Size = new System.Drawing.Size(105, 13); 768 | this.label5.TabIndex = 35; 769 | this.label5.Text = "Optional Columns"; 770 | // 771 | // chkShowLauncherArgumentsColumn 772 | // 773 | this.chkShowLauncherArgumentsColumn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 774 | this.chkShowLauncherArgumentsColumn.AutoSize = true; 775 | this.chkShowLauncherArgumentsColumn.Location = new System.Drawing.Point(266, 374); 776 | this.chkShowLauncherArgumentsColumn.Name = "chkShowLauncherArgumentsColumn"; 777 | this.chkShowLauncherArgumentsColumn.Size = new System.Drawing.Size(124, 17); 778 | this.chkShowLauncherArgumentsColumn.TabIndex = 34; 779 | this.chkShowLauncherArgumentsColumn.Text = "Launcher Arguments"; 780 | this.chkShowLauncherArgumentsColumn.UseVisualStyleBackColor = true; 781 | this.chkShowLauncherArgumentsColumn.CheckedChanged += new System.EventHandler(this.checkShowLauncherArgumentsColumn_CheckedChanged); 782 | // 783 | // ChkQuitAfterOpen 784 | // 785 | this.ChkQuitAfterOpen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 786 | this.ChkQuitAfterOpen.AutoSize = true; 787 | this.ChkQuitAfterOpen.Location = new System.Drawing.Point(20, 397); 788 | this.ChkQuitAfterOpen.Name = "ChkQuitAfterOpen"; 789 | this.ChkQuitAfterOpen.Size = new System.Drawing.Size(172, 17); 790 | this.ChkQuitAfterOpen.TabIndex = 33; 791 | this.ChkQuitAfterOpen.Text = "Close after launching a project"; 792 | this.ChkQuitAfterOpen.UseVisualStyleBackColor = true; 793 | this.ChkQuitAfterOpen.CheckedChanged += new System.EventHandler(this.ChkQuitAfterOpen_CheckedChanged); 794 | // 795 | // btnOpenLogFolder 796 | // 797 | this.btnOpenLogFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 798 | this.btnOpenLogFolder.Location = new System.Drawing.Point(328, 271); 799 | this.btnOpenLogFolder.Name = "btnOpenLogFolder"; 800 | this.btnOpenLogFolder.Size = new System.Drawing.Size(119, 23); 801 | this.btnOpenLogFolder.TabIndex = 32; 802 | this.btnOpenLogFolder.Text = "Open Editor Log Folder"; 803 | this.btnOpenLogFolder.UseVisualStyleBackColor = true; 804 | this.btnOpenLogFolder.Click += new System.EventHandler(this.btnOpenLogFolder_Click); 805 | // 806 | // chkQuitAfterCommandline 807 | // 808 | this.chkQuitAfterCommandline.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 809 | this.chkQuitAfterCommandline.AutoSize = true; 810 | this.chkQuitAfterCommandline.Location = new System.Drawing.Point(20, 420); 811 | this.chkQuitAfterCommandline.Name = "chkQuitAfterCommandline"; 812 | this.chkQuitAfterCommandline.Size = new System.Drawing.Size(189, 17); 813 | this.chkQuitAfterCommandline.TabIndex = 31; 814 | this.chkQuitAfterCommandline.Text = "Close after launching from Explorer"; 815 | this.chkQuitAfterCommandline.UseVisualStyleBackColor = true; 816 | this.chkQuitAfterCommandline.CheckedChanged += new System.EventHandler(this.chkQuitAfterCommandline_CheckedChanged); 817 | // 818 | // btnAddRegister 819 | // 820 | this.btnAddRegister.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 821 | this.btnAddRegister.Location = new System.Drawing.Point(139, 493); 822 | this.btnAddRegister.Name = "btnAddRegister"; 823 | this.btnAddRegister.Size = new System.Drawing.Size(64, 23); 824 | this.btnAddRegister.TabIndex = 30; 825 | this.btnAddRegister.Text = "Install"; 826 | this.btnAddRegister.UseVisualStyleBackColor = true; 827 | this.btnAddRegister.Click += new System.EventHandler(this.btnAddRegister_Click); 828 | // 829 | // btnRemoveRegister 830 | // 831 | this.btnRemoveRegister.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 832 | this.btnRemoveRegister.Location = new System.Drawing.Point(209, 493); 833 | this.btnRemoveRegister.Name = "btnRemoveRegister"; 834 | this.btnRemoveRegister.Size = new System.Drawing.Size(64, 23); 835 | this.btnRemoveRegister.TabIndex = 29; 836 | this.btnRemoveRegister.Text = "Uninstall"; 837 | this.btnRemoveRegister.UseVisualStyleBackColor = true; 838 | this.btnRemoveRegister.Click += new System.EventHandler(this.btnRemoveRegister_Click); 839 | // 840 | // label4 841 | // 842 | this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 843 | this.label4.AutoSize = true; 844 | this.label4.Location = new System.Drawing.Point(19, 498); 845 | this.label4.Name = "label4"; 846 | this.label4.Size = new System.Drawing.Size(117, 13); 847 | this.label4.TabIndex = 28; 848 | this.label4.Text = "Explorer Context Menu:"; 849 | // 850 | // label2 851 | // 852 | this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 853 | this.label2.AutoSize = true; 854 | this.label2.Enabled = false; 855 | this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 856 | this.label2.Location = new System.Drawing.Point(17, 349); 857 | this.label2.Name = "label2"; 858 | this.label2.Size = new System.Drawing.Size(88, 13); 859 | this.label2.TabIndex = 26; 860 | this.label2.Text = "Other Settings"; 861 | // 862 | // chkMinimizeToTaskbar 863 | // 864 | this.chkMinimizeToTaskbar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 865 | this.chkMinimizeToTaskbar.AutoSize = true; 866 | this.chkMinimizeToTaskbar.Location = new System.Drawing.Point(20, 374); 867 | this.chkMinimizeToTaskbar.Name = "chkMinimizeToTaskbar"; 868 | this.chkMinimizeToTaskbar.Size = new System.Drawing.Size(116, 17); 869 | this.chkMinimizeToTaskbar.TabIndex = 25; 870 | this.chkMinimizeToTaskbar.Text = "Minimize to taskbar"; 871 | this.chkMinimizeToTaskbar.UseVisualStyleBackColor = true; 872 | this.chkMinimizeToTaskbar.CheckedChanged += new System.EventHandler(this.chkMinimizeToTaskbar_CheckedChanged); 873 | // 874 | // label1 875 | // 876 | this.label1.AutoSize = true; 877 | this.label1.Enabled = false; 878 | this.label1.Location = new System.Drawing.Point(17, 15); 879 | this.label1.Name = "label1"; 880 | this.label1.Size = new System.Drawing.Size(102, 13); 881 | this.label1.TabIndex = 24; 882 | this.label1.Text = "Unity Parent Folders"; 883 | // 884 | // btnAddUnityFolder 885 | // 886 | this.btnAddUnityFolder.Location = new System.Drawing.Point(20, 223); 887 | this.btnAddUnityFolder.Name = "btnAddUnityFolder"; 888 | this.btnAddUnityFolder.Size = new System.Drawing.Size(75, 23); 889 | this.btnAddUnityFolder.TabIndex = 23; 890 | this.btnAddUnityFolder.Text = "Add Folder"; 891 | this.btnAddUnityFolder.UseVisualStyleBackColor = true; 892 | this.btnAddUnityFolder.Click += new System.EventHandler(this.btnAddUnityFolder_Click); 893 | // 894 | // btnRemoveInstallFolder 895 | // 896 | this.btnRemoveInstallFolder.Location = new System.Drawing.Point(101, 223); 897 | this.btnRemoveInstallFolder.Name = "btnRemoveInstallFolder"; 898 | this.btnRemoveInstallFolder.Size = new System.Drawing.Size(104, 23); 899 | this.btnRemoveInstallFolder.TabIndex = 22; 900 | this.btnRemoveInstallFolder.Text = "Remove Folder"; 901 | this.btnRemoveInstallFolder.UseVisualStyleBackColor = true; 902 | this.btnRemoveInstallFolder.Click += new System.EventHandler(this.btnRemoveInstallFolder_Click); 903 | // 904 | // lstRootFolders 905 | // 906 | this.lstRootFolders.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 907 | | System.Windows.Forms.AnchorStyles.Right))); 908 | this.lstRootFolders.FormattingEnabled = true; 909 | this.lstRootFolders.Location = new System.Drawing.Point(20, 31); 910 | this.lstRootFolders.Name = "lstRootFolders"; 911 | this.lstRootFolders.Size = new System.Drawing.Size(563, 186); 912 | this.lstRootFolders.TabIndex = 20; 913 | // 914 | // lbl_unityCount 915 | // 916 | this.lbl_unityCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 917 | this.lbl_unityCount.AutoSize = true; 918 | this.lbl_unityCount.Enabled = false; 919 | this.lbl_unityCount.Location = new System.Drawing.Point(483, 15); 920 | this.lbl_unityCount.Name = "lbl_unityCount"; 921 | this.lbl_unityCount.Size = new System.Drawing.Size(97, 13); 922 | this.lbl_unityCount.TabIndex = 18; 923 | this.lbl_unityCount.Text = "Founded - versions"; 924 | // 925 | // btnRefresh 926 | // 927 | this.btnRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 928 | this.btnRefresh.Location = new System.Drawing.Point(453, 223); 929 | this.btnRefresh.Name = "btnRefresh"; 930 | this.btnRefresh.Size = new System.Drawing.Size(119, 23); 931 | this.btnRefresh.TabIndex = 19; 932 | this.btnRefresh.Text = "Refresh Unity List"; 933 | this.toolTip1.SetToolTip(this.btnRefresh, "Refresh Unity Installations List"); 934 | this.btnRefresh.UseVisualStyleBackColor = true; 935 | this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click); 936 | // 937 | // toolTip1 938 | // 939 | this.toolTip1.ToolTipTitle = "UnityLauncher"; 940 | this.toolTip1.UseAnimation = false; 941 | this.toolTip1.UseFading = false; 942 | // 943 | // notifyIcon 944 | // 945 | this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); 946 | this.notifyIcon.Text = "UnityLauncher"; 947 | this.notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseClick); 948 | // 949 | // btnAddPackFolder 950 | // 951 | this.btnAddPackFolder.Location = new System.Drawing.Point(19, 232); 952 | this.btnAddPackFolder.Name = "btnAddPackFolder"; 953 | this.btnAddPackFolder.Size = new System.Drawing.Size(75, 23); 954 | this.btnAddPackFolder.TabIndex = 27; 955 | this.btnAddPackFolder.Text = "Add Folder"; 956 | this.btnAddPackFolder.UseVisualStyleBackColor = true; 957 | // 958 | // statusStrip1 959 | // 960 | // this next line keeps disappearing : this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.toolStripStatusLabel1}); 961 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripStatusLabel1 }); 962 | this.statusStrip1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 963 | | System.Windows.Forms.AnchorStyles.Right))); 964 | this.statusStrip1.AutoSize = false; 965 | this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None; 966 | this.statusStrip1.Location = new System.Drawing.Point(0, 590); 967 | this.statusStrip1.Name = "statusStrip1"; 968 | this.statusStrip1.Size = new System.Drawing.Size(579, 22); 969 | this.statusStrip1.SizingGrip = false; 970 | this.statusStrip1.TabIndex = 7; 971 | this.statusStrip1.Text = "statusStrip1"; 972 | // 973 | // toolStripStatusLabel1 974 | // 975 | this.toolStripStatusLabel1.AutoSize = false; 976 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 977 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(550, 17); 978 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 979 | this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 980 | // 981 | // Form1 982 | // 983 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 984 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 985 | this.ClientSize = new System.Drawing.Size(588, 612); 986 | this.Controls.Add(this.statusStrip1); 987 | this.Controls.Add(this.tabControl1); 988 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 989 | this.KeyPreview = true; 990 | this.MaximizeBox = false; 991 | this.MinimumSize = new System.Drawing.Size(600, 650); 992 | this.Name = "Form1"; 993 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; 994 | this.Text = "UnityLauncher - AutumnEdition 29"; 995 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); 996 | this.Load += new System.EventHandler(this.Form1_Load); 997 | this.ResizeEnd += new System.EventHandler(this.Form1_ResizeEnd); 998 | this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form1_KeyPress); 999 | this.Resize += new System.EventHandler(this.Form1_Resize); 1000 | this.tabControl1.ResumeLayout(false); 1001 | this.tabProjects.ResumeLayout(false); 1002 | this.tabProjects.PerformLayout(); 1003 | ((System.ComponentModel.ISupportInitialize)(this.gridRecent)).EndInit(); 1004 | this.tabUnitys.ResumeLayout(false); 1005 | ((System.ComponentModel.ISupportInitialize)(this.gridUnityList)).EndInit(); 1006 | this.tabPackages.ResumeLayout(false); 1007 | this.tabPackages.PerformLayout(); 1008 | this.tabUpdates.ResumeLayout(false); 1009 | this.tabUpdates.PerformLayout(); 1010 | ((System.ComponentModel.ISupportInitialize)(this.gridUnityUpdates)).EndInit(); 1011 | this.tabSettings.ResumeLayout(false); 1012 | this.tabSettings.PerformLayout(); 1013 | this.statusStrip1.ResumeLayout(false); 1014 | this.statusStrip1.PerformLayout(); 1015 | this.ResumeLayout(false); 1016 | 1017 | } 1018 | 1019 | #endregion 1020 | private System.Windows.Forms.TabControl tabControl1; 1021 | private System.Windows.Forms.TabPage tabProjects; 1022 | private System.Windows.Forms.Button btnOpenUnityFolder; 1023 | private System.Windows.Forms.ToolTip toolTip1; 1024 | private System.Windows.Forms.Button btnLaunch; 1025 | private System.Windows.Forms.DataGridView gridRecent; 1026 | private System.Windows.Forms.TabPage tabUnitys; 1027 | private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; 1028 | private System.Windows.Forms.NotifyIcon notifyIcon; 1029 | private System.Windows.Forms.TabPage tabSettings; 1030 | private System.Windows.Forms.Label lbl_unityCount; 1031 | private System.Windows.Forms.Button btnRefresh; 1032 | private System.Windows.Forms.DataGridView gridUnityList; 1033 | private System.Windows.Forms.Button btnExploreUnity; 1034 | private System.Windows.Forms.Button btnLaunchUnity; 1035 | private System.Windows.Forms.ListBox lstRootFolders; 1036 | private System.Windows.Forms.Button btnAddUnityFolder; 1037 | private System.Windows.Forms.Button btnRemoveInstallFolder; 1038 | private System.Windows.Forms.Label label1; 1039 | private System.Windows.Forms.Button btnOpenReleasePage; 1040 | private System.Windows.Forms.Label label2; 1041 | private System.Windows.Forms.CheckBox chkMinimizeToTaskbar; 1042 | private System.Windows.Forms.TabPage tabPackages; 1043 | private System.Windows.Forms.ListBox lstPackageFolders; 1044 | private System.Windows.Forms.Label label3; 1045 | private System.Windows.Forms.Button btnExplorePackageFolder; 1046 | private System.Windows.Forms.Button btnAddPackageFolder; 1047 | private System.Windows.Forms.Button btnRemovePackFolder; 1048 | private System.Windows.Forms.Button btnAddPackFolder; 1049 | private System.Windows.Forms.Button btnAddAssetStoreFolder; 1050 | private System.Windows.Forms.Button btnAddRegister; 1051 | private System.Windows.Forms.Button btnRemoveRegister; 1052 | private System.Windows.Forms.Label label4; 1053 | private System.Windows.Forms.CheckBox chkQuitAfterCommandline; 1054 | private System.Windows.Forms.Button btnRunUnityOnly; 1055 | private System.Windows.Forms.StatusStrip statusStrip1; 1056 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; 1057 | private System.Windows.Forms.Button btnUpgradeProject; 1058 | private System.Windows.Forms.Button btnOpenLogFolder; 1059 | private System.Windows.Forms.TextBox tbSearchBar; 1060 | private System.Windows.Forms.CheckBox ChkQuitAfterOpen; 1061 | private System.Windows.Forms.Button btn_refreshUnityList; 1062 | private System.Windows.Forms.TabPage tabUpdates; 1063 | private System.Windows.Forms.Button btnFetchUnityVersions; 1064 | private System.Windows.Forms.DataGridView gridUnityUpdates; 1065 | private System.Windows.Forms.Button btnOpenUpdateWebsite; 1066 | private System.Windows.Forms.DataGridViewTextBoxColumn _Date; 1067 | private System.Windows.Forms.DataGridViewTextBoxColumn _UnityUpdateVersion; 1068 | private System.Windows.Forms.DataGridViewTextBoxColumn _project; 1069 | private System.Windows.Forms.DataGridViewTextBoxColumn _version; 1070 | private System.Windows.Forms.DataGridViewTextBoxColumn _path; 1071 | private System.Windows.Forms.DataGridViewTextBoxColumn _dateModified; 1072 | private System.Windows.Forms.DataGridViewTextBoxColumn _launchArguments; 1073 | private System.Windows.Forms.DataGridViewTextBoxColumn _gitBranch; 1074 | private System.Windows.Forms.CheckBox chkShowGitBranchColumn; 1075 | private System.Windows.Forms.Label label5; 1076 | private System.Windows.Forms.CheckBox chkShowLauncherArgumentsColumn; 1077 | private System.Windows.Forms.LinkLabel linkArgumentsDocs; 1078 | private System.Windows.Forms.LinkLabel linkProjectGithub; 1079 | private System.Windows.Forms.Button btnCheckUpdates; 1080 | private System.Windows.Forms.Button btnRefreshProjectList; 1081 | private System.Windows.Forms.Button btnBrowseForProject; 1082 | private System.Windows.Forms.DataGridViewTextBoxColumn _unityVersion; 1083 | private System.Windows.Forms.DataGridViewTextBoxColumn _unityPath; 1084 | private System.Windows.Forms.DataGridViewTextBoxColumn _unityInstallDate; 1085 | private System.Windows.Forms.DataGridViewTextBoxColumn _Platforms; 1086 | private System.Windows.Forms.TextBox tbSearchUpdates; 1087 | private System.ComponentModel.BackgroundWorker backgroundWorker1; 1088 | private System.Windows.Forms.CheckBox chkDarkSkin; 1089 | private System.Windows.Forms.Button btnOpenLogcatCmd; 1090 | private System.Windows.Forms.Button btnDownloadNewUnity; 1091 | private System.Windows.Forms.Button btnPlayerLogFolder; 1092 | private System.Windows.Forms.Label lblClearSearchField; 1093 | } 1094 | } 1095 | 1096 | -------------------------------------------------------------------------------- /UnityLauncher/Form1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Reflection; 10 | using System.Text; 11 | using System.Text.RegularExpressions; 12 | using System.Windows.Forms; 13 | using UnityLauncherTools; 14 | 15 | namespace UnityLauncher 16 | { 17 | public partial class Form1 : Form 18 | { 19 | public static Dictionary unityList = new Dictionary(); 20 | const string contextRegRoot = "Software\\Classes\\Directory\\Background\\shell"; 21 | const string launcherArgumentsFile = "LauncherArguments.txt"; 22 | const string githubReleasesLinkURL = "https://github.com/unitycoder/UnityLauncher/releases"; 23 | 24 | bool isDownloadingUnityList = false; 25 | string previousGitRelease = "0"; 26 | 27 | 28 | public Form1() 29 | { 30 | InitializeComponent(); 31 | } 32 | 33 | private void Form1_Load(object sender, EventArgs e) 34 | { 35 | Start(); 36 | } 37 | 38 | 39 | 40 | void Start() 41 | { 42 | SetStatus("Initializing ..."); 43 | // check installations folder 44 | var root = GetUnityInstallationsRootFolder(); 45 | if (root == null || root.Length == 0) 46 | { 47 | SetStatus("Missing root folder ..."); 48 | AddUnityInstallationRootFolder(); 49 | SetStatus("Ready"); 50 | } 51 | 52 | LoadSettings(); 53 | 54 | // scan installed unitys 55 | bool foundUnitys = ScanUnityInstallations(); 56 | if (foundUnitys == false) 57 | { 58 | SetStatus("Error> Did not find any Unity installations, try setting correct root folder ..."); 59 | UpdateRecentProjectsList(); 60 | tabControl1.SelectedIndex = tabControl1.TabCount - 1; // last tab is settings 61 | return; 62 | } 63 | 64 | 65 | 66 | // check if received -projectPath argument (that means opening from explorer / cmdline) 67 | string[] args = Environment.GetCommandLineArgs(); 68 | if (args != null && args.Length > 2) 69 | { 70 | // first argument needs to be -projectPath 71 | var commandLineArgs = args[1]; 72 | if (commandLineArgs == "-projectPath") 73 | { 74 | SetStatus("Launching from commandline ..."); 75 | 76 | // path 77 | var projectPathArgument = args[2]; 78 | 79 | // resolve full path if path parameter isn't a rooted path 80 | if (!Path.IsPathRooted(projectPathArgument)) 81 | { 82 | projectPathArgument = Directory.GetCurrentDirectory() + projectPathArgument; 83 | } 84 | 85 | var version = Tools.GetProjectVersion(projectPathArgument); 86 | 87 | // take extra arguments also 88 | var commandLineArguments = ""; 89 | for (int i = 3, len = args.Length; i < len; i++) 90 | { 91 | commandLineArguments += " " + args[i]; 92 | } 93 | 94 | // check if force-update button is down 95 | if ((Control.ModifierKeys & Keys.Shift) != 0) 96 | { 97 | DisplayUpgradeDialog(version, projectPathArgument, launchProject: true, commandLineArguments: commandLineArguments); 98 | } 99 | else 100 | { 101 | // try launching it 102 | LaunchProject(projectPathArgument, version, openProject: true, commandLineArguments: commandLineArguments); 103 | } 104 | 105 | 106 | // quit after launch if enabled in settings 107 | if (Properties.Settings.Default.closeAfterExplorer == true) 108 | { 109 | Application.Exit(); 110 | } 111 | 112 | //SetStatus("Ready"); 113 | } 114 | else 115 | { 116 | SetStatus("Error> Invalid arguments:" + args[1]); 117 | } 118 | } 119 | 120 | UpdateRecentProjectsList(); 121 | 122 | // preselect grid 123 | gridRecent.Select(); 124 | 125 | // get previous version build info string 126 | // this string is release tag for latest release when this app was compiled 127 | using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("UnityLauncher." + "PreviousVersion.txt")) 128 | using (StreamReader reader = new StreamReader(stream)) 129 | { 130 | previousGitRelease = reader.ReadToEnd().Trim(); 131 | } 132 | } 133 | 134 | void LoadSettings() 135 | { 136 | // form size 137 | this.Width = Properties.Settings.Default.formWidth; 138 | this.Height = Properties.Settings.Default.formHeight; 139 | 140 | // update settings window 141 | chkMinimizeToTaskbar.Checked = Properties.Settings.Default.minimizeToTaskbar; 142 | chkQuitAfterCommandline.Checked = Properties.Settings.Default.closeAfterExplorer; 143 | ChkQuitAfterOpen.Checked = Properties.Settings.Default.closeAfterProject; 144 | chkShowLauncherArgumentsColumn.Checked = Properties.Settings.Default.showArgumentsColumn; 145 | chkShowGitBranchColumn.Checked = Properties.Settings.Default.showGitBranchColumn; 146 | chkDarkSkin.Checked = Properties.Settings.Default.useDarkSkin; 147 | 148 | // update optional grid columns, hidden or visible 149 | gridRecent.Columns["_launchArguments"].Visible = chkShowLauncherArgumentsColumn.Checked; 150 | gridRecent.Columns["_gitBranch"].Visible = chkShowGitBranchColumn.Checked; 151 | 152 | // update installations folder listbox 153 | lstRootFolders.Items.Clear(); 154 | lstRootFolders.Items.AddRange(Properties.Settings.Default.rootFolders.Cast().ToArray()); 155 | // update packages folder listbox 156 | lstPackageFolders.Items.AddRange(Properties.Settings.Default.packageFolders.Cast().ToArray()); 157 | 158 | // restore data grid view widths 159 | int[] gridColumnWidths = Properties.Settings.Default.gridColumnWidths; 160 | if (gridColumnWidths != null) 161 | { 162 | 163 | for (int i = 0; i < gridColumnWidths.Length; ++i) 164 | { 165 | gridRecent.Columns[i].Width = gridColumnWidths[i]; 166 | } 167 | } 168 | 169 | // TODO assign colors for dark theme 170 | if (chkDarkSkin.Checked == true) 171 | { 172 | var darkBg = Color.FromArgb(32, 37, 41); 173 | var darkRaised = Color.FromArgb(50, 56, 61); 174 | var darkBright = Color.FromArgb(161, 180, 196); 175 | 176 | 177 | this.BackColor = darkBg; 178 | tabProjects.BackColor = darkRaised; 179 | gridRecent.BackgroundColor = darkRaised; 180 | 181 | gridRecent.GridColor = darkBg; 182 | var dgs = new DataGridViewCellStyle(); 183 | dgs.BackColor = darkRaised; 184 | dgs.ForeColor = darkBright; 185 | gridRecent.DefaultCellStyle = dgs; 186 | 187 | statusStrip1.BackColor = darkRaised; 188 | } 189 | } 190 | 191 | /// 192 | /// returns true if we have exact version installed 193 | /// 194 | /// 195 | /// 196 | bool HaveExactVersionInstalled(string version) 197 | { 198 | return string.IsNullOrEmpty(version) == false && unityList.ContainsKey(version); 199 | } 200 | 201 | 202 | void AddUnityInstallationRootFolder() 203 | { 204 | folderBrowserDialog1.Description = "Select Unity installations root folder"; 205 | var d = folderBrowserDialog1.ShowDialog(); 206 | var newRoot = folderBrowserDialog1.SelectedPath; 207 | 208 | if (String.IsNullOrWhiteSpace(newRoot) == false && Directory.Exists(newRoot) == true) 209 | { 210 | lstRootFolders.Items.Add(newRoot); 211 | Properties.Settings.Default.rootFolders.Add(newRoot); 212 | Properties.Settings.Default.Save(); 213 | } 214 | } 215 | 216 | bool ScanUnityInstallations() 217 | { 218 | SetStatus("Scanning Unity installations ..."); 219 | 220 | // dictionary to keep version and path 221 | unityList.Clear(); 222 | 223 | // installed unitys list in other tab 224 | gridUnityList.Rows.Clear(); 225 | 226 | // iterate all root folders 227 | foreach (string root in lstRootFolders.Items) 228 | { 229 | if (String.IsNullOrWhiteSpace(root) == false && Directory.Exists(root) == true) 230 | { 231 | // parse all folders here, and search for unity editor files 232 | var directories = Directory.GetDirectories(root); 233 | for (int i = 0, length = directories.Length; i < length; i++) 234 | { 235 | var uninstallExe = Path.Combine(directories[i], "Editor", "Uninstall.exe"); 236 | if (File.Exists(uninstallExe) == true) 237 | { 238 | var unityExe = Path.Combine(directories[i], "Editor", "Unity.exe"); 239 | if (File.Exists(unityExe) == true) 240 | { 241 | // get full version number from uninstaller 242 | var unityVersion = Tools.GetFileVersionData(uninstallExe).Replace("Unity", "").Trim(); 243 | if (unityList.ContainsKey(unityVersion) == false) 244 | { 245 | unityList.Add(unityVersion, unityExe); 246 | var dataFolder = Path.Combine(directories[i], "Editor", "Data"); 247 | DateTime? installDate = Tools.GetLastModifiedTime(dataFolder); 248 | // TODO add platforms: PC|iOS|tvOS|Android|UWP|WebGL|Facebook|XBox|PSVita|PS4 249 | gridUnityList.Rows.Add(unityVersion, unityExe, installDate); 250 | } 251 | } // have unity.exe 252 | } // have uninstaller.exe 253 | else // no uninstaller, probably preview builds 254 | { 255 | var unityExe = Path.Combine(directories[i], "Editor", "Unity.exe"); 256 | if (File.Exists(unityExe) == true) 257 | { 258 | // get full version number from uninstaller 259 | var unityVersion = Tools.GetFileVersionData(unityExe).Replace("Unity", "").Trim(); 260 | if (unityList.ContainsKey(unityVersion) == false) 261 | { 262 | unityList.Add(unityVersion, unityExe); 263 | var dataFolder = Path.Combine(directories[i], "Editor", "Data"); 264 | DateTime? installDate = Tools.GetLastModifiedTime(dataFolder); 265 | // TODO add platforms: PC|iOS|tvOS|Android|UWP|WebGL|Facebook|XBox|PSVita|PS4 266 | gridUnityList.Rows.Add(unityVersion, unityExe, installDate); 267 | } 268 | } // have unity.exe 269 | } 270 | } // got folders 271 | } // failed check 272 | } // all root folders 273 | 274 | lbl_unityCount.Text = "Found " + unityList.Count.ToString() + " versions"; 275 | 276 | SetStatus("Finished scanning"); 277 | 278 | // found any Unity installations? 279 | return unityList.Count > 0; 280 | } 281 | 282 | 283 | void FilterRecentProject(object sender, EventArgs e) 284 | { 285 | SetStatus("Filtering recent projects list ..."); 286 | string searchString = tbSearchBar.Text; 287 | 288 | foreach (DataGridViewRow row in gridRecent.Rows) 289 | { 290 | if (row.Cells["_project"].Value.ToString().IndexOf(searchString, StringComparison.OrdinalIgnoreCase) > -1) 291 | { 292 | row.Visible = true; 293 | } 294 | else 295 | { 296 | row.Visible = false; 297 | } 298 | } 299 | 300 | lblClearSearchField.Visible = tbSearchBar.Text.Length > 0; 301 | 302 | } 303 | 304 | void FilterUnityUpdates(object sender, EventArgs e) 305 | { 306 | SetStatus("Filtering Unity updates list ..."); 307 | string searchString = tbSearchUpdates.Text; 308 | foreach (DataGridViewRow row in gridUnityUpdates.Rows) 309 | { 310 | if (row.Cells["_UnityUpdateVersion"].Value.ToString().IndexOf(searchString, StringComparison.OrdinalIgnoreCase) > -1) 311 | { 312 | row.Visible = true; 313 | } 314 | else 315 | { 316 | row.Visible = false; 317 | } 318 | } 319 | } 320 | 321 | /// 322 | /// scans registry for recent projects and adds to project grid list 323 | /// 324 | void UpdateRecentProjectsList() 325 | { 326 | SetStatus("Updating recent projects list ..."); 327 | 328 | gridRecent.Rows.Clear(); 329 | 330 | var hklm = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64); 331 | string[] registryPathsToCheck = new string[] { @"SOFTWARE\Unity Technologies\Unity Editor 5.x", @"SOFTWARE\Unity Technologies\Unity Editor 4.x" }; 332 | 333 | // check each version path 334 | for (int i = 0, len = registryPathsToCheck.Length; i < len; i++) 335 | { 336 | RegistryKey key = hklm.OpenSubKey(registryPathsToCheck[i]); 337 | 338 | if (key == null) 339 | { 340 | continue; 341 | } 342 | else 343 | { 344 | //Console.WriteLine("Null registry key at " + registryPathsToCheck[i]); 345 | } 346 | 347 | // parse recent project path 348 | foreach (var valueName in key.GetValueNames()) 349 | { 350 | if (valueName.IndexOf("RecentlyUsedProjectPaths-") == 0) 351 | { 352 | string projectPath = ""; 353 | // check if binary or not 354 | var valueKind = key.GetValueKind(valueName); 355 | if (valueKind == RegistryValueKind.Binary) 356 | { 357 | byte[] projectPathBytes = (byte[])key.GetValue(valueName); 358 | projectPath = Encoding.UTF8.GetString(projectPathBytes, 0, projectPathBytes.Length - 1); 359 | } 360 | else // should be string then 361 | { 362 | projectPath = (string)key.GetValue(valueName); 363 | } 364 | 365 | // first check if whole folder exists, if not, skip 366 | if (Directory.Exists(projectPath) == false) 367 | { 368 | //Console.WriteLine("Recent project directory not found, skipping: " + projectPath); 369 | continue; 370 | } 371 | 372 | string projectName = ""; 373 | 374 | // get project name from full path 375 | if (projectPath.IndexOf(Path.DirectorySeparatorChar) > -1) 376 | { 377 | projectName = projectPath.Substring(projectPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); 378 | } 379 | else if (projectPath.IndexOf(Path.AltDirectorySeparatorChar) > -1) 380 | { 381 | projectName = projectPath.Substring(projectPath.LastIndexOf(Path.AltDirectorySeparatorChar) + 1); 382 | } 383 | else // no path separator found 384 | { 385 | projectName = projectPath; 386 | } 387 | 388 | string csprojFile = Path.Combine(projectPath, projectName + ".csproj"); 389 | 390 | // solution only 391 | if (File.Exists(csprojFile) == false) 392 | { 393 | csprojFile = Path.Combine(projectPath, projectName + ".sln"); 394 | } 395 | 396 | // editor only project 397 | if (File.Exists(csprojFile) == false) 398 | { 399 | csprojFile = Path.Combine(projectPath, projectName + ".Editor.csproj"); 400 | } 401 | 402 | // maybe 4.x project 403 | if (File.Exists(csprojFile) == false) 404 | { 405 | csprojFile = Path.Combine(projectPath, "Assembly-CSharp.csproj"); 406 | } 407 | 408 | // get last modified date 409 | DateTime? lastUpdated = Tools.GetLastModifiedTime(csprojFile); 410 | 411 | // get project version 412 | string projectVersion = Tools.GetProjectVersion(projectPath); 413 | 414 | // get custom launch arguments, only if column in enabled 415 | string customArgs = ""; 416 | if (chkShowLauncherArgumentsColumn.Checked == true) 417 | { 418 | customArgs = Tools.ReadCustomLaunchArguments(projectPath, launcherArgumentsFile); 419 | } 420 | 421 | // get git branchinfo, only if column in enabled 422 | string gitBranch = ""; 423 | if (chkShowGitBranchColumn.Checked == true) 424 | { 425 | gitBranch = Tools.ReadGitBranchInfo(projectPath); 426 | } 427 | 428 | gridRecent.Rows.Add(projectName, projectVersion, projectPath, lastUpdated, customArgs, gitBranch); 429 | gridRecent.Rows[gridRecent.Rows.Count - 1].Cells[1].Style.ForeColor = HaveExactVersionInstalled(projectVersion) ? Color.Green : Color.Red; 430 | } 431 | } 432 | } 433 | //SetStatus("Ready"); 434 | } 435 | 436 | void LaunchProject(string projectPath, string version, bool openProject = true, string commandLineArguments = "") 437 | { 438 | if (Directory.Exists(projectPath) == true) 439 | { 440 | // no assets path, probably we want to create new project then 441 | var assetsFolder = Path.Combine(projectPath, "Assets"); 442 | if (Directory.Exists(assetsFolder) == false) 443 | { 444 | // TODO could ask if want to create project.. 445 | Directory.CreateDirectory(assetsFolder); 446 | } 447 | 448 | // when opening project, check for crashed backup scene first 449 | if (openProject == true) 450 | { 451 | var cancelLaunch = CheckCrashBackupScene(projectPath); 452 | if (cancelLaunch == true) 453 | { 454 | return; 455 | } 456 | } 457 | 458 | if (HaveExactVersionInstalled(version) == true) 459 | { 460 | if (openProject == true) 461 | { 462 | SetStatus("Launching project in Unity " + version); 463 | } 464 | else 465 | { 466 | SetStatus("Launching Unity " + version); 467 | } 468 | 469 | try 470 | { 471 | Process myProcess = new Process(); 472 | var cmd = "\"" + unityList[version] + "\""; 473 | myProcess.StartInfo.FileName = cmd; 474 | if (openProject == true) 475 | { 476 | var pars = " -projectPath " + "\"" + projectPath + "\""; 477 | 478 | // check for custom launch parameters and append them 479 | string customArguments = GetSelectedRowData("_launchArguments"); 480 | if (string.IsNullOrEmpty(customArguments) == false) 481 | { 482 | pars += " " + customArguments; 483 | } 484 | 485 | myProcess.StartInfo.Arguments = pars + commandLineArguments; 486 | } 487 | myProcess.Start(); 488 | 489 | if (Properties.Settings.Default.closeAfterProject) 490 | { 491 | Environment.Exit(0); 492 | } 493 | } 494 | catch (Exception ex) 495 | { 496 | Console.WriteLine(ex); 497 | } 498 | } 499 | else // we dont have this version installed (or no version info available) 500 | { 501 | SetStatus("Missing Unity version: " + version); 502 | // if only running only, stop here 503 | if (openProject == true) DisplayUpgradeDialog(version, projectPath); 504 | } 505 | } 506 | else // given path doesnt exists, strange 507 | { 508 | SetStatus("Invalid path: " + projectPath); 509 | } 510 | } 511 | 512 | bool CheckCrashBackupScene(string projectPath) 513 | { 514 | var cancelRunningUnity = false; 515 | var recoveryFile = Path.Combine(projectPath, "Temp", "__Backupscenes", "0.backup"); 516 | if (File.Exists(recoveryFile)) 517 | { 518 | DialogResult dialogResult = MessageBox.Show("Crash recovery scene found, do you want to copy it into Assets/_Recovery/-folder?", "UnityLauncher - Scene Recovery", MessageBoxButtons.YesNoCancel); 519 | if (dialogResult == DialogResult.Yes) // restore 520 | { 521 | var restoreFolder = Path.Combine(projectPath, "Assets", "_Recovery"); 522 | if (Directory.Exists(restoreFolder) == false) 523 | { 524 | Directory.CreateDirectory(restoreFolder); 525 | } 526 | if (Directory.Exists(restoreFolder) == true) 527 | { 528 | Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 529 | var uniqueFileName = "Recovered_Scene" + unixTimestamp + ".unity"; 530 | File.Copy(recoveryFile, Path.Combine(restoreFolder, uniqueFileName)); 531 | SetStatus("Recovered crashed scene into: " + restoreFolder); 532 | } 533 | else 534 | { 535 | SetStatus("Error: Failed to create restore folder: " + restoreFolder); 536 | cancelRunningUnity = true; 537 | } 538 | } 539 | else if (dialogResult == DialogResult.Cancel) // dont do restore, but run Unity 540 | { 541 | cancelRunningUnity = true; 542 | } 543 | } 544 | return cancelRunningUnity; 545 | } 546 | 547 | // parse Unity installer exe from release page 548 | // thanks to https://github.com/softfruit 549 | string ParseDownloadURLFromWebpage(string version) 550 | { 551 | string url = ""; 552 | 553 | using (WebClient client = new WebClient()) 554 | { 555 | // get correct page url 556 | string website = "https://unity3d.com/get-unity/download/archive"; 557 | if (Tools.VersionIsPatch(version)) website = "https://unity3d.com/unity/qa/patch-releases"; 558 | if (Tools.VersionIsBeta(version)) website = "https://unity3d.com/unity/beta/" + version; 559 | if (Tools.VersionIsAlpha(version)) website = "https://unity3d.com/unity/alpha/" + version; 560 | 561 | // download html 562 | string sourceHTML = client.DownloadString(website); 563 | string[] lines = sourceHTML.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); 564 | 565 | // patch version download assistant finder 566 | if (Tools.VersionIsPatch(version)) 567 | { 568 | for (int i = 0; i < lines.Length; i++) 569 | { 570 | if (lines[i].Contains("UnityDownloadAssistant-" + version + ".exe")) 571 | { 572 | int start = lines[i].IndexOf('"') + 1; 573 | int end = lines[i].IndexOf('"', start); 574 | url = lines[i].Substring(start, end - start); 575 | break; 576 | } 577 | } 578 | } 579 | else if (Tools.VersionIsArchived(version)) 580 | { 581 | // archived version download assistant finder 582 | for (int i = 0; i < lines.Length; i++) 583 | { 584 | // find line where full installer is (from archive page) 585 | if (lines[i].Contains("UnitySetup64-" + version)) 586 | { 587 | // take previous line, which contains download assistant url 588 | string line = lines[i - 1]; 589 | int start = line.IndexOf('"') + 1; 590 | int end = line.IndexOf('"', start); 591 | url = @"https://unity3d.com" + line.Substring(start, end - start); 592 | break; 593 | } 594 | } 595 | } 596 | else // alpha or beta version download assistant finder 597 | { 598 | for (int i = 0; i < lines.Length; i++) 599 | { 600 | if (lines[i].Contains("UnityDownloadAssistant.exe")) 601 | { 602 | int start = lines[i].IndexOf('"') + 1; 603 | int end = lines[i].IndexOf('"', start); 604 | url = lines[i].Substring(start, end - start) + "#version=" + version; 605 | break; 606 | } 607 | } 608 | } 609 | } 610 | 611 | // didnt find installer 612 | if (string.IsNullOrEmpty(url)) 613 | { 614 | SetStatus("Cannot find UnityDownloadAssistant.exe for this version."); 615 | } 616 | 617 | return url; 618 | } 619 | 620 | /// 621 | /// launches browser to download installer 622 | /// 623 | /// full url to installer 624 | void DownloadInBrowser(string url, string version) 625 | { 626 | string exeURL = ParseDownloadURLFromWebpage(version); 627 | 628 | if (string.IsNullOrEmpty(exeURL) == false) 629 | { 630 | SetStatus("Download installer in browser: " + exeURL); 631 | Process.Start(exeURL); 632 | } 633 | else // not found 634 | { 635 | SetStatus("Error> Cannot find installer executable ... opening website instead"); 636 | url = "https://unity3d.com/get-unity/download/archive"; 637 | Process.Start(url + "#installer-not-found---version-" + version); 638 | } 639 | } 640 | 641 | /// 642 | /// get rootfolder from settings, default is c:\program files\ 643 | /// 644 | /// 645 | string[] GetUnityInstallationsRootFolder() 646 | { 647 | string[] rootFolders = null; 648 | try 649 | { 650 | // if settings exists, use that value 651 | rootFolders = new string[Properties.Settings.Default.rootFolders.Count]; 652 | Properties.Settings.Default.rootFolders.CopyTo(rootFolders, 0); 653 | } 654 | catch (Exception e) 655 | { 656 | MessageBox.Show("Rare error while checking Unity installation folder settings: " + e.Message, "UnityLauncher", MessageBoxButtons.OK); 657 | 658 | // this doesnt work? 659 | Properties.Settings.Default.Reset(); 660 | Properties.Settings.Default.Save(); 661 | } 662 | return rootFolders; 663 | } 664 | 665 | void SetStatus(string msg) 666 | { 667 | toolStripStatusLabel1.Text = msg; 668 | this.Refresh(); 669 | } 670 | 671 | private void ShowForm() 672 | { 673 | this.WindowState = FormWindowState.Minimized; 674 | this.Show(); 675 | this.WindowState = FormWindowState.Normal; 676 | notifyIcon.Visible = false; 677 | } 678 | 679 | void LaunchSelectedProject(bool openProject = true) 680 | { 681 | FixSelectedRow(); 682 | var selected = gridRecent?.CurrentCell?.RowIndex; 683 | 684 | if (selected.HasValue && selected > -1) 685 | { 686 | var projectPath = gridRecent.Rows[(int)selected].Cells["_path"].Value.ToString(); 687 | var version = Tools.GetProjectVersion(projectPath); 688 | Console.WriteLine("version: '" + version + "'"); 689 | LaunchProject(projectPath, version, openProject); 690 | //SetStatus("Ready"); 691 | } 692 | } 693 | 694 | void LaunchSelectedUnity() 695 | { 696 | 697 | var selected = gridUnityList?.CurrentCell?.RowIndex; 698 | if (selected.HasValue && selected > -1) 699 | { 700 | var version = gridUnityList.Rows[(int)selected].Cells["_unityVersion"].Value.ToString(); 701 | SetStatus("Launching Unity: " + version); 702 | try 703 | { 704 | Process myProcess = new Process(); 705 | var cmd = "\"" + unityList[version] + "\""; 706 | myProcess.StartInfo.FileName = cmd; 707 | myProcess.Start(); 708 | } 709 | catch (Exception ex) 710 | { 711 | Console.WriteLine(ex); 712 | } 713 | //SetStatus("Ready"); 714 | } 715 | } 716 | 717 | void AddPackageFolder() 718 | { 719 | folderBrowserDialog1.Description = "Select package folder"; 720 | var d = folderBrowserDialog1.ShowDialog(); 721 | var newPackageFolder = folderBrowserDialog1.SelectedPath; 722 | 723 | if (String.IsNullOrWhiteSpace(newPackageFolder) == false && Directory.Exists(newPackageFolder) == true) 724 | { 725 | lstPackageFolders.Items.Add(newPackageFolder); 726 | Properties.Settings.Default.packageFolders.Add(newPackageFolder); 727 | Properties.Settings.Default.Save(); 728 | } 729 | } 730 | 731 | 732 | #region Buttons and UI events 733 | 734 | private void btnRemoveRegister_Click(object sender, EventArgs e) 735 | { 736 | Tools.RemoveContextMenuRegistry(contextRegRoot); 737 | } 738 | 739 | private void chkMinimizeToTaskbar_CheckedChanged(object sender, EventArgs e) 740 | { 741 | Properties.Settings.Default.minimizeToTaskbar = chkMinimizeToTaskbar.Checked; 742 | Properties.Settings.Default.Save(); 743 | } 744 | 745 | 746 | 747 | private void btnAddPackageFolder_Click(object sender, EventArgs e) 748 | { 749 | AddPackageFolder(); 750 | } 751 | 752 | private void btnRemovePackFolder_Click(object sender, EventArgs e) 753 | { 754 | if (lstPackageFolders.SelectedIndex > -1) 755 | { 756 | lstPackageFolders.Items.RemoveAt(lstPackageFolders.SelectedIndex); 757 | } 758 | } 759 | 760 | private void btnOpenReleasePage_Click(object sender, EventArgs e) 761 | { 762 | var selected = gridUnityList?.CurrentCell?.RowIndex; 763 | if (selected.HasValue && selected > -1) 764 | { 765 | var version = gridUnityList.Rows[(int)selected].Cells["_unityVersion"].Value.ToString(); 766 | if (Tools.OpenReleaseNotes(version) == true) 767 | { 768 | SetStatus("Opening release notes for version " + version); 769 | } 770 | else 771 | { 772 | SetStatus("Failed opening Release Notes URL for version " + version); 773 | } 774 | } 775 | } 776 | 777 | private void btnLaunchUnity_Click(object sender, EventArgs e) 778 | { 779 | LaunchSelectedUnity(); 780 | } 781 | 782 | private void btnExploreUnity_Click(object sender, EventArgs e) 783 | { 784 | 785 | var selected = gridUnityList?.CurrentCell?.RowIndex; 786 | if (selected.HasValue && selected > -1) 787 | { 788 | var unityPath = Path.GetDirectoryName(gridUnityList.Rows[(int)selected].Cells["_unityPath"].Value.ToString()); 789 | if (Tools.LaunchExplorer(unityPath) == false) 790 | { 791 | SetStatus("Error> Directory not found: " + unityPath); 792 | } 793 | } 794 | } 795 | 796 | private void btnAddUnityFolder_Click(object sender, EventArgs e) 797 | { 798 | AddUnityInstallationRootFolder(); 799 | ScanUnityInstallations(); 800 | UpdateRecentProjectsList(); 801 | } 802 | 803 | private void btnRemoveInstallFolder_Click(object sender, EventArgs e) 804 | { 805 | if (lstRootFolders.SelectedIndex > -1) 806 | { 807 | Properties.Settings.Default.rootFolders.Remove(lstRootFolders.Items[lstRootFolders.SelectedIndex].ToString()); 808 | Properties.Settings.Default.Save(); 809 | lstRootFolders.Items.RemoveAt(lstRootFolders.SelectedIndex); 810 | ScanUnityInstallations(); 811 | } 812 | } 813 | 814 | private void btnFetchUnityVersions_Click(object sender, EventArgs e) 815 | { 816 | FetchListOfUnityUpdates(); 817 | } 818 | 819 | int lastKnownSelectedRow = -1; 820 | private void unityGridView_KeyDown(object sender, KeyEventArgs e) 821 | { 822 | switch (e.KeyCode) 823 | { 824 | case Keys.Return: // launch selected Unity 825 | e.SuppressKeyPress = true; 826 | LaunchSelectedUnity(); 827 | break; 828 | case Keys.F5: // refresh installed Unity versions list 829 | ScanUnityInstallations(); 830 | UpdateRecentProjectsList(); 831 | break; 832 | default: 833 | break; 834 | } 835 | } 836 | 837 | /// 838 | /// global keys 839 | /// 840 | /// 841 | /// 842 | private void Form1_KeyPress(object sender, KeyPressEventArgs e) 843 | { 844 | // if editing cells, dont focus on search 845 | if (gridRecent.IsCurrentCellInEditMode == true) return; 846 | 847 | switch ((int)e.KeyChar) 848 | { 849 | case 27: // ESCAPE - clear search 850 | if (tabControl1.SelectedIndex == 0 && tbSearchBar.Text != "") 851 | { 852 | tbSearchBar.Text = ""; 853 | lblClearSearchField.Visible = false; 854 | } 855 | else if (tabControl1.SelectedIndex == 3 && tbSearchUpdates.Text != "") 856 | { 857 | tbSearchUpdates.Text = ""; 858 | } 859 | break; 860 | default: // any key 861 | // activate searchbar if not active and we are in tab#1 862 | if (tabControl1.SelectedIndex == 0 && tbSearchBar.Focused == false) 863 | { 864 | // skip tab key on search field 865 | if ((int)e.KeyChar == 9) 866 | { 867 | break; 868 | } 869 | tbSearchBar.Focus(); 870 | tbSearchBar.Text += e.KeyChar; 871 | tbSearchBar.Select(tbSearchBar.Text.Length, 0); 872 | lblClearSearchField.Visible = tbSearchBar.Text.Length > 0; 873 | } 874 | break; 875 | } 876 | } 877 | 878 | /// 879 | /// grid keys 880 | /// 881 | /// 882 | /// 883 | private void gridRecent_KeyDown(object sender, KeyEventArgs e) 884 | { 885 | // if editing cells, dont search or launch 886 | if (gridRecent.IsCurrentCellInEditMode == true) return; 887 | 888 | switch (e.KeyCode) 889 | { 890 | case Keys.Return: // launch selected project 891 | e.SuppressKeyPress = true; 892 | LaunchSelectedProject(); 893 | break; 894 | case Keys.F5: // refresh recent projects list 895 | lastKnownSelectedRow = GetSelectedRowIndex(); 896 | Console.WriteLine(lastKnownSelectedRow); 897 | UpdateRecentProjectsList(); 898 | SetSelectedRowIndex(lastKnownSelectedRow); 899 | break; 900 | default: 901 | break; 902 | } 903 | } 904 | 905 | //Checks if you are doubleclicking the current cell 906 | private void GridRecent_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) 907 | { 908 | if (e.Button == MouseButtons.Left && e.RowIndex == gridRecent.CurrentCell.RowIndex) 909 | { 910 | LaunchSelectedProject(); 911 | } 912 | } 913 | 914 | // set basefolder of all Unity installations 915 | private void btn_setinstallfolder_Click(object sender, EventArgs e) 916 | { 917 | AddUnityInstallationRootFolder(); 918 | ScanUnityInstallations(); 919 | UpdateRecentProjectsList(); 920 | } 921 | 922 | private void btnLaunch_Click(object sender, EventArgs e) 923 | { 924 | LaunchSelectedProject(); 925 | } 926 | 927 | private void Form1_Resize(object sender, EventArgs e) 928 | { 929 | if (chkMinimizeToTaskbar.Checked == true) 930 | { 931 | if (FormWindowState.Minimized == this.WindowState) 932 | { 933 | notifyIcon.Visible = true; 934 | this.Hide(); 935 | } 936 | else if (FormWindowState.Normal == this.WindowState) 937 | { 938 | notifyIcon.Visible = false; 939 | } 940 | } 941 | } 942 | 943 | private void btnRefresh_Click(object sender, EventArgs e) 944 | { 945 | ScanUnityInstallations(); 946 | UpdateRecentProjectsList(); 947 | } 948 | 949 | private void notifyIcon_MouseClick(object sender, MouseEventArgs e) 950 | { 951 | ShowForm(); 952 | } 953 | 954 | private void btn_openFolder_Click(object sender, EventArgs e) 955 | { 956 | FixSelectedRow(); 957 | var selected = gridRecent?.CurrentCell?.RowIndex; 958 | if (selected.HasValue && selected > -1) 959 | { 960 | string folder = gridRecent.Rows[(int)selected].Cells["_path"].Value.ToString(); 961 | if (Tools.LaunchExplorer(folder) == false) 962 | { 963 | SetStatus("Error> Directory not found: " + folder); 964 | } 965 | } 966 | } 967 | 968 | private void btnExplorePackageFolder_Click(object sender, EventArgs e) 969 | { 970 | var selected = lstPackageFolders.SelectedIndex; 971 | //Console.WriteLine(lstPackageFolders.Items[selected].ToString()); 972 | if (selected > -1) 973 | { 974 | string folder = lstPackageFolders.Items[selected].ToString(); 975 | if (Tools.LaunchExplorer(folder) == false) 976 | { 977 | SetStatus("Error> Directory not found: " + folder); 978 | } 979 | } 980 | } 981 | 982 | private void btnAddAssetStoreFolder_Click(object sender, EventArgs e) 983 | { 984 | var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Unity", "Asset Store-5.x"); 985 | if (Directory.Exists(path) == true) 986 | { 987 | if (lstPackageFolders.Items.Contains(path) == false) 988 | { 989 | lstPackageFolders.Items.Add(path); 990 | Properties.Settings.Default.packageFolders.Add(path); 991 | Properties.Settings.Default.Save(); 992 | } 993 | } 994 | } 995 | 996 | private void btnAddRegister_Click(object sender, EventArgs e) 997 | { 998 | Tools.AddContextMenuRegistry(contextRegRoot); 999 | } 1000 | 1001 | private void ChkQuitAfterOpen_CheckedChanged(object sender, EventArgs e) 1002 | { 1003 | Properties.Settings.Default.closeAfterProject = ChkQuitAfterOpen.Checked; 1004 | Properties.Settings.Default.Save(); 1005 | } 1006 | 1007 | private void chkQuitAfterCommandline_CheckedChanged(object sender, EventArgs e) 1008 | { 1009 | Properties.Settings.Default.closeAfterExplorer = chkQuitAfterCommandline.Checked; 1010 | Properties.Settings.Default.Save(); 1011 | } 1012 | 1013 | private void chkDarkSkin_CheckedChanged(object sender, EventArgs e) 1014 | { 1015 | Properties.Settings.Default.useDarkSkin = chkDarkSkin.Checked; 1016 | Properties.Settings.Default.Save(); 1017 | } 1018 | 1019 | private void btnRunUnityOnly_Click(object sender, EventArgs e) 1020 | { 1021 | LaunchSelectedProject(openProject: false); 1022 | } 1023 | 1024 | private void btnUpgradeProject_Click(object sender, EventArgs e) 1025 | { 1026 | UpgradeProject(); 1027 | } 1028 | 1029 | private void btnOpenLogFolder_Click(object sender, EventArgs e) 1030 | { 1031 | var logfolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Unity", "Editor"); 1032 | if (Directory.Exists(logfolder) == true) 1033 | { 1034 | if (Tools.LaunchExplorer(logfolder) == false) 1035 | { 1036 | SetStatus("Error> Directory not found: " + logfolder); 1037 | } 1038 | } 1039 | } 1040 | 1041 | private void btnOpenUpdateWebsite_Click(object sender, EventArgs e) 1042 | { 1043 | FixSelectedRow(); 1044 | var selected = gridUnityUpdates?.CurrentCell?.RowIndex; 1045 | if (selected.HasValue && selected > -1) 1046 | { 1047 | var version = gridUnityUpdates.Rows[(int)selected].Cells["_UnityUpdateVersion"].Value.ToString(); 1048 | Tools.OpenReleaseNotes(version); 1049 | } 1050 | } 1051 | 1052 | private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) 1053 | { 1054 | // if enter Updates tab, then automatically fetch list of Unity versions if list is empty (not fetched) 1055 | if (((TabControl)sender).SelectedIndex == 3) // FIXME: fixed index 3 for this tab.. 1056 | { 1057 | if (gridUnityUpdates.Rows.Count == 0) 1058 | { 1059 | FetchListOfUnityUpdates(); 1060 | } 1061 | } 1062 | } 1063 | 1064 | private void Form1_ResizeEnd(object sender, EventArgs e) 1065 | { 1066 | var form = (Form)sender; 1067 | Properties.Settings.Default.formWidth = form.Size.Width; 1068 | Properties.Settings.Default.formHeight = form.Size.Height; 1069 | Properties.Settings.Default.Save(); 1070 | } 1071 | 1072 | private void checkShowLauncherArgumentsColumn_CheckedChanged(object sender, EventArgs e) 1073 | { 1074 | Properties.Settings.Default.showArgumentsColumn = chkShowLauncherArgumentsColumn.Checked; 1075 | Properties.Settings.Default.Save(); 1076 | gridRecent.Columns["_launchArguments"].Visible = chkShowLauncherArgumentsColumn.Checked; 1077 | // reload list data, if enabled (otherwise missing data) 1078 | if (chkShowLauncherArgumentsColumn.Checked == true) UpdateRecentProjectsList(); 1079 | } 1080 | 1081 | private void checkShowGitBranchColumn_CheckedChanged(object sender, EventArgs e) 1082 | { 1083 | Properties.Settings.Default.showGitBranchColumn = chkShowGitBranchColumn.Checked; 1084 | Properties.Settings.Default.Save(); 1085 | gridRecent.Columns["_gitBranch"].Visible = chkShowGitBranchColumn.Checked; 1086 | // reload list data, if enabled (otherwise missing data) 1087 | if (chkShowGitBranchColumn.Checked == true) UpdateRecentProjectsList(); 1088 | } 1089 | 1090 | 1091 | private void linkArgumentsDocs_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 1092 | { 1093 | Tools.OpenURL("https://docs.unity3d.com/Manual/CommandLineArguments.html"); 1094 | } 1095 | 1096 | private void linkProjectGithub_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 1097 | { 1098 | Tools.OpenURL("https://github.com/unitycoder/UnityLauncher/releases"); 1099 | } 1100 | 1101 | 1102 | // after editing launch arguments cell 1103 | private void gridRecent_CellEndEdit(object sender, DataGridViewCellEventArgs e) 1104 | { 1105 | string path = GetSelectedRowData("_path"); 1106 | if (string.IsNullOrEmpty(path)) return; 1107 | 1108 | string arguments = GetSelectedRowData("_launchArguments"); 1109 | 1110 | // check folder first 1111 | string outputFolder = Path.Combine(path, "ProjectSettings"); 1112 | if (Directory.Exists(outputFolder) == false) 1113 | { 1114 | Directory.CreateDirectory(outputFolder); 1115 | } 1116 | 1117 | // save arguments to projectsettings folder 1118 | string outputFile = Path.Combine(path, "ProjectSettings", launcherArgumentsFile); 1119 | 1120 | try 1121 | { 1122 | StreamWriter sw = new StreamWriter(outputFile); 1123 | sw.WriteLine(arguments); 1124 | sw.Close(); 1125 | } 1126 | catch (Exception exception) 1127 | { 1128 | SetStatus("File error: " + exception.Message); 1129 | } 1130 | 1131 | // select the same row again (dont move to next), doesnt work here 1132 | // var previousRow = gridRecent.CurrentCell.RowIndex; 1133 | // gridRecent.Rows[previousRow].Selected = true; 1134 | } 1135 | 1136 | private void btnCheckUpdates_Click(object sender, EventArgs e) 1137 | { 1138 | Tools.OpenURL("https://github.com/unitycoder/UnityLauncher/releases"); 1139 | } 1140 | 1141 | private void btnRefreshProjectList_Click(object sender, EventArgs e) 1142 | { 1143 | UpdateRecentProjectsList(); 1144 | } 1145 | 1146 | private void btnBrowseForProject_Click(object sender, EventArgs e) 1147 | { 1148 | BrowseForExistingProjectFolder(); 1149 | } 1150 | 1151 | private void Form1_FormClosing(object sender, FormClosingEventArgs e) 1152 | { 1153 | SaveSettingsOnExit(); 1154 | } 1155 | 1156 | #endregion UI events 1157 | 1158 | 1159 | 1160 | 1161 | // displays version selector to upgrade project 1162 | void UpgradeProject() 1163 | { 1164 | FixSelectedRow(); 1165 | var selected = gridRecent?.CurrentCell?.RowIndex; 1166 | if (selected.HasValue && selected > -1) 1167 | { 1168 | SetStatus("Upgrading project ..."); 1169 | 1170 | var projectPath = gridRecent.Rows[(int)selected].Cells["_path"].Value.ToString(); 1171 | var currentVersion = Tools.GetProjectVersion(projectPath); 1172 | 1173 | if (string.IsNullOrEmpty(currentVersion) == true) 1174 | { 1175 | // TODO no version info available, should handle errors? 1176 | } 1177 | else // have version info 1178 | { 1179 | bool haveExactVersion = HaveExactVersionInstalled(currentVersion); 1180 | if (haveExactVersion == true) 1181 | { 1182 | // you already have exact version, are you sure about upgrade? 1183 | } 1184 | } 1185 | DisplayUpgradeDialog(currentVersion, projectPath, true); 1186 | } 1187 | } 1188 | 1189 | void DisplayUpgradeDialog(string currentVersion, string projectPath, bool launchProject = true, string commandLineArguments = "") 1190 | { 1191 | // display upgrade dialog (version selector) 1192 | Form2 upgradeDialog = new Form2(); 1193 | Form2.currentVersion = currentVersion; 1194 | 1195 | // check what user selected 1196 | var results = upgradeDialog.ShowDialog(this); 1197 | switch (results) 1198 | { 1199 | case DialogResult.Ignore: // view release notes page 1200 | Tools.OpenReleaseNotes(currentVersion); 1201 | // display window again for now.. 1202 | DisplayUpgradeDialog(currentVersion, projectPath, launchProject, commandLineArguments); 1203 | break; 1204 | case DialogResult.Cancel: // cancelled 1205 | SetStatus("Cancelled project upgrade"); 1206 | break; 1207 | case DialogResult.Retry: // download and install missing version 1208 | SetStatus("Download and install missing version " + currentVersion); 1209 | string url = Tools.GetUnityReleaseURL(currentVersion); 1210 | if (string.IsNullOrEmpty(url) == false) 1211 | { 1212 | DownloadInBrowser(url, currentVersion); 1213 | } 1214 | else 1215 | { 1216 | SetStatus("Failed getting Unity Installer URL"); 1217 | } 1218 | break; 1219 | case DialogResult.Yes: // upgrade 1220 | SetStatus("Upgrading project to " + Form2.currentVersion); 1221 | if (launchProject == true) LaunchProject(projectPath, Form2.currentVersion); 1222 | break; 1223 | default: 1224 | Console.WriteLine("Unknown DialogResult: " + results); 1225 | break; 1226 | } 1227 | upgradeDialog.Close(); 1228 | } 1229 | 1230 | private void FetchListOfUnityUpdates() 1231 | { 1232 | if (isDownloadingUnityList == true) 1233 | { 1234 | SetStatus("We are already downloading ..."); 1235 | return; 1236 | } 1237 | isDownloadingUnityList = true; 1238 | SetStatus("Downloading list of Unity versions ..."); 1239 | 1240 | // download list of Unity versions 1241 | using (WebClient webClient = new WebClient()) 1242 | { 1243 | webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(UnityVersionsListDownloaded); 1244 | var unityVersionsURL = @"http://symbolserver.unity3d.com/000Admin/history.txt"; 1245 | webClient.DownloadStringAsync(new Uri(unityVersionsURL)); 1246 | } 1247 | } 1248 | 1249 | private void UnityVersionsListDownloaded(object sender, DownloadStringCompletedEventArgs e) 1250 | { 1251 | // TODO check for error.. 1252 | SetStatus("Downloading list of Unity versions ... done"); 1253 | isDownloadingUnityList = false; 1254 | 1255 | // parse to list 1256 | var receivedList = e.Result.Split(new[] { Environment.NewLine }, StringSplitOptions.None); 1257 | Array.Reverse(receivedList); 1258 | gridUnityUpdates.Rows.Clear(); 1259 | // fill in, TODO: show only top 50 or so 1260 | for (int i = 0, len = receivedList.Length; i < len; i++) 1261 | { 1262 | var row = receivedList[i].Split(','); 1263 | var versionTemp = row[6].Trim('"'); 1264 | gridUnityUpdates.Rows.Add(row[3], versionTemp); 1265 | 1266 | // set color if we already have it installed 1267 | gridUnityUpdates.Rows[i].Cells[1].Style.ForeColor = unityList.ContainsKey(versionTemp) ? Color.Green : Color.Black; 1268 | } 1269 | } 1270 | 1271 | // returns currently selected rows path string 1272 | string GetSelectedRowData(string key) 1273 | { 1274 | string path = null; 1275 | FixSelectedRow(); 1276 | var selected = gridRecent?.CurrentCell?.RowIndex; 1277 | if (selected.HasValue && selected > -1) 1278 | { 1279 | path = gridRecent.Rows[(int)selected].Cells[key].Value?.ToString(); 1280 | } 1281 | return path; 1282 | } 1283 | 1284 | void BrowseForExistingProjectFolder() 1285 | { 1286 | folderBrowserDialog1.Description = "Select existing project folder"; 1287 | var d = folderBrowserDialog1.ShowDialog(); 1288 | var projectPath = folderBrowserDialog1.SelectedPath; 1289 | 1290 | // NOTE: if user didnt click enter or deselect-select newly created folder, this fails as it returns "new folder" instead of actual name 1291 | // https://social.msdn.microsoft.com/Forums/vstudio/en-US/cc7f1d54-c1a0-45de-9611-7f69873f32df/folderbrowserdialog-bug-when-click-ok-while-modify-new-folders-name?forum=netfxbcl 1292 | 1293 | if (String.IsNullOrWhiteSpace(projectPath) == false && Directory.Exists(projectPath) == true) 1294 | { 1295 | // TODO: remove duplicate code (from UpdateRecentList()) 1296 | string projectName = ""; 1297 | 1298 | // get project name from full path 1299 | if (projectPath.IndexOf(Path.DirectorySeparatorChar) > -1) 1300 | { 1301 | projectName = projectPath.Substring(projectPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); 1302 | } 1303 | else if (projectPath.IndexOf(Path.AltDirectorySeparatorChar) > -1) 1304 | { 1305 | projectName = projectPath.Substring(projectPath.LastIndexOf(Path.AltDirectorySeparatorChar) + 1); 1306 | } 1307 | else // no path separator found 1308 | { 1309 | projectName = projectPath; 1310 | } 1311 | 1312 | string csprojFile = Path.Combine(projectPath, projectName + ".csproj"); 1313 | 1314 | // editor only project 1315 | if (File.Exists(csprojFile) == false) 1316 | { 1317 | csprojFile = Path.Combine(projectPath, projectName + ".Editor.csproj"); 1318 | } 1319 | 1320 | // maybe 4.x project 1321 | if (File.Exists(csprojFile) == false) 1322 | { 1323 | csprojFile = Path.Combine(projectPath, "Assembly-CSharp.csproj"); 1324 | } 1325 | 1326 | // get last modified date 1327 | DateTime? lastUpdated = Tools.GetLastModifiedTime(csprojFile); 1328 | 1329 | // get project version 1330 | string projectVersion = Tools.GetProjectVersion(projectPath); 1331 | 1332 | // get custom launch arguments, only if column in enabled 1333 | string customArgs = ""; 1334 | if (chkShowLauncherArgumentsColumn.Checked == true) 1335 | { 1336 | customArgs = Tools.ReadCustomLaunchArguments(projectPath, launcherArgumentsFile); 1337 | } 1338 | 1339 | // get git branchinfo, only if column in enabled 1340 | string gitBranch = ""; 1341 | if (chkShowGitBranchColumn.Checked == true) 1342 | { 1343 | gitBranch = Tools.ReadGitBranchInfo(projectPath); 1344 | } 1345 | 1346 | // NOTE: list item will disappear if you dont open the project once.. 1347 | 1348 | // TODO: dont add if not a project?? 1349 | 1350 | gridRecent.Rows.Insert(0, projectName, projectVersion, projectPath, lastUpdated, customArgs, gitBranch); 1351 | gridRecent.Rows[0].Cells[1].Style.ForeColor = HaveExactVersionInstalled(projectVersion) ? Color.Green : Color.Red; 1352 | gridRecent.Rows[0].Selected = true; 1353 | gridRecent.CurrentCell = gridRecent[0, 0]; // reset position to first item 1354 | } 1355 | } 1356 | 1357 | private void SaveSettingsOnExit() 1358 | { 1359 | // save list column widths 1360 | List gridWidths; 1361 | if (Properties.Settings.Default.gridColumnWidths != null) 1362 | { 1363 | gridWidths = new List(Properties.Settings.Default.gridColumnWidths); 1364 | } 1365 | else 1366 | { 1367 | gridWidths = new List(); 1368 | } 1369 | 1370 | // restore data grid view widths 1371 | var colum = gridRecent.Columns[0]; 1372 | for (int i = 0; i < gridRecent.Columns.Count; ++i) 1373 | { 1374 | if (Properties.Settings.Default.gridColumnWidths != null && Properties.Settings.Default.gridColumnWidths.Length > i) 1375 | { 1376 | gridWidths[i] = gridRecent.Columns[i].Width; 1377 | } 1378 | else 1379 | { 1380 | gridWidths.Add(gridRecent.Columns[i].Width); 1381 | } 1382 | } 1383 | Properties.Settings.Default.gridColumnWidths = gridWidths.ToArray(); 1384 | Properties.Settings.Default.Save(); 1385 | } 1386 | 1387 | void FixSelectedRow() 1388 | { 1389 | if (gridRecent.CurrentCell == null) 1390 | { 1391 | if (gridRecent.SelectedRows.Count != 0) 1392 | { 1393 | DataGridViewRow row = gridRecent.SelectedRows[0]; 1394 | gridRecent.CurrentCell = row.Cells[0]; 1395 | } 1396 | } 1397 | } 1398 | 1399 | private void btnOpenLogcatCmd_Click(object sender, EventArgs e) 1400 | { 1401 | try 1402 | { 1403 | Process myProcess = new Process(); 1404 | var cmd = "cmd.exe"; 1405 | myProcess.StartInfo.FileName = cmd; 1406 | // NOTE windows 10 cmd line supports ansi colors, otherwise remove -v color 1407 | var pars = " /c adb logcat -s Unity ActivityManager PackageManager dalvikvm DEBUG -v color"; 1408 | myProcess.StartInfo.Arguments = pars; 1409 | myProcess.Start(); 1410 | } 1411 | catch (Exception ex) 1412 | { 1413 | Console.WriteLine(ex); 1414 | } 1415 | } 1416 | 1417 | int GetSelectedRowIndex() 1418 | { 1419 | var selected = gridRecent?.CurrentCell?.RowIndex; 1420 | if (selected.HasValue && selected > -1) 1421 | { 1422 | return (int)selected; 1423 | } 1424 | else 1425 | { 1426 | return -1; 1427 | } 1428 | } 1429 | 1430 | void SetSelectedRowIndex(int index) 1431 | { 1432 | if (index > -1 && index < gridRecent.Rows.Count) gridRecent.Rows[index].Selected = true; 1433 | } 1434 | 1435 | private void btnDownloadNewUnity_Click(object sender, EventArgs e) 1436 | { 1437 | FixSelectedRow(); 1438 | var selected = gridUnityUpdates?.CurrentCell?.RowIndex; 1439 | if (selected.HasValue && selected > -1) 1440 | { 1441 | var version = gridUnityUpdates.Rows[(int)selected].Cells["_UnityUpdateVersion"].Value.ToString(); 1442 | string url = Tools.GetUnityReleaseURL(version); 1443 | if (string.IsNullOrEmpty(url) == false) 1444 | { 1445 | DownloadInBrowser(url, version); 1446 | } 1447 | } 1448 | 1449 | } 1450 | 1451 | // open LocalLow folder 1452 | private void btnPlayerLogFolder_Click(object sender, EventArgs e) 1453 | { 1454 | var logfolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/../LocalLow"); 1455 | if (Directory.Exists(logfolder) == true) 1456 | { 1457 | if (Tools.LaunchExplorer(logfolder) == false) 1458 | { 1459 | SetStatus("Error> Directory not found: " + logfolder); 1460 | } 1461 | } 1462 | } 1463 | 1464 | private void lblClearSearchField_Click(object sender, EventArgs e) 1465 | { 1466 | tbSearchBar.Text = ""; 1467 | } 1468 | 1469 | private void lblClearSearchField_MouseEnter(object sender, EventArgs e) 1470 | { 1471 | ((Label)sender).ForeColor = Color.FromArgb(255, 0, 0, 0); 1472 | } 1473 | 1474 | private void lblClearSearchField_MouseLeave(object sender, EventArgs e) 1475 | { 1476 | ((Label)sender).ForeColor = Color.FromArgb(128, 128, 128, 128); 1477 | } 1478 | } // class Form 1479 | } // namespace -------------------------------------------------------------------------------- /UnityLauncher/Form2.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace UnityLauncher 2 | { 3 | partial class Form2 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.label1 = new System.Windows.Forms.Label(); 32 | this.lstUnityVersions = new System.Windows.Forms.ListBox(); 33 | this.btnCancelUpgrade = new System.Windows.Forms.Button(); 34 | this.btnConfirmUpgrade = new System.Windows.Forms.Button(); 35 | this.txtUpgradeCurrentVersion = new System.Windows.Forms.TextBox(); 36 | this.label2 = new System.Windows.Forms.Label(); 37 | this.btn_GoInstallMissingVersion = new System.Windows.Forms.Button(); 38 | this.btn_OpenMissingVersionReleasePage = new System.Windows.Forms.Button(); 39 | this.SuspendLayout(); 40 | // 41 | // label1 42 | // 43 | this.label1.AutoSize = true; 44 | this.label1.Location = new System.Drawing.Point(16, 21); 45 | this.label1.Name = "label1"; 46 | this.label1.Size = new System.Drawing.Size(118, 13); 47 | this.label1.TabIndex = 0; 48 | this.label1.Text = "Current Project Version:"; 49 | // 50 | // lstUnityVersions 51 | // 52 | this.lstUnityVersions.FormattingEnabled = true; 53 | this.lstUnityVersions.Location = new System.Drawing.Point(12, 104); 54 | this.lstUnityVersions.Name = "lstUnityVersions"; 55 | this.lstUnityVersions.Size = new System.Drawing.Size(235, 303); 56 | this.lstUnityVersions.TabIndex = 1; 57 | this.lstUnityVersions.KeyDown += new System.Windows.Forms.KeyEventHandler(this.lstUnityVersions_KeyDown); 58 | // 59 | // btnCancelUpgrade 60 | // 61 | this.btnCancelUpgrade.Location = new System.Drawing.Point(12, 413); 62 | this.btnCancelUpgrade.Name = "btnCancelUpgrade"; 63 | this.btnCancelUpgrade.Size = new System.Drawing.Size(95, 56); 64 | this.btnCancelUpgrade.TabIndex = 2; 65 | this.btnCancelUpgrade.Text = "Cancel"; 66 | this.btnCancelUpgrade.UseVisualStyleBackColor = true; 67 | this.btnCancelUpgrade.Click += new System.EventHandler(this.btnCancelUpgrade_Click); 68 | // 69 | // btnConfirmUpgrade 70 | // 71 | this.btnConfirmUpgrade.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 72 | this.btnConfirmUpgrade.Location = new System.Drawing.Point(113, 413); 73 | this.btnConfirmUpgrade.Name = "btnConfirmUpgrade"; 74 | this.btnConfirmUpgrade.Size = new System.Drawing.Size(136, 56); 75 | this.btnConfirmUpgrade.TabIndex = 3; 76 | this.btnConfirmUpgrade.Text = "Upgrade Project"; 77 | this.btnConfirmUpgrade.UseVisualStyleBackColor = true; 78 | this.btnConfirmUpgrade.Click += new System.EventHandler(this.btnConfirmUpgrade_Click); 79 | // 80 | // txtUpgradeCurrentVersion 81 | // 82 | this.txtUpgradeCurrentVersion.Enabled = false; 83 | this.txtUpgradeCurrentVersion.Location = new System.Drawing.Point(136, 18); 84 | this.txtUpgradeCurrentVersion.Name = "txtUpgradeCurrentVersion"; 85 | this.txtUpgradeCurrentVersion.Size = new System.Drawing.Size(111, 20); 86 | this.txtUpgradeCurrentVersion.TabIndex = 4; 87 | // 88 | // label2 89 | // 90 | this.label2.AutoSize = true; 91 | this.label2.Location = new System.Drawing.Point(9, 85); 92 | this.label2.Name = "label2"; 93 | this.label2.Size = new System.Drawing.Size(120, 13); 94 | this.label2.TabIndex = 5; 95 | this.label2.Text = "Available Unity Versions"; 96 | // 97 | // btn_GoInstallMissingVersion 98 | // 99 | this.btn_GoInstallMissingVersion.Location = new System.Drawing.Point(136, 44); 100 | this.btn_GoInstallMissingVersion.Name = "btn_GoInstallMissingVersion"; 101 | this.btn_GoInstallMissingVersion.Size = new System.Drawing.Size(111, 22); 102 | this.btn_GoInstallMissingVersion.TabIndex = 6; 103 | this.btn_GoInstallMissingVersion.Text = "Download"; 104 | this.btn_GoInstallMissingVersion.UseVisualStyleBackColor = true; 105 | this.btn_GoInstallMissingVersion.Click += new System.EventHandler(this.btn_GoInstallMissingVersion_Click); 106 | // 107 | // btn_OpenMissingVersionReleasePage 108 | // 109 | this.btn_OpenMissingVersionReleasePage.Location = new System.Drawing.Point(19, 44); 110 | this.btn_OpenMissingVersionReleasePage.Name = "btn_OpenMissingVersionReleasePage"; 111 | this.btn_OpenMissingVersionReleasePage.Size = new System.Drawing.Size(111, 22); 112 | this.btn_OpenMissingVersionReleasePage.TabIndex = 7; 113 | this.btn_OpenMissingVersionReleasePage.Text = "Open Release Page"; 114 | this.btn_OpenMissingVersionReleasePage.UseVisualStyleBackColor = true; 115 | this.btn_OpenMissingVersionReleasePage.Click += new System.EventHandler(this.btn_OpenMissingVersionReleasePage_Click); 116 | // 117 | // Form2 118 | // 119 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 120 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 121 | this.ClientSize = new System.Drawing.Size(259, 476); 122 | this.Controls.Add(this.btn_OpenMissingVersionReleasePage); 123 | this.Controls.Add(this.btn_GoInstallMissingVersion); 124 | this.Controls.Add(this.label2); 125 | this.Controls.Add(this.txtUpgradeCurrentVersion); 126 | this.Controls.Add(this.btnConfirmUpgrade); 127 | this.Controls.Add(this.btnCancelUpgrade); 128 | this.Controls.Add(this.lstUnityVersions); 129 | this.Controls.Add(this.label1); 130 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 131 | this.MaximizeBox = false; 132 | this.MinimizeBox = false; 133 | this.Name = "Form2"; 134 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 135 | this.Text = "Missing Exact Unity Version"; 136 | this.TopMost = true; 137 | this.Load += new System.EventHandler(this.Form2_Load); 138 | this.ResumeLayout(false); 139 | this.PerformLayout(); 140 | 141 | } 142 | 143 | #endregion 144 | 145 | private System.Windows.Forms.Label label1; 146 | private System.Windows.Forms.ListBox lstUnityVersions; 147 | private System.Windows.Forms.Button btnCancelUpgrade; 148 | private System.Windows.Forms.Button btnConfirmUpgrade; 149 | private System.Windows.Forms.TextBox txtUpgradeCurrentVersion; 150 | private System.Windows.Forms.Label label2; 151 | private System.Windows.Forms.Button btn_GoInstallMissingVersion; 152 | private System.Windows.Forms.Button btn_OpenMissingVersionReleasePage; 153 | } 154 | } -------------------------------------------------------------------------------- /UnityLauncher/Form2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using UnityLauncherTools; 11 | 12 | namespace UnityLauncher 13 | { 14 | public partial class Form2 : Form 15 | { 16 | public static string currentVersion = ""; 17 | 18 | public Form2() 19 | { 20 | InitializeComponent(); 21 | } 22 | 23 | private void Form2_Load(object sender, EventArgs e) 24 | { 25 | Start(); 26 | } 27 | 28 | void Start() 29 | { 30 | // update unity installations list 31 | lstUnityVersions.Items.AddRange(Form1.unityList.Keys.ToArray()); 32 | 33 | // show available versions, autoselect nearest one 34 | if (string.IsNullOrEmpty(currentVersion) == false) 35 | { 36 | string nearestVersion = Tools.FindNearestVersion(currentVersion, Form1.unityList.Keys.ToList()); 37 | 38 | // preselect most likely version 39 | int likelyIndex = lstUnityVersions.FindString(nearestVersion); 40 | if (likelyIndex > -1) 41 | { 42 | lstUnityVersions.SetSelected(likelyIndex, true); 43 | } 44 | else 45 | { 46 | // just select first item then 47 | lstUnityVersions.SetSelected(0, true); 48 | } 49 | 50 | // enable release and dl buttons 51 | btn_GoInstallMissingVersion.Enabled = true; 52 | btn_OpenMissingVersionReleasePage.Enabled = true; 53 | 54 | } 55 | else // we dont have current version 56 | { 57 | btn_GoInstallMissingVersion.Enabled = false; 58 | btn_OpenMissingVersionReleasePage.Enabled = false; 59 | 60 | currentVersion = "None"; 61 | // just select first item then 62 | if (lstUnityVersions != null && lstUnityVersions.Items.Count > 0) lstUnityVersions.SetSelected(0, true); 63 | } 64 | 65 | // fill textbox 66 | txtUpgradeCurrentVersion.Text = currentVersion; 67 | } 68 | 69 | #region UI Events 70 | 71 | private void btnConfirmUpgrade_Click(object sender, EventArgs e) 72 | { 73 | UpgradeToSelected(); 74 | } 75 | 76 | private void btnCancelUpgrade_Click(object sender, EventArgs e) 77 | { 78 | DialogResult = DialogResult.Cancel; 79 | } 80 | 81 | private void btn_OpenMissingVersionReleasePage_Click(object sender, EventArgs e) 82 | { 83 | DialogResult = DialogResult.Ignore; // opens release notes 84 | } 85 | 86 | private void btn_GoInstallMissingVersion_Click(object sender, EventArgs e) 87 | { 88 | DialogResult = DialogResult.Retry; // download package 89 | } 90 | 91 | #endregion 92 | 93 | private void lstUnityVersions_KeyDown(object sender, KeyEventArgs e) 94 | { 95 | if (e.KeyCode == Keys.Return) 96 | { 97 | UpgradeToSelected(); 98 | } 99 | else if (e.KeyCode == Keys.Escape) 100 | { 101 | DialogResult = DialogResult.Cancel; 102 | } 103 | } 104 | 105 | void UpgradeToSelected() 106 | { 107 | if (lstUnityVersions.SelectedIndex > -1) 108 | { 109 | currentVersion = lstUnityVersions.Items[lstUnityVersions.SelectedIndex].ToString(); 110 | DialogResult = DialogResult.Yes; 111 | } 112 | else 113 | { 114 | // no version selected 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /UnityLauncher/Form2.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /UnityLauncher/PreviousVersion.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitycoder/UnityLauncher/1b568e3f46bd9752e5bd41ba5b8386613b0d68d2/UnityLauncher/PreviousVersion.txt -------------------------------------------------------------------------------- /UnityLauncher/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using System.Windows.Forms; 5 | 6 | namespace UnityLauncher 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | /* 17 | // TODO allow only single instance https://stackoverflow.com/a/6486341/5452781 18 | bool result = false; 19 | var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result); 20 | 21 | if (result == false) 22 | { 23 | // another instance already running, decide what to do 24 | MessageBox.Show("Another instance is already running."); 25 | return; 26 | }*/ 27 | 28 | Application.EnableVisualStyles(); 29 | Application.SetCompatibleTextRenderingDefault(false); 30 | Application.Run(new Form1()); 31 | 32 | //GC.KeepAlive(mutex); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /UnityLauncher/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnityLauncher")] 9 | [assembly: AssemblyDescription("Unity Version Selected and Automatic Launcher")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("UnityCoder.com")] 12 | [assembly: AssemblyProduct("UnityLauncher")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c48990d2-a403-4e0e-80a2-a5d06fc77663")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /UnityLauncher/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace UnityLauncher.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UnityLauncher.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /UnityLauncher/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /UnityLauncher/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace UnityLauncher.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("\r\n\r\n C:\\Program Files\\\r\n")] 31 | public global::System.Collections.Specialized.StringCollection rootFolders { 32 | get { 33 | return ((global::System.Collections.Specialized.StringCollection)(this["rootFolders"])); 34 | } 35 | set { 36 | this["rootFolders"] = value; 37 | } 38 | } 39 | 40 | [global::System.Configuration.UserScopedSettingAttribute()] 41 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 42 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 43 | public bool minimizeToTaskbar { 44 | get { 45 | return ((bool)(this["minimizeToTaskbar"])); 46 | } 47 | set { 48 | this["minimizeToTaskbar"] = value; 49 | } 50 | } 51 | 52 | [global::System.Configuration.UserScopedSettingAttribute()] 53 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 54 | [global::System.Configuration.DefaultSettingValueAttribute("\r\n")] 56 | public global::System.Collections.Specialized.StringCollection packageFolders { 57 | get { 58 | return ((global::System.Collections.Specialized.StringCollection)(this["packageFolders"])); 59 | } 60 | set { 61 | this["packageFolders"] = value; 62 | } 63 | } 64 | 65 | [global::System.Configuration.UserScopedSettingAttribute()] 66 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 67 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 68 | public bool closeAfterExplorer { 69 | get { 70 | return ((bool)(this["closeAfterExplorer"])); 71 | } 72 | set { 73 | this["closeAfterExplorer"] = value; 74 | } 75 | } 76 | 77 | [global::System.Configuration.UserScopedSettingAttribute()] 78 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 79 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 80 | public bool closeAfterProject { 81 | get { 82 | return ((bool)(this["closeAfterProject"])); 83 | } 84 | set { 85 | this["closeAfterProject"] = value; 86 | } 87 | } 88 | 89 | [global::System.Configuration.UserScopedSettingAttribute()] 90 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 91 | [global::System.Configuration.DefaultSettingValueAttribute("600")] 92 | public int formWidth { 93 | get { 94 | return ((int)(this["formWidth"])); 95 | } 96 | set { 97 | this["formWidth"] = value; 98 | } 99 | } 100 | 101 | [global::System.Configuration.UserScopedSettingAttribute()] 102 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 103 | [global::System.Configuration.DefaultSettingValueAttribute("650")] 104 | public int formHeight { 105 | get { 106 | return ((int)(this["formHeight"])); 107 | } 108 | set { 109 | this["formHeight"] = value; 110 | } 111 | } 112 | 113 | [global::System.Configuration.UserScopedSettingAttribute()] 114 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 115 | public int[] gridColumnWidths { 116 | get { 117 | return ((int[])(this["gridColumnWidths"])); 118 | } 119 | set { 120 | this["gridColumnWidths"] = value; 121 | } 122 | } 123 | 124 | [global::System.Configuration.UserScopedSettingAttribute()] 125 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 126 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 127 | public bool showArgumentsColumn { 128 | get { 129 | return ((bool)(this["showArgumentsColumn"])); 130 | } 131 | set { 132 | this["showArgumentsColumn"] = value; 133 | } 134 | } 135 | 136 | [global::System.Configuration.UserScopedSettingAttribute()] 137 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 138 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 139 | public bool showGitBranchColumn { 140 | get { 141 | return ((bool)(this["showGitBranchColumn"])); 142 | } 143 | set { 144 | this["showGitBranchColumn"] = value; 145 | } 146 | } 147 | 148 | [global::System.Configuration.UserScopedSettingAttribute()] 149 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 150 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 151 | public bool useDarkSkin { 152 | get { 153 | return ((bool)(this["useDarkSkin"])); 154 | } 155 | set { 156 | this["useDarkSkin"] = value; 157 | } 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /UnityLauncher/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | <?xml version="1.0" encoding="utf-16"?> 7 | <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 8 | <string>C:\Program Files\</string> 9 | </ArrayOfString> 10 | 11 | 12 | True 13 | 14 | 15 | <?xml version="1.0" encoding="utf-16"?> 16 | <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /> 17 | 18 | 19 | True 20 | 21 | 22 | False 23 | 24 | 25 | 600 26 | 27 | 28 | 650 29 | 30 | 31 | 32 | 33 | 34 | False 35 | 36 | 37 | False 38 | 39 | 40 | False 41 | 42 | 43 | -------------------------------------------------------------------------------- /UnityLauncher/Tools.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using System.Windows.Forms; 11 | 12 | namespace UnityLauncherTools 13 | { 14 | public static class Tools 15 | { 16 | /// 17 | /// open url with default browser 18 | /// 19 | /// 20 | public static void OpenURL(string url) 21 | { 22 | Process.Start(url); 23 | } 24 | 25 | /// 26 | /// reads .git/HEAD file from the project to get current branch name 27 | /// 28 | /// 29 | /// 30 | public static string ReadGitBranchInfo(string projectPath) 31 | { 32 | string results = null; 33 | DirectoryInfo gitDirectory = FindDir(".git", projectPath); 34 | if (gitDirectory != null) 35 | { 36 | string branchFile = Path.Combine(gitDirectory.FullName, "HEAD"); 37 | if (File.Exists(branchFile)) 38 | { 39 | results = File.ReadAllText(branchFile); 40 | // get branch only 41 | int pos = results.LastIndexOf("/") + 1; 42 | results = results.Substring(pos, results.Length - pos); 43 | } 44 | } 45 | return results; 46 | } 47 | 48 | /// 49 | /// Searches for a directory beginning with "startPath". 50 | /// If the directory is not found, then parent folders are searched until 51 | /// either it is found or the root folder has been reached. 52 | /// Null is returned if the directory was not found. 53 | /// 54 | /// 55 | /// 56 | /// 57 | public static DirectoryInfo FindDir(string dirName, string startPath) 58 | { 59 | DirectoryInfo dirInfo = new DirectoryInfo(Path.Combine(startPath, dirName)); 60 | while (!dirInfo.Exists) 61 | { 62 | if (dirInfo.Parent.Parent == null) 63 | { 64 | return null; 65 | } 66 | dirInfo = new DirectoryInfo(Path.Combine(dirInfo.Parent.Parent.FullName, dirName)); 67 | } 68 | return dirInfo; 69 | } 70 | 71 | /// 72 | /// returns last-write-time for a file or folder 73 | /// 74 | /// full path to file or folder 75 | /// 76 | public static DateTime? GetLastModifiedTime(string path) 77 | { 78 | if (File.Exists(path) == true || Directory.Exists(path) == true) 79 | { 80 | DateTime modification = File.GetLastWriteTime(path); 81 | return modification; 82 | } 83 | else 84 | { 85 | return null; 86 | } 87 | } 88 | 89 | /// 90 | /// reads LauncherArguments.txt file from ProjectSettings-folder 91 | /// 92 | /// full project root path 93 | /// default filename is "LauncherArguments.txt" 94 | /// 95 | public static string ReadCustomLaunchArguments(string projectPath, string launcherArgumentsFile) 96 | { 97 | string results = null; 98 | string argumentsFile = Path.Combine(projectPath, "ProjectSettings", launcherArgumentsFile); 99 | if (File.Exists(argumentsFile) == true) 100 | { 101 | results = File.ReadAllText(argumentsFile); 102 | } 103 | return results; 104 | } 105 | 106 | /// 107 | /// tries to find next higher version 108 | /// 109 | /// 110 | /// 111 | /// 112 | public static string FindNearestVersion(string currentVersion, List allAvailable) 113 | { 114 | if (currentVersion.Contains("2019")) 115 | { 116 | return FindNearestVersionFromSimilarVersions(currentVersion, allAvailable.Where(x => x.Contains("2019"))); 117 | } 118 | if (currentVersion.Contains("2018")) 119 | { 120 | return FindNearestVersionFromSimilarVersions(currentVersion, allAvailable.Where(x => x.Contains("2018"))); 121 | } 122 | if (currentVersion.Contains("2017")) 123 | { 124 | return FindNearestVersionFromSimilarVersions(currentVersion, allAvailable.Where(x => x.Contains("2017"))); 125 | } 126 | return FindNearestVersionFromSimilarVersions(currentVersion, allAvailable.Where(x => !x.Contains("2017"))); 127 | } 128 | 129 | private static string FindNearestVersionFromSimilarVersions(string version, IEnumerable allAvailable) 130 | { 131 | Dictionary stripped = new Dictionary(); 132 | var enumerable = allAvailable as string[] ?? allAvailable.ToArray(); 133 | 134 | foreach (var t in enumerable) 135 | { 136 | stripped.Add(new Regex("[a-zA-z]").Replace(t, "."), t); 137 | } 138 | 139 | var comparableVersion = new Regex("[a-zA-z]").Replace(version, "."); 140 | if (!stripped.ContainsKey(comparableVersion)) 141 | { 142 | stripped.Add(comparableVersion, version); 143 | } 144 | 145 | var comparables = stripped.Keys.OrderBy(x => x).ToList(); 146 | var actualIndex = comparables.IndexOf(comparableVersion); 147 | 148 | if (actualIndex < stripped.Count - 1) return stripped[comparables[actualIndex + 1]]; 149 | return null; 150 | } 151 | 152 | /// 153 | /// opens release notes url in default browser 154 | /// 155 | /// 156 | /// 157 | public static bool OpenReleaseNotes(string version) 158 | { 159 | bool result = false; 160 | var url = GetUnityReleaseURL(version); 161 | if (string.IsNullOrEmpty(url) == false) 162 | { 163 | Process.Start(url); 164 | result = true; 165 | } 166 | else 167 | { 168 | } 169 | return result; 170 | } 171 | 172 | /// 173 | /// returns release page URL to given version 174 | /// NOTE: doesnt parse alpha versions, since they are not visible 175 | /// 176 | /// 177 | /// 178 | public static string GetUnityReleaseURL(string version) 179 | { 180 | string url = ""; 181 | if (VersionIsArchived(version)) 182 | { 183 | // remove f# 184 | version = Regex.Replace(version, @"f.", "", RegexOptions.IgnoreCase); 185 | 186 | string padding = "unity-"; 187 | string whatsnew = "whats-new"; 188 | 189 | if (version.Contains("5.6")) padding = ""; 190 | if (version.Contains("2017.1")) whatsnew = "whatsnew"; 191 | if (version.Contains("2018.2")) whatsnew = "whatsnew"; 192 | if (version.Contains("2018.3")) padding = ""; 193 | if (version.Contains("2018.1")) whatsnew = "whatsnew"; // doesnt work 194 | if (version.Contains("2017.4.")) padding = ""; // doesnt work for all versions 195 | if (version.Contains("2018.4.")) padding = ""; 196 | if (version.Contains("2019")) padding = ""; 197 | url = "https://unity3d.com/unity/" + whatsnew + "/" + padding + version; 198 | } 199 | else 200 | if (VersionIsPatch(version)) 201 | { 202 | url = "https://unity3d.com/unity/qa/patch-releases/" + version; 203 | } 204 | else 205 | if (VersionIsBeta(version)) 206 | { 207 | url = "https://unity3d.com/unity/beta/" + version; 208 | } 209 | else 210 | if (VersionIsAlpha(version)) 211 | { 212 | url = "https://unity3d.com/unity/alpha/" + version; 213 | } 214 | 215 | Console.WriteLine(url); 216 | 217 | return url; 218 | } 219 | 220 | // if version contains *f* its archived version 221 | public static bool VersionIsArchived(string version) 222 | { 223 | return version.Contains("f"); 224 | } 225 | 226 | public static bool VersionIsPatch(string version) 227 | { 228 | return version.Contains("p"); 229 | } 230 | 231 | public static bool VersionIsBeta(string version) 232 | { 233 | return version.Contains("b"); 234 | } 235 | 236 | public static bool VersionIsAlpha(string version) 237 | { 238 | return version.Contains("a"); 239 | } 240 | 241 | /// 242 | /// uninstall context menu item from registry 243 | /// 244 | /// 245 | public static void RemoveContextMenuRegistry(string contextRegRoot) 246 | { 247 | RegistryKey key = Registry.CurrentUser.OpenSubKey(contextRegRoot, true); 248 | if (key != null) 249 | { 250 | var appName = "UnityLauncher"; 251 | RegistryKey appKey = Registry.CurrentUser.OpenSubKey(contextRegRoot + "\\" + appName, false); 252 | if (appKey != null) 253 | { 254 | key.DeleteSubKeyTree(appName); 255 | //SetStatus("Removed context menu registry items"); 256 | } 257 | else 258 | { 259 | //SetStatus("Nothing to uninstall.."); 260 | } 261 | } 262 | else 263 | { 264 | //SetStatus("Error> Cannot find registry key: " + contextRegRoot); 265 | } 266 | } 267 | 268 | /// 269 | /// install context menu item to registry 270 | /// 271 | /// 272 | public static void AddContextMenuRegistry(string contextRegRoot) 273 | { 274 | RegistryKey key = Registry.CurrentUser.OpenSubKey(contextRegRoot, true); 275 | 276 | // add folder if missing 277 | if (key == null) 278 | { 279 | key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\Directory\Background\Shell"); 280 | } 281 | 282 | if (key != null) 283 | { 284 | var appName = "UnityLauncher"; 285 | key.CreateSubKey(appName); 286 | 287 | key = key.OpenSubKey(appName, true); 288 | key.SetValue("", "Open with UnityLauncher"); 289 | key.SetValue("Icon", "\"" + Application.ExecutablePath + "\""); 290 | 291 | key.CreateSubKey("command"); 292 | key = key.OpenSubKey("command", true); 293 | var executeString = "\"" + Application.ExecutablePath + "\""; 294 | executeString += " -projectPath \"%V\""; 295 | key.SetValue("", executeString); 296 | } 297 | else 298 | { 299 | Console.WriteLine("Error> Cannot find registry key: " + contextRegRoot); 300 | } 301 | } 302 | 303 | 304 | /// 305 | /// parse project version from ProjectSettings/ data 306 | /// 307 | /// project base path 308 | /// 309 | public static string GetProjectVersion(string path) 310 | { 311 | var version = ""; 312 | 313 | if (File.Exists(Path.Combine(path, "ProjectVersionOverride.txt"))) 314 | { 315 | version = File.ReadAllText(Path.Combine(path, "ProjectVersionOverride.txt")); 316 | } 317 | else if (Directory.Exists(Path.Combine(path, "ProjectSettings"))) 318 | { 319 | var versionPath = Path.Combine(path, "ProjectSettings", "ProjectVersion.txt"); 320 | if (File.Exists(versionPath) == true) // 5.x and later 321 | { 322 | var data = File.ReadAllLines(versionPath); 323 | 324 | if (data != null && data.Length > 0) 325 | { 326 | var dd = data[0]; 327 | // check first line 328 | if (dd.Contains("m_EditorVersion")) 329 | { 330 | var t = dd.Split(new string[] { "m_EditorVersion: " }, StringSplitOptions.None); 331 | if (t != null && t.Length > 0) 332 | { 333 | version = t[1].Trim(); 334 | } 335 | else 336 | { 337 | throw new InvalidDataException("invalid version data:" + data); 338 | } 339 | } 340 | else 341 | { 342 | MessageBox.Show("Cannot find m_EditorVersion in '" + versionPath + "'.\n\nFile Content:\n" + string.Join("\n", data).ToString()); 343 | } 344 | } 345 | else 346 | { 347 | MessageBox.Show("Invalid projectversion data found in '" + versionPath + "'.\n\nFile Content:\n" + string.Join("\n", data).ToString()); 348 | } 349 | } 350 | else // maybe its 4.x 351 | { 352 | versionPath = Path.Combine(path, "ProjectSettings", "ProjectSettings.asset"); 353 | if (File.Exists(versionPath) == true) 354 | { 355 | // first try if its ascii format 356 | var data = File.ReadAllLines(versionPath); 357 | if (data != null && data.Length > 0 && data[0].IndexOf("YAML") > -1) 358 | { 359 | // in text format, then we need to try library file instead 360 | var newVersionPath = Path.Combine(path, "Library", "AnnotationManager"); 361 | if (File.Exists(newVersionPath) == true) 362 | { 363 | versionPath = newVersionPath; 364 | } 365 | } 366 | 367 | // try to get version data out from binary asset 368 | var binData = File.ReadAllBytes(versionPath); 369 | if (binData != null && binData.Length > 0) 370 | { 371 | int dataLen = 7; 372 | int startIndex = 20; 373 | var bytes = new byte[dataLen]; 374 | for (int i = 0; i < dataLen; i++) 375 | { 376 | bytes[i] = binData[startIndex + i]; 377 | } 378 | version = Encoding.UTF8.GetString(bytes); 379 | } 380 | } 381 | } 382 | } 383 | return version; 384 | } 385 | 386 | /// 387 | /// checks file version info 388 | /// 389 | /// 390 | /// 391 | public static string GetFileVersionData(string path) 392 | { 393 | FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(path); 394 | return fvi.ProductName.Replace("(64-bit)", "").Trim(); 395 | //return fvi.FileVersion.Replace("(64-bit)", "").Trim(); 396 | } 397 | 398 | /// 399 | /// launch windows explorer to selected project folder 400 | /// 401 | /// 402 | public static bool LaunchExplorer(string folder) 403 | { 404 | bool result = false; 405 | if (Directory.Exists(folder) == true) 406 | { 407 | Process.Start(folder); 408 | result = true; 409 | } 410 | else 411 | { 412 | result = false; 413 | } 414 | return result; 415 | } 416 | 417 | } 418 | } 419 | -------------------------------------------------------------------------------- /UnityLauncher/UnityLauncher.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C48990D2-A403-4E0E-80A2-A5D06FC77663} 8 | WinExe 9 | UnityLauncher 10 | UnityLauncher 11 | v4.5 12 | 512 13 | false 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 1 25 | 1.0.0.%2a 26 | false 27 | true 28 | true 29 | 30 | 31 | AnyCPU 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | AnyCPU 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | 49 | 50 | 597E4EF6AB63EA908F381A7D86C9B7095269CFFF 51 | 52 | 53 | UnityLauncher_TemporaryKey.pfx 54 | 55 | 56 | true 57 | 58 | 59 | false 60 | 61 | 62 | unitylauncher.ico 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Form 81 | 82 | 83 | Form1.cs 84 | 85 | 86 | Form 87 | 88 | 89 | Form2.cs 90 | 91 | 92 | 93 | 94 | Form1.cs 95 | 96 | 97 | Form2.cs 98 | 99 | 100 | ResXFileCodeGenerator 101 | Resources.Designer.cs 102 | Designer 103 | 104 | 105 | True 106 | Resources.resx 107 | 108 | 109 | SettingsSingleFileGenerator 110 | Settings.Designer.cs 111 | 112 | 113 | True 114 | Settings.settings 115 | True 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | False 125 | .NET Framework 3.5 SP1 126 | false 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /UnityLauncher/unitylauncher.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitycoder/UnityLauncher/1b568e3f46bd9752e5bd41ba5b8386613b0d68d2/UnityLauncher/unitylauncher.ico --------------------------------------------------------------------------------