-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathInstallPath.cs
161 lines (139 loc) · 6.79 KB
/
InstallPath.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
class InstallPath
{
public static string GetInstallPath()
{
string path = "C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Steam";
if (!Directory.Exists(path) || !File.Exists(Path.Combine(path, "Steam.lnk")))
{
if (Directory.Exists("C:/Program Files (x86)/Origin Games/Titanfall2") && File.Exists("C:/Program Files (x86)/Origin Games/Titanfall2/Titanfall2.exe"))
return "C:/Program Files (x86)/Origin Games/Titanfall2";
try
{
RegistryKey originReg = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Respawn").OpenSubKey("Titanfall2");
if (originReg.GetValue("Install Dir") != null) return (string)originReg.GetValue("Install Dir");
}
catch
{
}
MessageBox.Show("Could not find install location automatically", "Could not find install location automatically. Please select the folder containing the Titanfall2.exe file.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return GetInstallPathManually();
}
// AUTOMATIC AQCUISITION
// THE COOL SHIT:TM:
string target = GetShortcutTarget(Path.Combine(path, "Steam.lnk"));
string steamDir = Path.GetDirectoryName(target);
Console.WriteLine(target);
List<string> folderPaths = new List<string>();
// probably stupid, but meh
string[] libraryFolders = File.ReadAllText(Path.Combine(steamDir, "config/libraryfolders.vdf")).Split('\"');
for (int i = 0; i < libraryFolders.Length; i++)
{
string val = libraryFolders[i];
if (val == "path")
{
Console.WriteLine(libraryFolders[i + 2]);
folderPaths.Add(libraryFolders[i + 2]);
}
}
foreach (string folder in folderPaths)
{
//Console.WriteLine(folder);
Thread.Sleep(1000);
foreach (string dir in Directory.GetDirectories(Path.Combine(folder, "steamapps/common")))
{
//Console.WriteLine(dir);
if (dir.EndsWith("Titanfall2") && File.Exists(Path.Combine(dir, "Titanfall2.exe")))
{
return dir;
}
}
}
try
{
RegistryKey originReg = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Respawn").OpenSubKey("Titanfall2");
if (originReg.GetValue("Install Dir") != null) return (string)originReg.GetValue("Install Dir");
}
catch
{
}
if (Directory.Exists("C:/Program Files (x86)/Origin Games/Titanfall2") && File.Exists("C:/Program Files (x86)/Origin Games/Titanfall2/Titanfall2.exe"))
return "C:/Program Files (x86)/Origin Games/Titanfall2";
MessageBox.Show("Could not find install location automatically", "Could not find install location automatically. Please select the folder containing the Titanfall2.exe file.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return GetInstallPathManually();
}
static string GetInstallPathManually()
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "Select Titanfall 2 Executable";
dialog.Multiselect = false;
dialog.InitialDirectory = "C:\\Program Files (x86)\\Steam";
if (dialog.ShowDialog() != DialogResult.OK)
{
MessageBox.Show("Error!", "No install location was selected! Select the Titanfall 2 executable!", MessageBoxButtons.OK, MessageBoxIcon.Error);
return GetInstallPathManually();
}
return Path.GetDirectoryName(dialog.FileName);
}
// stolen from the internet
private static string GetShortcutTarget(string file)
{
try
{
if (System.IO.Path.GetExtension(file).ToLower() != ".lnk")
{
throw new Exception("Supplied file must be a .LNK file");
}
FileStream fileStream = File.Open(file, FileMode.Open, FileAccess.Read);
using (System.IO.BinaryReader fileReader = new BinaryReader(fileStream))
{
fileStream.Seek(0x14, SeekOrigin.Begin); // Seek to flags
uint flags = fileReader.ReadUInt32(); // Read flags
if ((flags & 1) == 1)
{ // Bit 1 set means we have to
// skip the shell item ID list
fileStream.Seek(0x4c, SeekOrigin.Begin); // Seek to the end of the header
uint offset = fileReader.ReadUInt16(); // Read the length of the Shell item ID list
fileStream.Seek(offset, SeekOrigin.Current); // Seek past it (to the file locator info)
}
long fileInfoStartsAt = fileStream.Position; // Store the offset where the file info
// structure begins
uint totalStructLength = fileReader.ReadUInt32(); // read the length of the whole struct
fileStream.Seek(0xc, SeekOrigin.Current); // seek to offset to base pathname
uint fileOffset = fileReader.ReadUInt32(); // read offset to base pathname
// the offset is from the beginning of the file info struct (fileInfoStartsAt)
fileStream.Seek((fileInfoStartsAt + fileOffset), SeekOrigin.Begin); // Seek to beginning of
// base pathname (target)
long pathLength = (totalStructLength + fileInfoStartsAt) - fileStream.Position - 2; // read
// the base pathname. I don't need the 2 terminating nulls.
char[] linkTarget = fileReader.ReadChars((int)pathLength); // should be unicode safe
var link = new string(linkTarget);
int begin = link.IndexOf("\0\0");
if (begin > -1)
{
int end = link.IndexOf("\\\\", begin + 2) + 2;
end = link.IndexOf('\0', end) + 1;
string firstPart = link.Substring(0, begin);
string secondPart = link.Substring(end);
return firstPart + secondPart;
}
else
{
return link;
}
}
}
catch
{
return "";
}
}
}