Skip to content
This repository was archived by the owner on Jul 29, 2023. It is now read-only.

Commit 972b7df

Browse files
committed
Added the ability to find BoxVR exe in Oculus libraris on the local system
1 parent 84ae208 commit 972b7df

File tree

6 files changed

+129
-9
lines changed

6 files changed

+129
-9
lines changed

BOXVR Playlist Manager/App.xaml.cs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using NLog;
33
using System;
44
using System.Collections.Generic;
5+
using System.ComponentModel;
56
using System.Configuration;
67
using System.Data;
78
using System.Diagnostics;
@@ -20,6 +21,7 @@ public partial class App : Application
2021
{
2122
const string DEFAULT_BOXVR_APPDATA = @"%userprofile%\AppData\LocalLow\FITXR\BOXVR";
2223
const string REGISTRY_UNINSTALL_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
24+
const string REGISTRY_OCULUS_LIB_KEY = @"Software\Oculus VR, LLC\Oculus\Libraries";
2325
const string REGISTRY_STEAM_KEY = @"HKEY_CURRENT_USER\Software\Valve\Steam";
2426

2527

@@ -76,20 +78,78 @@ private static string LocateBoxVRExe()
7678
{
7779
using (var subkey = key.OpenSubKey(subkey_name))
7880
{
79-
logger.Trace($"Checking reg key {REGISTRY_UNINSTALL_KEY}\\{subkey_name}");
81+
logger.Trace($"Checking reg key HKLM\\{REGISTRY_UNINSTALL_KEY}\\{subkey_name}");
8082
if (string.Equals(subkey.GetValue("DisplayName")?.ToString(), "BOXVR", StringComparison.OrdinalIgnoreCase))
8183
{
8284
var location = subkey.GetValue("InstallLocation")?.ToString();
8385
if(location != null)
8486
{
85-
logger.Debug($"BoxVR location found in reg key {REGISTRY_UNINSTALL_KEY}\\{subkey_name}: {location}");
87+
logger.Debug($"BoxVR location found in reg key HKLM\\{REGISTRY_UNINSTALL_KEY}\\{subkey_name}: {location}");
8688
return location;
8789
}
8890
}
8991
}
9092
}
9193
}
9294

95+
logger.Debug("Searching registry for Oculus library location");
96+
using (var key = Registry.CurrentUser.OpenSubKey(REGISTRY_OCULUS_LIB_KEY))
97+
{
98+
if (key == null)
99+
{
100+
logger.Trace($"Couldn't locate Oculus registry key: {REGISTRY_OCULUS_LIB_KEY}");
101+
}
102+
else
103+
{
104+
var mountPoints = new List<string>();
105+
foreach(var subkey_name in key.GetSubKeyNames())
106+
{
107+
using(var subkey = key.OpenSubKey(subkey_name))
108+
{
109+
logger.Trace($"Checking reg key HKCU\\{REGISTRY_OCULUS_LIB_KEY}\\{subkey_name}");
110+
var libPath = subkey.GetValue("Path")?.ToString();
111+
if(libPath == null)
112+
{
113+
logger.Trace($"No 'Path' value found, moving on");
114+
}
115+
else
116+
{
117+
logger.Trace($"Path found: {libPath}, searching for 'fitxr-boxvr'");
118+
var volumeIdMatch = Regex.Match(libPath, @"(\\\\\?\\Volume{.*?}\\)(.*)");
119+
if (volumeIdMatch.Success)
120+
{
121+
logger.Trace($"Getting mount points for volume {volumeIdMatch.Groups[1].Value}");
122+
try
123+
{
124+
var _mountPoints = SafeNativeMethods.GetMountPointsForVolume(volumeIdMatch.Groups[1].Value);
125+
logger.Trace($"Found the following mountpoints for {volumeIdMatch.Groups[1].Value}:\r\n{string.Join("\r\n", _mountPoints)}");
126+
mountPoints.AddRange(_mountPoints.Select(m => Path.Combine(m, volumeIdMatch.Groups[2].Value)));
127+
}
128+
catch (Win32Exception ex)
129+
{
130+
logger.Error(ex);
131+
}
132+
}
133+
else
134+
{
135+
logger.Trace("Failed to find volume GUID path");
136+
}
137+
}
138+
}
139+
}
140+
141+
foreach(var mountPoint in mountPoints)
142+
{
143+
var location = Path.Combine(mountPoint, "Software", "fitxr-boxvr");
144+
if (File.Exists(Path.Combine(location, "BoxVR.exe")))
145+
{
146+
logger.Debug($"BoxVR located in Oculus library: {location}");
147+
return location;
148+
}
149+
}
150+
}
151+
}
152+
93153
logger.Debug("Searching registry for Steam install location");
94154
var steamPath = Registry.GetValue(REGISTRY_STEAM_KEY, "SteamPath", null)?.ToString();
95155
if (steamPath != null)

BOXVR Playlist Manager/BOXVR Playlist Manager.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<Compile Include="Extensions.cs" />
7171
<Compile Include="IsEnabledColorConverter.cs" />
7272
<Compile Include="Track.cs" />
73+
<Compile Include="SafeNativeMethods.cs" />
7374
<Page Include="App.xaml">
7475
<Generator>MSBuild:Compile</Generator>
7576
<SubType>Designer</SubType>

BOXVR Playlist Manager/MainWindow.xaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@
140140
<DataGrid Grid.Row="1" Name="playlistTracks" ItemsSource="{Binding Tracks}" AllowDrop="True" SelectionMode="Extended"
141141
FontSize="14" AutoGenerateColumns="False" IsReadOnly="True" SelectedItem="{Binding SelectedTrack}" Sorting="playlistTracks_Sorting">
142142
<DataGrid.Columns>
143-
<DataGridTextColumn Header="Title" Binding="{Binding Title}" Width="Auto" />
144-
<DataGridTextColumn Header="Artist" Binding="{Binding Artist}" Width="Auto" />
145-
<DataGridTextColumn Header="Album" Binding="{Binding Album}" Width="Auto" />
146-
<DataGridTextColumn Header="Duration" Binding="{Binding Duration,StringFormat={}{0:mm':'ss}}" Width="Auto" />
143+
<DataGridTextColumn Header="Title" Binding="{Binding Title}" />
144+
<DataGridTextColumn Header="Artist" Binding="{Binding Artist}" />
145+
<DataGridTextColumn Header="Album" Binding="{Binding Album}" />
146+
<DataGridTextColumn Header="Duration" Binding="{Binding Duration,StringFormat={}{0:mm':'ss}}" />
147147
</DataGrid.Columns>
148148
<DataGrid.ContextMenu>
149149
<ContextMenu>

BOXVR Playlist Manager/MainWindow.xaml.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ private Playlist SelectedPlaylist
3333
{
3434
_selectedPlaylist = value;
3535
playlistView.DataContext = SelectedPlaylist;
36-
playlistView.UpdateLayout();
3736
gridGeneratingBeatmaps.DataContext = SelectedPlaylist;
3837
}
3938
}

BOXVR Playlist Manager/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
// You can specify all the values or you can default the Build and Revision Numbers
5252
// by using the '*' as shown below:
5353
// [assembly: AssemblyVersion("1.0.*")]
54-
[assembly: AssemblyVersion("1.0.1.0")]
55-
[assembly: AssemblyFileVersion("1.0.1.0")]
54+
[assembly: AssemblyVersion("1.1.1.0")]
55+
[assembly: AssemblyFileVersion("1.1.1.0")]
5656
[assembly: NeutralResourcesLanguage("en-GB")]
5757

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Linq;
5+
using System.Runtime.InteropServices;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace BoxVR_Playlist_Manager
10+
{
11+
internal static class SafeNativeMethods
12+
{
13+
#region GetVolumePathNamesForVolumeNameW Win32 API sample from https://www.pinvoke.net/default.aspx/kernel32.getvolumepathnamesforvolumename
14+
[DllImport("kernel32.dll", SetLastError = true)]
15+
[return: MarshalAs(UnmanagedType.Bool)]
16+
private static extern bool GetVolumePathNamesForVolumeNameW (
17+
[MarshalAs(UnmanagedType.LPWStr)]
18+
string lpszVolumeName,
19+
[MarshalAs(UnmanagedType.LPWStr)]
20+
string lpszVolumePathNames,
21+
uint cchBuferLength,
22+
ref uint lpcchReturnLength
23+
);
24+
25+
public static List<string> GetMountPointsForVolume(string volumeDeviceName)
26+
{
27+
List<string> result = new List<string>();
28+
29+
// GetVolumePathNamesForVolumeName is only available on Windows XP/2003 and above
30+
int osVersionMajor = Environment.OSVersion.Version.Major;
31+
int osVersionMinor = Environment.OSVersion.Version.Minor;
32+
if (osVersionMajor < 5 || (osVersionMajor == 5 && osVersionMinor < 1))
33+
{
34+
return result;
35+
}
36+
37+
uint lpcchReturnLength = 0;
38+
string buffer = "";
39+
40+
GetVolumePathNamesForVolumeNameW(volumeDeviceName, buffer, (uint)buffer.Length, ref lpcchReturnLength);
41+
if (lpcchReturnLength == 0)
42+
{
43+
throw new Win32Exception(Marshal.GetLastWin32Error());
44+
return result;
45+
}
46+
47+
buffer = new string(new char[lpcchReturnLength]);
48+
49+
if (!GetVolumePathNamesForVolumeNameW(volumeDeviceName, buffer, lpcchReturnLength, ref lpcchReturnLength))
50+
{
51+
throw new Win32Exception(Marshal.GetLastWin32Error());
52+
}
53+
54+
result.AddRange(buffer.Split('\0').Where(m => m.Length > 0));
55+
56+
return result;
57+
}
58+
#endregion
59+
}
60+
}

0 commit comments

Comments
 (0)