Permalink
Browse files

Bootstrapper no longer requires running installer again after .NET 3.…

…5 installer finishes

Bootstrapper adds installer to RunOnce entry of registry if .NET 3.5 installer requires a reboot after installing


git-svn-id: https://videobrowser.googlecode.com/svn/trunk@1097 096cc86f-8a4c-0410-9b85-8b5e0eee1c45
  • Loading branch information...
1 parent 1b17ece commit 1a75b10907034d6b21f6ae6a313b92a0558e30cd ogre@chaocracy.net committed May 14, 2009
Showing with 85 additions and 10 deletions.
  1. +22 −4 Bootstrapper/App.cs
  2. +22 −0 Bootstrapper/App.manifest
  3. +2 −0 Bootstrapper/Bootsrapper.csproj
  4. +39 −6 Bootstrapper/Main.xaml.cs
View
@@ -19,19 +19,22 @@ public class App : Application{
public static void Main() {
if (IsDotNet35Installed())
+ {
LaunchInstaller();
- else {
-
+ }
+ else
+ {
var app = new Bootstrapper.App();
var main = new Main();
main.Show();
app.Run(main);
+ //AddToRunOnce();
}
}
public static bool IsDotNet35Installed() {
RegistryKey key = Registry.LocalMachine;
- using (key = key.OpenSubKey(@"Software\Microsoft\NET Framework Setup\NDP\v3.5\1033"))
+ using (key = key.OpenSubKey(@"Software\Microsoft\NET Framework Setup\NDP\v3.5"))
{
return (key != null);
}
@@ -45,7 +48,7 @@ public static void LaunchInstaller()
}
public static string ExtractInstaller() {
- var tempfile = Path.Combine(Path.GetTempPath(), "MediaBrowser.msi"); ;
+ var tempfile = Path.Combine(Path.GetTempPath(), "MediaBrowser.msi");
var name = "Bootstrapper.MediaBrowser.msi.gz";
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
@@ -55,6 +58,21 @@ public static void LaunchInstaller()
return tempfile;
}
+ public static void AddToRunOnce()
+ {
+ try
+ {
+ RegistryKey key = Registry.LocalMachine;
+ using (key = key.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\RunOnce", true))
+ {
+ key.SetValue("MediaBrowser", Assembly.GetExecutingAssembly().Location, RegistryValueKind.String);
+ }
+ }
+ catch (Exception e)
+ {
+ MessageBox.Show(e.StackTrace, e.Message);
+ }
+ }
// from http://www.yoda.arachsys.com/csharp/readbinary.html
private static byte[] ReadStream(Stream stream, int initialLength) {
View
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <assemblyIdentity version="1.0.0.0" name="Bootstrapper.app"/>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+ <!-- UAC Manifest Options
+ If you want to change the Windows User Account Control level replace the
+ requestedExecutionLevel node with one of the following.
+
+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
+ <requestedExecutionLevel level="highestAvailable" uiAccess="false" />
+
+ If you want to utilize File and Registry Virtualization for backward
+ compatibility then delete the requestedExecutionLevel node.
+ -->
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</asmv1:assembly>
@@ -15,6 +15,7 @@
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<ApplicationIcon>install.ico</ApplicationIcon>
+ <ApplicationManifest>App.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -80,6 +81,7 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="MediaBrowser.msi.gz" />
+ <EmbeddedResource Include="App.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
View
@@ -27,6 +27,8 @@ namespace Bootstrapper {
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Main : Window {
+ Process _dotNetInstaller = null;
+
public Main() {
InitializeComponent();
message.Text = "";
@@ -72,18 +74,49 @@ class RequestState {
}
SetMaxProgress(100);
- try {
- Process p = Process.Start(tempFile, "");
- } catch {
+ try
+ {
+ _dotNetInstaller = new Process();
+ _dotNetInstaller.StartInfo.FileName = tempFile;
+ _dotNetInstaller.EnableRaisingEvents = true;
+ _dotNetInstaller.Exited += new EventHandler(dotNetInstaller_Exited);
+ _dotNetInstaller.Start();
+ }
+ catch
+ {
// if UAC is no accepted we will find ourselves here
- Dispatcher.Invoke(DispatcherPriority.Normal, (MethodInvoker)delegate() {
+ Dispatcher.Invoke(DispatcherPriority.Normal, (MethodInvoker)delegate()
+ {
MessageBox.Show("Failed to Launch Installer, you really are going to have to accept that UAC message.");
});
+ Dispatcher.Invoke(DispatcherPriority.Normal, (MethodInvoker)delegate()
+ {
+ this.Close();
+ });
+ return;
}
- Dispatcher.Invoke(DispatcherPriority.Normal, (MethodInvoker)delegate() {
- this.Close();
+ Dispatcher.Invoke(DispatcherPriority.Normal, (MethodInvoker)delegate()
+ {
+ this.Hide();
});
+ }
+ private void dotNetInstaller_Exited(object sender, EventArgs e)
+ {
+ int exitCode = _dotNetInstaller.ExitCode;
+ // TODO: We really should be checking for more error codes
+ if (exitCode == 3010)
+ {
+ App.AddToRunOnce();
+ }
+ else
+ {
+ App.LaunchInstaller();
+ }
+ Dispatcher.Invoke(DispatcherPriority.Normal, (MethodInvoker)delegate()
+ {
+ this.Close();
+ });
}
private bool IsBackgroundThread {

0 comments on commit 1a75b10

Please sign in to comment.