Skip to content

Commit a4ea629

Browse files
committed
add recent project list scanning from registry
1 parent 049d68f commit a4ea629

File tree

6 files changed

+267
-13
lines changed

6 files changed

+267
-13
lines changed

UnityLauncherPro/GetProjects.cs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using Microsoft.Win32;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Text;
6+
7+
namespace UnityLauncherPro
8+
{
9+
public static class GetProjects
10+
{
11+
// which registries we want to scan for projects
12+
static readonly string[] registryPathsToCheck = new string[] { @"SOFTWARE\Unity Technologies\Unity Editor 5.x", @"SOFTWARE\Unity Technologies\Unity Editor 4.x" };
13+
14+
public static Project[] Scan()
15+
{
16+
List<Project> projectsFound = new List<Project>();
17+
18+
var hklm = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
19+
20+
// check each version path
21+
for (int i = 0, len = registryPathsToCheck.Length; i < len; i++)
22+
{
23+
RegistryKey key = hklm.OpenSubKey(registryPathsToCheck[i]);
24+
25+
if (key == null)
26+
{
27+
continue;
28+
}
29+
else
30+
{
31+
//Console.WriteLine("Null registry key at " + registryPathsToCheck[i]);
32+
}
33+
34+
// parse recent project path
35+
foreach (var valueName in key.GetValueNames())
36+
{
37+
if (valueName.IndexOf("RecentlyUsedProjectPaths-") == 0)
38+
{
39+
string projectPath = "";
40+
// check if binary or not
41+
var valueKind = key.GetValueKind(valueName);
42+
if (valueKind == RegistryValueKind.Binary)
43+
{
44+
byte[] projectPathBytes = (byte[])key.GetValue(valueName);
45+
projectPath = Encoding.UTF8.GetString(projectPathBytes, 0, projectPathBytes.Length - 1);
46+
}
47+
else // should be string then
48+
{
49+
projectPath = (string)key.GetValue(valueName);
50+
}
51+
52+
//Console.WriteLine("projectPath=" + projectPath);
53+
54+
// first check if whole folder exists, if not, skip
55+
if (Directory.Exists(projectPath) == false)
56+
{
57+
//Console.WriteLine("Recent project directory not found, skipping: " + projectPath);
58+
continue;
59+
}
60+
61+
string projectName = "";
62+
63+
// get project name from full path
64+
if (projectPath.IndexOf(Path.DirectorySeparatorChar) > -1)
65+
{
66+
projectName = projectPath.Substring(projectPath.LastIndexOf(Path.DirectorySeparatorChar) + 1);
67+
}
68+
else if (projectPath.IndexOf(Path.AltDirectorySeparatorChar) > -1)
69+
{
70+
projectName = projectPath.Substring(projectPath.LastIndexOf(Path.AltDirectorySeparatorChar) + 1);
71+
}
72+
else // no path separator found
73+
{
74+
projectName = projectPath;
75+
}
76+
77+
string csprojFile = Path.Combine(projectPath, projectName + ".csproj");
78+
79+
// solution only
80+
if (File.Exists(csprojFile) == false)
81+
{
82+
csprojFile = Path.Combine(projectPath, projectName + ".sln");
83+
}
84+
85+
// editor only project
86+
if (File.Exists(csprojFile) == false)
87+
{
88+
csprojFile = Path.Combine(projectPath, projectName + ".Editor.csproj");
89+
}
90+
91+
// maybe 4.x project
92+
if (File.Exists(csprojFile) == false)
93+
{
94+
csprojFile = Path.Combine(projectPath, "Assembly-CSharp.csproj");
95+
}
96+
97+
// get last modified date
98+
DateTime? lastUpdated = Tools.GetLastModifiedTime(csprojFile);
99+
Console.WriteLine(lastUpdated.ToString());
100+
101+
// get project version
102+
string projectVersion = Tools.GetProjectVersion(projectPath);
103+
104+
/*
105+
// TODO
106+
// get custom launch arguments, only if column in enabled
107+
string customArgs = "";
108+
if (chkShowLauncherArgumentsColumn.Checked == true)
109+
{
110+
customArgs = Tools.ReadCustomLaunchArguments(projectPath, launcherArgumentsFile);
111+
}
112+
// get git branchinfo, only if column in enabled
113+
string gitBranch = "";
114+
if (chkShowGitBranchColumn.Checked == true)
115+
{
116+
gitBranch = Tools.ReadGitBranchInfo(projectPath);
117+
}
118+
*/
119+
120+
var p = new Project();
121+
p.Title = projectName;
122+
p.Version = projectVersion;
123+
p.Path = projectPath;
124+
p.Modified = lastUpdated;
125+
//p.Arguments = customArgs;
126+
//p.GITBranch = gitBranch;
127+
128+
projectsFound.Add(p);
129+
} // valid key
130+
} // each key
131+
} // for each registry root
132+
133+
return projectsFound.ToArray();
134+
} // Scan()
135+
136+
} // class
137+
} // namespace

UnityLauncherPro/MainWindow.xaml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
66
xmlns:local="clr-namespace:UnityLauncherPro"
77
mc:Ignorable="d"
8-
Title="UnityLauncherPro" Height="600" Width="500" WindowStartupLocation="CenterScreen" Background="{DynamicResource DarkestBackground}" MinWidth="500" MinHeight="300" AllowsTransparency="True" WindowStyle="None" Margin="0" >
8+
Title="UnityLauncherPro" Height="650" Width="600" WindowStartupLocation="CenterScreen" Background="{DynamicResource DarkestBackground}" MinWidth="600" MinHeight="650" AllowsTransparency="True" WindowStyle="None" Margin="0" >
99

1010
<Window.Resources>
1111
<!-- tabs -->
@@ -290,12 +290,12 @@
290290
<DataGrid x:Name="dataGrid" SelectionMode="Single" Margin="4,30,2,42" Background="{x:Null}" BorderBrush="{x:Null}" ColumnHeaderStyle="{StaticResource HeaderStyle}" Padding="0" HorizontalScrollBarVisibility="Disabled" HeadersVisibility="Column" Foreground="#FFD8D8D8" HorizontalGridLinesBrush="#4C000000" VerticalGridLinesBrush="#19000000">
291291

292292
<DataGrid.Columns>
293-
<DataGridTextColumn Binding="{Binding Title}" ClipboardContentBinding="{x:Null}" Header="Project" IsReadOnly="True" MinWidth="123"/>
294-
<DataGridTextColumn Binding="{Binding Version}" ClipboardContentBinding="{x:Null}" Header="Version" IsReadOnly="True"/>
295-
<DataGridTextColumn Binding="{Binding Path}" ClipboardContentBinding="{x:Null}" Header="Path" IsReadOnly="True"/>
296-
<DataGridTextColumn Binding="{Binding Modified}" ClipboardContentBinding="{x:Null}" Header="Modified" IsReadOnly="True"/>
297-
<DataGridTextColumn Binding="{Binding Arguments}" ClipboardContentBinding="{x:Null}" Header="Arguments" IsReadOnly="True"/>
298-
<DataGridTextColumn Binding="{Binding GITBranch}" ClipboardContentBinding="{x:Null}" Header="GITBranch" IsReadOnly="True"/>
293+
<DataGridTextColumn Binding="{Binding Title}" ClipboardContentBinding="{x:Null}" Header="Project" IsReadOnly="True" Width="150"/>
294+
<DataGridTextColumn Binding="{Binding Version}" ClipboardContentBinding="{x:Null}" Header="Version" IsReadOnly="True" Width="72"/>
295+
<DataGridTextColumn Binding="{Binding Path}" ClipboardContentBinding="{x:Null}" Header="Path" IsReadOnly="True" Width="185"/>
296+
<DataGridTextColumn Binding="{Binding Modified, StringFormat=\{0:dd/MM/yyyy HH:mm:ss\}}" ClipboardContentBinding="{x:Null}" Header="Modified" IsReadOnly="True" Width="120"/>
297+
<DataGridTextColumn Binding="{Binding Arguments}" ClipboardContentBinding="{x:Null}" Header="Arguments" IsReadOnly="True" Width="100"/>
298+
<DataGridTextColumn Binding="{Binding GITBranch}" ClipboardContentBinding="{x:Null}" Header="GITBranch" IsReadOnly="True" Width="100"/>
299299
</DataGrid.Columns>
300300

301301
<!-- right click context menu -->
@@ -575,6 +575,7 @@
575575
<CheckBox Content="Close after launching from Explorer" Foreground="{DynamicResource ButtonForeground}"></CheckBox>
576576
<CheckBox Content="Show Arguments Column" Foreground="{DynamicResource ButtonForeground}"></CheckBox>
577577
<CheckBox Content="Show Git Branch Column" Foreground="{DynamicResource ButtonForeground}"></CheckBox>
578+
<CheckBox Content="Show full modified time" Foreground="{DynamicResource ButtonForeground}" ToolTip="Full=dd/mm/yyyy hh:mm:ss, NotFull=x hours ago, x days ago.."></CheckBox>
578579
</StackPanel>
579580

580581
<!-- links-->

UnityLauncherPro/MainWindow.xaml.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public partial class MainWindow : Window
1515

1616
private System.Windows.Forms.NotifyIcon notifyIcon;
1717

18+
Project[] projectsSource;
19+
1820
public MainWindow()
1921
{
2022
InitializeComponent();
@@ -23,16 +25,16 @@ public MainWindow()
2325

2426
void Start()
2527
{
26-
// make window resizable (didnt work within xaml..)
28+
// make window resizable (this didnt work when used pure xaml to do this)
2729
WindowChrome Resizable_BorderLess_Chrome = new WindowChrome();
2830
Resizable_BorderLess_Chrome.GlassFrameThickness = new Thickness(0);
2931
Resizable_BorderLess_Chrome.CornerRadius = new CornerRadius(0);
3032
Resizable_BorderLess_Chrome.CaptionHeight = 1.0;
3133
WindowChrome.SetWindowChrome(this, Resizable_BorderLess_Chrome);
3234

33-
34-
// test data
35+
// add test data
3536
dataGrid.Items.Clear();
37+
/*
3638
for (int i = 0; i < 6; i++)
3739
{
3840
dataGrid.Items.Add(new Project { Title = "asdf" + i, Version = "5000", Path = "A:/", Modified = DateTime.Now, Arguments = "", GITBranch = "-" });
@@ -42,10 +44,14 @@ void Start()
4244
dataGrid.Items.Add(new Project { Title = "asdf", Version = "5000", Path = "A:/", Modified = DateTime.Now, Arguments = "", GITBranch = "-" });
4345
dataGrid.Items.Add(new Project { Title = "asdf asd" + i * 3, Version = "2", Path = "C:/", Modified = DateTime.Now, Arguments = "", GITBranch = "-" });
4446
dataGrid.Items.Add(new Project { Title = "kuykkyu", Version = "23.23.23", Path = "8,1", Modified = DateTime.Now, Arguments = "", GITBranch = "-" });
45-
}
47+
}*/
48+
49+
//dataGrid.Items.Add(GetProjects.Scan());
50+
projectsSource = GetProjects.Scan();
51+
dataGrid.ItemsSource = projectsSource;
4652

4753

48-
// build notifyicon
54+
// build notifyicon (using windows.forms)
4955
notifyIcon = new System.Windows.Forms.NotifyIcon();
5056
notifyIcon.Icon = new Icon(System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/Images/icon.ico")).Stream);
5157
notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(NotifyIcon_MouseClick);
@@ -58,6 +64,7 @@ void NotifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
5864
notifyIcon.Visible = false;
5965
}
6066

67+
// hide/show notifyicon based on window state
6168
private void Window_StateChanged(object sender, EventArgs e)
6269
{
6370
if (this.WindowState == WindowState.Minimized)

UnityLauncherPro/Project.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class Project
77
public string Title { set; get; }
88
public string Version { set; get; }
99
public string Path { set; get; }
10-
public DateTime Modified { set; get; }
10+
public DateTime? Modified { set; get; }
1111
public string Arguments { set; get; }
1212
public string GITBranch { set; get; }
1313
}

UnityLauncherPro/Tools.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System;
2+
using System.IO;
3+
using System.Text;
4+
5+
namespace UnityLauncherPro
6+
{
7+
public static class Tools
8+
{
9+
// returns last modified date for file (or null if cannot get it)
10+
public static DateTime? GetLastModifiedTime(string path)
11+
{
12+
if (File.Exists(path) == true || Directory.Exists(path) == true)
13+
{
14+
DateTime modification = File.GetLastWriteTime(path);
15+
return modification;
16+
}
17+
else
18+
{
19+
return null;
20+
}
21+
}
22+
23+
/// <summary>
24+
/// parse project version from ProjectSettings/ data
25+
/// </summary>
26+
/// <param name="path">project base path</param>
27+
/// <returns></returns>
28+
public static string GetProjectVersion(string path)
29+
{
30+
var version = "";
31+
32+
if (File.Exists(Path.Combine(path, "ProjectVersionOverride.txt")))
33+
{
34+
version = File.ReadAllText(Path.Combine(path, "ProjectVersionOverride.txt"));
35+
}
36+
else if (Directory.Exists(Path.Combine(path, "ProjectSettings")))
37+
{
38+
var versionPath = Path.Combine(path, "ProjectSettings", "ProjectVersion.txt");
39+
if (File.Exists(versionPath) == true) // 5.x and later
40+
{
41+
var data = File.ReadAllLines(versionPath);
42+
43+
if (data != null && data.Length > 0)
44+
{
45+
var dd = data[0];
46+
// check first line
47+
if (dd.Contains("m_EditorVersion"))
48+
{
49+
var t = dd.Split(new string[] { "m_EditorVersion: " }, StringSplitOptions.None);
50+
if (t != null && t.Length > 0)
51+
{
52+
version = t[1].Trim();
53+
}
54+
else
55+
{
56+
throw new InvalidDataException("invalid version data:" + data);
57+
}
58+
}
59+
else
60+
{
61+
Console.WriteLine("Cannot find m_EditorVersion in '" + versionPath + "'.\n\nFile Content:\n" + string.Join("\n", data).ToString());
62+
}
63+
}
64+
else
65+
{
66+
Console.WriteLine("Invalid projectversion data found in '" + versionPath + "'.\n\nFile Content:\n" + string.Join("\n", data).ToString());
67+
}
68+
}
69+
else // maybe its 4.x
70+
{
71+
versionPath = Path.Combine(path, "ProjectSettings", "ProjectSettings.asset");
72+
if (File.Exists(versionPath) == true)
73+
{
74+
// first try if its ascii format
75+
var data = File.ReadAllLines(versionPath);
76+
if (data != null && data.Length > 0 && data[0].IndexOf("YAML") > -1)
77+
{
78+
// in text format, then we need to try library file instead
79+
var newVersionPath = Path.Combine(path, "Library", "AnnotationManager");
80+
if (File.Exists(newVersionPath) == true)
81+
{
82+
versionPath = newVersionPath;
83+
}
84+
}
85+
86+
// try to get version data out from binary asset
87+
var binData = File.ReadAllBytes(versionPath);
88+
if (binData != null && binData.Length > 0)
89+
{
90+
int dataLen = 7;
91+
int startIndex = 20;
92+
var bytes = new byte[dataLen];
93+
for (int i = 0; i < dataLen; i++)
94+
{
95+
bytes[i] = binData[startIndex + i];
96+
}
97+
version = Encoding.UTF8.GetString(bytes);
98+
}
99+
}
100+
}
101+
}
102+
return version;
103+
}
104+
105+
106+
} // class
107+
} // namespace

UnityLauncherPro/UnityLauncherPro.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@
7575
<Generator>MSBuild:Compile</Generator>
7676
<SubType>Designer</SubType>
7777
</ApplicationDefinition>
78+
<Compile Include="GetProjects.cs" />
79+
<Compile Include="Tools.cs" />
7880
<Compile Include="UnityInstallations.cs" />
7981
<Compile Include="Updates.cs" />
8082
<Page Include="Resources\Colors.xaml">

0 commit comments

Comments
 (0)