Skip to content

Commit 5db7778

Browse files
committed
Prevent multiple Instances / Installer Changes
1 parent daf2c02 commit 5db7778

File tree

12 files changed

+151
-61
lines changed

12 files changed

+151
-61
lines changed

Installer/AppPackage.zip

42 Bytes
Binary file not shown.

Installer/Installer.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<UpdateRequired>false</UpdateRequired>
2727
<MapFileExtensions>true</MapFileExtensions>
2828
<ApplicationRevision>0</ApplicationRevision>
29-
<ApplicationVersion>0.4.1.0</ApplicationVersion>
29+
<ApplicationVersion>0.4.2.0</ApplicationVersion>
3030
<UseApplicationTrust>false</UseApplicationTrust>
3131
<PublishWizardCompleted>true</PublishWizardCompleted>
3232
<BootstrapperEnabled>true</BootstrapperEnabled>

Installer/InstallerFunctions.cs

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.Win32;
22
using System;
3+
using System.Collections.Generic;
34
using System.Diagnostics;
45
using System.Globalization;
56
using System.IO;
@@ -18,6 +19,7 @@ namespace Installer
1819
{
1920
public enum AutoStart
2021
{
22+
REMOVE = -1,
2123
NONE = 0,
2224
FSUIPC,
2325
EXE
@@ -32,7 +34,7 @@ public static bool GetProcessRunning(string name)
3234
}
3335

3436
#region Install Actions
35-
public static bool AutoStartFsuipc()
37+
public static bool AutoStartFsuipc(bool removeEntry = false)
3638
{
3739
bool result = false;
3840
string programParam = "READY";
@@ -50,9 +52,9 @@ public static bool AutoStartFsuipc()
5052
if (File.Exists(regPath))
5153
{
5254
string fileContent = File.ReadAllText(regPath, Encoding.Default);
53-
if (!fileContent.Contains("[Programs]"))
55+
if (!fileContent.Contains("[Programs]") && !removeEntry)
5456
{
55-
fileContent += $"\r\n[Programs]\r\nRunIf1={programParam},KILL,{Parameters.binPath}";
57+
fileContent += $"\r\n[Programs]\r\nRunIf1={programParam},CLOSE,{Parameters.binPath}";
5658
File.WriteAllText(regPath, fileContent, Encoding.Default);
5759
result = true;
5860
}
@@ -69,15 +71,21 @@ public static bool AutoStartFsuipc()
6971
if (runIfMatches.Count > 0 && runIfMatches[runIfMatches.Count - 1].Groups.Count == 2)
7072
lastRunIf = Convert.ToInt32(runIfMatches[runIfMatches.Count - 1].Groups[1].Value);
7173

72-
if (Regex.IsMatch(fileContent, @"^[;]{0,1}Run(\d+).*WorkingTitle2GSX\.exe", regOptions))
74+
if (Regex.IsMatch(fileContent, @"^[;]{0,1}Run(\d+).*" + Parameters.appName + "\\.exe", regOptions))
7375
{
74-
fileContent = Regex.Replace(fileContent, @"^[;]{0,1}Run(\d+).*WorkingTitle2GSX\.exe", $"RunIf{lastRunIf + 1}={programParam},KILL,{Parameters.binPath}", regOptions);
76+
if (!removeEntry)
77+
fileContent = Regex.Replace(fileContent, @"^[;]{0,1}Run(\d+).*" + Parameters.appName + "\\.exe", $"RunIf{lastRunIf + 1}={programParam},CLOSE,{Parameters.binPath}", regOptions);
78+
else
79+
fileContent = Regex.Replace(fileContent, @"^[;]{0,1}Run(\d+).*" + Parameters.appName + "\\.exe", $"", regOptions);
7580
File.WriteAllText(regPath, fileContent, Encoding.Default);
7681
result = true;
7782
}
78-
else if (Regex.IsMatch(fileContent, @"^[;]{0,1}RunIf(\d+).*WorkingTitle2GSX\.exe", regOptions))
83+
else if (Regex.IsMatch(fileContent, @"^[;]{0,1}RunIf(\d+).*" + Parameters.appName + "\\.exe", regOptions))
7984
{
80-
fileContent = Regex.Replace(fileContent, @"^[;]{0,1}RunIf(\d+).*WorkingTitle2GSX\.exe", $"RunIf$1={programParam},KILL,{Parameters.binPath}", regOptions);
85+
if (!removeEntry)
86+
fileContent = Regex.Replace(fileContent, @"^[;]{0,1}RunIf(\d+).*" + Parameters.appName + "\\.exe", $"RunIf$1={programParam},CLOSE,{Parameters.binPath}", regOptions);
87+
else
88+
fileContent = Regex.Replace(fileContent, @"^[;]{0,1}RunIf(\d+).*" + Parameters.appName + "\\.exe", $"", regOptions);
8189
File.WriteAllText(regPath, fileContent, Encoding.Default);
8290
result = true;
8391
}
@@ -95,15 +103,15 @@ public static bool AutoStartFsuipc()
95103
else if (runMatches.Count > 0)
96104
index = runMatches[runMatches.Count - 1].Index + runMatches[runMatches.Count - 1].Length;
97105

98-
if (index > 0)
106+
if (index > 0 && !removeEntry)
99107
{
100-
fileContent = fileContent.Insert(index + 1, $"RunIf{lastRunIf + 1}={programParam},KILL,{Parameters.binPath}\r\n");
108+
fileContent = fileContent.Insert(index + 1, $"RunIf{lastRunIf + 1}={programParam},CLOSE,{Parameters.binPath}\r\n");
101109
File.WriteAllText(regPath, fileContent, Encoding.Default);
102110
result = true;
103111
}
104-
else
112+
else if (!removeEntry)
105113
{
106-
fileContent = Regex.Replace(fileContent, @"^\[Programs\]\r\n", $"[Programs]\r\nRunIf{lastRunIf + 1}={programParam},KILL,{Parameters.binPath}\r\n", regOptions);
114+
fileContent = Regex.Replace(fileContent, @"^\[Programs\]\r\n", $"[Programs]\r\nRunIf{lastRunIf + 1}={programParam},CLOSE,{Parameters.binPath}\r\n", regOptions);
107115
File.WriteAllText(regPath, fileContent, Encoding.Default);
108116
result = true;
109117
}
@@ -119,7 +127,7 @@ public static bool AutoStartFsuipc()
119127
return result;
120128
}
121129

122-
public static bool AutoStartExe()
130+
public static bool AutoStartExe(bool removeEntry = false)
123131
{
124132
bool result = false;
125133

@@ -134,26 +142,35 @@ public static bool AutoStartExe()
134142

135143
bool found = false;
136144
XmlNode simbase = xmlDoc.ChildNodes[1];
145+
List<XmlNode> removeList = new List<XmlNode>();
137146
foreach (XmlNode outerNode in simbase.ChildNodes)
138147
{
139-
if (outerNode.Name == "Launch.Addon" && outerNode.InnerText.Contains("WorkingTitle2GSX.exe"))
148+
if (outerNode.Name == "Launch.Addon" && outerNode.InnerText.Contains(Parameters.appBinary))
140149
{
141150
found = true;
142-
foreach (XmlNode innerNode in outerNode.ChildNodes)
151+
152+
if (!removeEntry)
143153
{
144-
if (innerNode.Name == "Disabled")
145-
innerNode.InnerText = "False";
146-
else if (innerNode.Name == "Path")
147-
innerNode.InnerText = Parameters.binPath;
148-
else if (innerNode.Name == "CommandLine")
149-
innerNode.InnerText = "";
150-
else if (innerNode.Name == "ManualLoad")
151-
innerNode.InnerText = "False";
154+
foreach (XmlNode innerNode in outerNode.ChildNodes)
155+
{
156+
if (innerNode.Name == "Disabled")
157+
innerNode.InnerText = "False";
158+
else if (innerNode.Name == "Path")
159+
innerNode.InnerText = Parameters.binPath;
160+
else if (innerNode.Name == "CommandLine")
161+
innerNode.InnerText = "";
162+
else if (innerNode.Name == "ManualLoad")
163+
innerNode.InnerText = "False";
164+
}
152165
}
166+
else
167+
removeList.Add(outerNode);
153168
}
154169
}
170+
foreach (XmlNode node in removeList)
171+
xmlDoc.ChildNodes[1].RemoveChild(node);
155172

156-
if (!found)
173+
if (!found && !removeEntry)
157174
{
158175
XmlNode outerNode = xmlDoc.CreateElement("Launch.Addon");
159176

@@ -166,7 +183,7 @@ public static bool AutoStartExe()
166183
outerNode.AppendChild(innerNode);
167184

168185
innerNode = xmlDoc.CreateElement("Name");
169-
innerNode.InnerText = "WorkingTitle2GSX";
186+
innerNode.InnerText = Parameters.appName;
170187
outerNode.AppendChild(innerNode);
171188

172189
innerNode = xmlDoc.CreateElement("Path");
@@ -194,12 +211,12 @@ public static bool PlaceDesktopLink()
194211
{
195212
IShellLink link = (IShellLink)new ShellLink();
196213

197-
link.SetDescription("Start WorkingTitle2GSX");
214+
link.SetDescription("Start " + Parameters.appName);
198215
link.SetPath(Parameters.binPath);
199216

200217
IPersistFile file = (IPersistFile)link;
201218
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
202-
file.Save(Path.Combine(desktopPath, "WorkingTitle2GSX.lnk"), false);
219+
file.Save(Path.Combine(desktopPath, $"{Parameters.appName}.lnk"), false);
203220
result = true;
204221
}
205222
catch (Exception e)
@@ -473,6 +490,22 @@ public static bool StringGreaterEqual(string input, int compare)
473490
return false;
474491
}
475492

493+
public static bool StringEqual(string input, int compare)
494+
{
495+
if (int.TryParse(input, NumberStyles.Number, CultureInfo.InvariantCulture, out int numA) && numA == compare)
496+
return true;
497+
else
498+
return false;
499+
}
500+
501+
public static bool StringGreater(string input, int compare)
502+
{
503+
if (int.TryParse(input, NumberStyles.Number, CultureInfo.InvariantCulture, out int numA) && numA > compare)
504+
return true;
505+
else
506+
return false;
507+
}
508+
476509
public static bool CheckDotNet()
477510
{
478511
try
@@ -484,9 +517,12 @@ public static bool CheckDotNet()
484517
var matches = Parameters.netDesktop.Matches(output);
485518
foreach (Match match in matches)
486519
{
487-
if (!match.Success || match.Groups.Count != 5) continue;
488-
489-
if (StringGreaterEqual(match.Groups[2].Value, Parameters.netMajor) && StringGreaterEqual(match.Groups[3].Value, Parameters.netMinor) && StringGreaterEqual(match.Groups[4].Value, Parameters.netPatch))
520+
if (!match.Success || match.Groups.Count != 5)
521+
continue;
522+
if (!StringEqual(match.Groups[2].Value, Parameters.netMajor))
523+
continue;
524+
if ((StringEqual(match.Groups[3].Value, Parameters.netMinor) && StringGreaterEqual(match.Groups[4].Value, Parameters.netPatch))
525+
|| StringGreater(match.Groups[3].Value, Parameters.netMinor))
490526
installedDesktop = true;
491527
}
492528

Installer/InstallerWindow.xaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@
1313
<Label HorizontalContentAlignment="Center" Margin="12,-8,12,0">But NOTE: For FSUIPC only the State and Version is checked, you have to install/update it manually!</Label>
1414
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
1515
<CheckBox Name="chkDesktopLink" IsChecked="True" HorizontalAlignment="Left" Margin="0,12,12,0" Click="chkDesktopLink_Click">Create Link on Desktop</CheckBox>
16-
<RadioButton Name="radioNone" GroupName="AutoStart" IsChecked="True" HorizontalAlignment="Left" Margin="0,13,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="The Installer does not touch anything. You have to take Care of Adding/Updating the Auto-Start.">Do not configure Auto-Start</RadioButton>
17-
<RadioButton Name="radioFsuipc" GroupName="AutoStart" HorizontalAlignment="Left" Margin="0,1,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="WorkingTitle2GSX will be started by FSUIPC - it will modify your FSUIPC7.ini File.&#x0a;An existing Entry will automatically be updated, else a new Entry is inserted.&#x0a;A Backup of the FSUIPC7.ini File is not created.">Auto-Start with FSUIPC</RadioButton>
18-
<RadioButton Name="radioExe" GroupName="AutoStart" HorizontalAlignment="Left" Margin="0,1,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="WorkingTitle2GSX will be started by MSFS - it will modify your EXE.xml File.&#x0a;An existing Entry will automatically be updated, else a new Entry is inserted.&#x0a;A Backup of the EXE.xml File is not created.">Auto-Start with MSFS</RadioButton>
16+
<RadioButton Name="radioRemove" GroupName="AutoStart" HorizontalAlignment="Left" Margin="0,13,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="Remove existing Auto-Start Entries (FSUIPC and MSFS).">Remove Auto-Start</RadioButton>
17+
<RadioButton Name="radioNone" GroupName="AutoStart" IsChecked="True" HorizontalAlignment="Left" Margin="0,1,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="The Installer does not touch anything.&#x0a;You have to take Care of Adding/Updating/Removing the Auto-Start Entries.">Do not configure Auto-Start</RadioButton>
18+
<RadioButton Name="radioFsuipc" GroupName="AutoStart" HorizontalAlignment="Left" Margin="0,1,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="WorkingTitle2GSX will be started by FSUIPC - it will modify your FSUIPC7.ini File.&#x0a;An existing Entry will automatically be updated, else a new Entry is inserted.&#x0a;An existing Auto-Start Entry in your FSUIPC7.ini will automatically be removed!&#x0a;A Backup of the Files is not created!">Auto-Start with FSUIPC</RadioButton>
19+
<RadioButton Name="radioExe" GroupName="AutoStart" HorizontalAlignment="Left" Margin="0,1,0,0" Click="radio_Click" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ToolTip="WorkingTitle2GSX will be started by MSFS - it will modify your EXE.xml File.&#x0a;An existing Entry will automatically be updated, else a new Entry is inserted.&#x0a;An existing Auto-Start Entry in your FSUIPC7.ini will automatically be removed!&#x0a;A Backup of the Files is not created!">Auto-Start with MSFS</RadioButton>
1920
</StackPanel>
2021
<TextBlock Name="txtMessages" MinHeight="0" Margin="12,16,12,0"></TextBlock>
2122
<Label Name="lblResult" HorizontalContentAlignment="Center" FontWeight="DemiBold" Margin="12,0,12,0"></Label>
2223
<Label Name="lblAvWarning" HorizontalContentAlignment="Center" FontWeight="DemiBold" Margin="12,0,12,0" Visibility="Collapsed">Remember to set/update your Anti-Virus Exclusion, if necessary.</Label>
2324
<Label Name="lblRebootWarning" HorizontalContentAlignment="Center" FontWeight="DemiBold" Margin="12,-8,12,0" Visibility="Collapsed">If you have installed WorkingTitle2GSX for the first Time, reboot your PC after Installation has finished!</Label>
2425
<Button Name="btnInstall" FontWeight="DemiBold" Width="128" MinHeight="24" Margin="12,16,12,12" Click="btnInstall_Click">Install!</Button>
26+
<Button Name="btnRemove" FontWeight="DemiBold" Width="128" MinHeight="24" Margin="12,4,12,12" Foreground="Red" Click="btnRemove_Click" ToolTip="Attention: Will remove the whole App including its current Configuration. Does also remove Auto-Start Entries for it from FSUIPC and MSFS.">Remove!</Button>
2527
</StackPanel>
2628
</Grid>
2729
</Window>

Installer/InstallerWindow.xaml.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Reflection;
45
using System.Threading.Tasks;
56
using System.Windows;
@@ -21,7 +22,15 @@ public InstallerWindow()
2122

2223
string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
2324
assemblyVersion = assemblyVersion.Substring(0, assemblyVersion.LastIndexOf('.'));
24-
Title += " (" + assemblyVersion + ")";
25+
Title += " (" + assemblyVersion + ")";
26+
27+
if (Directory.Exists(Parameters.appDir))
28+
btnInstall.Content = "Update!";
29+
else
30+
{
31+
btnRemove.IsEnabled = false;
32+
btnRemove.Visibility = Visibility.Hidden;
33+
}
2534

2635
messageQueue = new Queue<string>();
2736
worker = new InstallerWorker(messageQueue);
@@ -64,16 +73,18 @@ private void btnInstall_Click(object sender, RoutedEventArgs e)
6473
{
6574
if (!workerHasFinished)
6675
{
67-
if (InstallerFunctions.GetProcessRunning("WorkingTitle2GSX"))
76+
if (InstallerFunctions.GetProcessRunning(Parameters.appName))
6877
{
69-
MessageBox.Show("Please stop WorkingTitle2GSX and try again.", "WorkingTitle2GSX is running!", MessageBoxButton.OK, MessageBoxImage.Warning);
78+
MessageBox.Show($"Please stop {Parameters.appName} and try again.", $"{Parameters.appName} is running!", MessageBoxButton.OK, MessageBoxImage.Warning);
7079
return;
7180
}
7281

7382
chkDesktopLink_Click(null, null);
7483
radio_Click(null, null);
7584

7685
btnInstall.IsEnabled = false;
86+
btnRemove.Visibility = Visibility.Hidden;
87+
btnRemove.IsEnabled = false;
7788
timer.Start();
7889
Task.Run(worker.Run);
7990
}
@@ -83,6 +94,35 @@ private void btnInstall_Click(object sender, RoutedEventArgs e)
8394
}
8495
}
8596

97+
private void btnRemove_Click(object sender, RoutedEventArgs e)
98+
{
99+
if (InstallerFunctions.GetProcessRunning(Parameters.appName))
100+
{
101+
MessageBox.Show($"Please stop {Parameters.appName} and try again.", $"{Parameters.appName} is running!", MessageBoxButton.OK, MessageBoxImage.Warning);
102+
return;
103+
}
104+
else
105+
{
106+
btnRemove.IsEnabled = false;
107+
btnInstall.IsEnabled = false;
108+
109+
try
110+
{
111+
Directory.Delete(Parameters.appDir, true);
112+
InstallerFunctions.AutoStartExe(true);
113+
InstallerFunctions.AutoStartFsuipc(true);
114+
}
115+
catch (Exception ex)
116+
{
117+
MessageBox.Show($"Exception '{ex.GetType()}' during Uninstall", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
118+
return;
119+
}
120+
121+
lblResult.Content = "REMOVED successfully!";
122+
lblResult.Foreground = new SolidColorBrush(Colors.DarkGreen);
123+
}
124+
}
125+
86126
private void chkDesktopLink_Click(object sender, RoutedEventArgs e)
87127
{
88128
worker.CfgDesktopLink = chkDesktopLink.IsChecked ?? false;
@@ -96,6 +136,8 @@ private void radio_Click(object sender, RoutedEventArgs e)
96136
worker.CfgAutoStart = AutoStart.FSUIPC;
97137
else if (radioExe.IsChecked == true)
98138
worker.CfgAutoStart = AutoStart.EXE;
139+
else if (radioRemove.IsChecked == true)
140+
worker.CfgAutoStart = AutoStart.REMOVE;
99141
}
100142
}
101143
}

0 commit comments

Comments
 (0)