Skip to content
Browse files

Lots of source updates, split the application list item into two files

  • Loading branch information...
1 parent 2040e0d commit a9803782e96d10b58e617e84d91cbc03a2dfa613 @philc committed
Showing with 331 additions and 298 deletions.
  1. +3 −0 InstallPad.csproj
  2. +300 −0 src/ApplicationListItem.Installation.cs
  3. +27 −296 src/ApplicationListItem.cs
  4. +1 −1 src/InstallPad.cs
  5. +0 −1 src/downloader/FileDownloader.cs
View
3 InstallPad.csproj
@@ -55,6 +55,9 @@
<DependentUpon>ApplicationListItem.cs</DependentUpon>
</Compile>
<Compile Include="src\ApplicationList.cs" />
+ <Compile Include="src\ApplicationListItem.Installation.cs">
+ <SubType>UserControl</SubType>
+ </Compile>
<Compile Include="src\AppListErrorDialog.cs">
<SubType>Form</SubType>
</Compile>
View
300 src/ApplicationListItem.Installation.cs
@@ -0,0 +1,300 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+using System.Windows.Forms;
+using CodeProject.Downloader;
+using InstallPad.Properties;
+
+namespace InstallPad
+{
+ public partial class ApplicationListItem
+ {
+ #region Properties
+ public bool Downloading
+ {
+ get { return downloading; }
+ set { downloading = value; }
+ }
+
+ public bool DownloadComplete
+ {
+ get { return downloadComplete; }
+ set { downloadComplete = value; }
+ }
+
+ public bool Installing
+ {
+ get { return this.labelStatus.Text.Contains("Installing"); }
+ }
+ private bool installed = false;
+
+ public bool Installed
+ {
+ get { return installed; }
+ }
+ #endregion
+
+ #region Event we publish
+ public event EventHandler FinishedDownloading;
+ private void OnFinishedDownloading()
+ {
+
+
+ if (this.FinishedDownloading != null)
+ FinishedDownloading(this, new EventArgs());
+ }
+ public event EventHandler FinishedInstalling;
+ private void OnFinishedInstalling()
+ {
+ this.Invoke(new EventHandler(delegate
+ {
+ if (this.installProcess != null && this.installProcess.ExitCode == 0)
+ {
+ this.installed = true;
+ this.labelStatus.Text = "Install finished";
+ RunPostInstallationScript();
+ }
+ else
+ this.labelStatus.Text = "Downloaded";
+
+ MoveControlToTheLeftOf(labelStatus, this.Right);
+ SetInstalLinkText("Install");
+ }));
+
+ if (this.FinishedInstalling != null)
+ FinishedInstalling(this, new EventArgs());
+ }
+ #endregion
+
+ private void RunPostInstallationScript()
+ {
+ if (this.application.Options.PostInstallScript == null)
+ return;
+ try
+ {
+ ProcessStartInfo info = new ProcessStartInfo();
+ info.FileName = application.Options.PostInstallScript;
+ Process p = Process.Start(info);
+ }
+ catch (Exception e)
+ {
+ this.installErrorBox.DetailsText =
+ String.Format("Error running the post install script {0} : {1}",
+ application.Options.PostInstallScript, e.Message);
+ this.installErrorBox.Show();
+ }
+ }
+ void downloader_DownloadComplete(object sender, EventArgs e)
+ {
+ // Update our appearance, let others know we're finished downloading.
+ Debug.WriteLine("download complete.");
+ if (!this.downloading)
+ return;
+
+ this.downloading = false;
+ this.downloadComplete = true;
+
+ this.Invoke(new EventHandler(delegate
+ {
+ this.progressBar.Visible = false;
+ this.labelStatus.Visible = true;
+ this.labelStatus.Text = "Downloaded";
+ MoveControlToTheLeftOf(labelStatus, this.Right);
+ }));
+
+ this.OnFinishedDownloading();
+ }
+
+ private void FinishedDownloadingAfterLinkClicked(object sender, EventArgs e)
+ {
+ // If we finished downloading after they explictly clicked on the "Install"
+ // link, they we should launch the installer
+ this.FinishedDownloading -= LinkClickedDownloadHandler;
+ InstallApplication();
+ }
+ public void Download()
+ {
+ // If we're already downloading this file, ignore this click
+ if (this.Downloading)
+ return;
+ this.downloading = true;
+
+ this.Invoke(new EventHandler(delegate
+ {
+ // Hide any previous errors we might have had
+ this.downloadErrorBox.Visible = false;
+ this.installErrorBox.Visible = false;
+
+ // Update the progress bar with our progress
+ this.progressBar.Visible = true;
+ }));
+
+ // Change "install" to "cancel"
+ SetInstalLinkText("Cancel");
+
+ this.FinishedDownloading += LinkClickedDownloadHandler;
+
+ ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncDownload), null);
+ }
+
+ /// <summary>
+ /// Begins an async download
+ /// </summary>
+ /// <param name="data"></param>
+ private void AsyncDownload(object data)
+ {
+ Exception ex = null;
+ try
+ {
+ String downloadUrl = this.application.FindLatestUrl();
+ downloader.Download(downloadUrl, InstallPadApp.InstallFolder);
+ }
+
+ catch (System.IO.DirectoryNotFoundException e)
+ {
+ ex = e;
+ }
+ catch (Exception e)
+ {
+ ex = e;
+ }
+ if (ex != null)
+ {
+ this.Invoke(new EventHandler(delegate
+ {
+ // Show an error
+ this.downloadErrorBox.Visible = true;
+ this.downloadErrorBox.DetailsText = ex.Message;
+ this.progressBar.Visible = false;
+ this.labelStatus.Visible = false;
+ }));
+ this.Downloading = false;
+ SetInstalLinkText("Install");
+ }
+ }
+
+ /// <summary>
+ /// Installs the application referred to by this app list item.
+ /// </summary>
+ public void InstallApplication()
+ {
+
+ this.Invoke(new EventHandler(delegate
+ {
+ this.labelStatus.Text = "Installing...";
+ this.downloadErrorBox.Visible = false;
+ this.installErrorBox.Visible = false;
+ this.labelProgress.Hide();
+ }));
+
+ // TODO: Should check to make sure the app is downloaded first.
+ ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncInstall), null);
+ }
+
+ private static string ArgumentsForSilentInstall(ApplicationItem application)
+ {
+ // Coding in special rules here for apps. Each of these special rules should be moved
+ // to another class, or a seperate file. Make sure there is a space before the command line arguments.
+
+ // TODO: externalize this information. Put it in a .ini or .config file accessible by users?
+ // Each rule should be on its own line; first, a regex to match the application name, and next to it,
+ // the installer arguments that pertain to that app
+
+ if (application.FileName.ToLower().Contains("firefox"))
+ return "-ms";
+ else if (application.FileName.ToLower().Contains("itunessetup"))
+ {
+ // Args are: /s /v"SILENT_INSTALL=1 ALLUSERS=1 /qb"
+ return "/s /v\"SILENT_INSTALL=1 ALLUSERS=1 /qb\"";
+ }
+ else if (application.FileName.ToLower().Contains("spybot"))
+ {
+ return "/VERYSILENT";
+ }
+ else if (application.FileName.ToLower().Contains("adberdr"))
+ {
+ // Adobe Acrobat Reader. Argh adobe...
+ return "/S /w /v\"/qb-! /norestart EULA_ACCEPT=YES\"";
+ }
+ else
+ // This will work for most installers - /S for nullsoft installers, and -s for InstallShield
+ return "/S -s";
+
+ }
+
+ /// <summary>
+ /// Begin an async install
+ /// </summary>
+ private void AsyncInstall(object data)
+ {
+ this.installed = false;
+
+ ProcessStartInfo psi = new ProcessStartInfo(downloader.DownloadingTo);
+ psi.Arguments = application.Options.InstallerArguments;
+ if (application.Options.SilentInstall || InstallPadApp.AppList.InstallationOptions.SilentInstall)
+ {
+ psi.Arguments = String.Format("{0} {1}",psi.Arguments,ArgumentsForSilentInstall(application));
+ }
+
+ installProcess = new Process();
+
+ installProcess.StartInfo = psi;
+ installProcess.EnableRaisingEvents = true;
+ installProcess.Exited += new EventHandler(process_Exited);
+
+ Exception ex = null;
+ try
+ {
+ installProcess.Start();
+ }
+ catch (Exception e)
+ {
+ ex = e;
+ }
+ if (ex != null)
+ {
+ this.installProcess = null;
+ this.Invoke(new EventHandler(delegate
+ {
+ // Show an error
+ installErrorBox.DetailsText = String.Format("Couldn't install {0} : {1}",
+ downloader.DownloadingTo, ex.Message);
+ installErrorBox.Visible = true;
+ }));
+
+ SetInstalLinkText("Install");
+
+ // We're done running the installer..
+ OnFinishedInstalling();
+ }
+ }
+ void downloader_ProgressChanged(object sender, CodeProject.Downloader.DownloadEventArgs e)
+ {
+ // Sometimes we may get events fired even after we're done downloading.
+ // Don't react to them.
+ if (!this.Downloading)
+ return;
+ this.Invoke(new EventHandler(delegate
+ {
+ if (e.PercentDone <= 100)
+ {
+ this.progressBar.Value = e.PercentDone;
+ UpdateProgressLabel(e);
+ }
+ }));
+
+ }
+
+
+ void process_Exited(object sender, EventArgs e)
+ {
+ OnFinishedInstalling();
+ }
+
+ }
+}
View
323 src/ApplicationListItem.cs
@@ -24,7 +24,8 @@
namespace InstallPad
{
/// <summary>
- /// A list item, one for each app. Each app can be in the state of:
+ /// A list item to be displayed in a ControList, one for each application.
+ /// Each app can be in one of the following states:
/// downloading, downloaded, installing, installed, or none of those.
/// </summary>
public partial class ApplicationListItem : UserControl
@@ -48,34 +49,7 @@ public partial class ApplicationListItem : UserControl
private bool downloading = false;
#region Properties
- public bool Downloading
- {
- get { return downloading; }
- set { downloading = value; }
- }
- public bool DownloadComplete
- {
- get { return downloadComplete; }
- set { downloadComplete = value; }
- }
-
- // Value of the "enabled" check box
- private bool enabledCheck = true;
-
- public bool EnabledCheck
- {
- get { return enabledCheck; }
- set
- {
- enabledCheck = value;
- OnEnabledCheckChanged();
- }
- }
- public bool Installing
- {
- get { return this.labelStatus.Text.Contains("Installing"); }
- }
/// <summary>
@@ -86,72 +60,11 @@ public bool Checked
get { return this.checkboxEnabled.Checked; }
}
- private bool installed = false;
-
- public bool Installed
- {
- get { return installed; }
- }
#endregion
- #region Events
- public event EventHandler EnabledCheckChanged;
- private void OnEnabledCheckChanged()
- {
- this.enabledCheck = true;
- if (this.EnabledCheckChanged != null)
- EnabledCheckChanged(this, new EventArgs());
- }
-
- public event EventHandler FinishedDownloading;
- private void OnFinishedDownloading()
- {
-
-
- if (this.FinishedDownloading != null)
- FinishedDownloading(this, new EventArgs());
- }
- public event EventHandler FinishedInstalling;
- private void OnFinishedInstalling()
- {
- this.Invoke(new EventHandler(delegate
- {
- if (this.installProcess != null && this.installProcess.ExitCode == 0)
- {
- this.installed = true;
- this.labelStatus.Text = "Install finished";
- RunPostInstallationScript();
- }
- else
- this.labelStatus.Text = "Downloaded";
-
- MoveControlToTheLeftOf(labelStatus, this.Right);
- SetInstalLinkText("Install");
- }));
- if (this.FinishedInstalling != null)
- FinishedInstalling(this, new EventArgs());
- }
- #endregion
- private void RunPostInstallationScript()
- {
- if (this.application.Options.PostInstallScript == null)
- return;
- try
- {
- ProcessStartInfo info = new ProcessStartInfo();
- info.FileName = application.Options.PostInstallScript;
- Process p = Process.Start(info);
- }
- catch (Exception e)
- {
- this.installErrorBox.DetailsText =
- String.Format("Error running the post install script {0} : {1}",
- application.Options.PostInstallScript, e.Message);
- this.installErrorBox.Show();
- }
- }
+
public ApplicationListItem()
{
InitializeComponent();
@@ -175,11 +88,11 @@ public ApplicationListItem(ApplicationItem application)
{
this.ApplicationItem = application;
this.LinkClickedDownloadHandler = new EventHandler(this.FinishedDownloadingAfterLinkClicked);
-
+
this.Controls.Add(downloadErrorBox);
AddErrorBoxes();
-
+
downloader = new FileDownloader();
ProxyOptions options = InstallPadApp.AppList.InstallationOptions.ProxyOptions;
@@ -217,38 +130,13 @@ private void AddErrorBoxes()
- void downloader_DownloadComplete(object sender, EventArgs e)
- {
- // Update our appearance, let others know we're finished downloading.
- Debug.WriteLine("download complete.");
- if (!this.downloading)
- return;
-
- this.downloading = false;
- this.downloadComplete = true;
-
- this.Invoke(new EventHandler(delegate
- {
- this.progressBar.Visible = false;
- this.labelStatus.Visible = true;
- this.labelStatus.Text = "Downloaded";
- MoveControlToTheLeftOf(labelStatus, this.Right);
- }));
-
- this.OnFinishedDownloading();
- }
-
- private void FinishedDownloadingAfterLinkClicked(object sender, EventArgs e){
- // If we finished downloading after they explictly clicked on the "Install"
- // link, they we should launch the installer
- this.FinishedDownloading -= LinkClickedDownloadHandler;
- InstallApplication();
- }
+
private void installLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
-
- if (this.installLink.Text=="Install"){
+
+ if (this.installLink.Text == "Install")
+ {
Download();
}
else if (this.installLink.Text == "Cancel")
@@ -263,18 +151,17 @@ private void installLink_LinkClicked(object sender, LinkLabelLinkClickedEventArg
this.progressBar.Hide();
this.labelProgress.Hide();
}
- else if (installProcess!=null)
+ else if (installProcess != null)
{
try
{
// The installer is running. Close the installer.
- //if (!installProcess.HasExited)
- installProcess.Kill();
+ installProcess.Kill();
}
catch (InvalidOperationException)
{
// If the process has already exited by this time, we might get an exception
- // trying to kill it
+ // trying to kill it. Ignore
}
}
SetInstalLinkText("Install");
@@ -282,63 +169,9 @@ private void installLink_LinkClicked(object sender, LinkLabelLinkClickedEventArg
}
- public void Download()
- {
- // If we're already downloading this file, ignore this click
- if (this.Downloading)
- return;
- this.downloading = true;
-
- this.Invoke(new EventHandler(delegate
- {
- // Hide any previous errors we might have had
- this.downloadErrorBox.Visible = false;
- this.installErrorBox.Visible = false;
-
- // Update the progress bar with our progress
- this.progressBar.Visible = true;
- }));
-
- // Change "install" to "cancel"
- SetInstalLinkText("Cancel");
+
- // TODO: should this link clicked handler be used? It will start the install after the download finishes..
- this.FinishedDownloading += LinkClickedDownloadHandler;
-
- ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncDownload), null);
-
- }
- private void AsyncDownload(object data)
- {
- Exception ex = null;
- try
- {
- String downloadUrl = this.application.FindLatestUrl();
- downloader.Download(downloadUrl, InstallPadApp.InstallFolder);
- }
-
- catch (System.IO.DirectoryNotFoundException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- ex = e;
- }
- if (ex != null)
- {
- this.Invoke(new EventHandler(delegate
- {
- // Show an error
- this.downloadErrorBox.Visible = true;
- this.downloadErrorBox.DetailsText = ex.Message;
- this.progressBar.Visible = false;
- this.labelStatus.Visible = false;
- }));
- this.Downloading = false;
- SetInstalLinkText("Install");
- }
- }
+
private void SetInstalLinkText(string s)
{
@@ -347,142 +180,43 @@ private void SetInstalLinkText(string s)
this.installLink.Text = s;
MoveControlToTheLeftOf(installLink, this.Right);
}));
- }
-
-
- public void InstallApplication()
- {
-
- this.Invoke(new EventHandler(delegate
- {
- this.labelStatus.Text = "Installing...";
- this.downloadErrorBox.Visible = false;
- this.installErrorBox.Visible = false;
- this.labelProgress.Hide();
- }));
-
- // Should check to make sure the app is downloaded.
- ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncInstall), null);
}
- private void AsyncInstall(object data)
- {
- Debug.WriteLine("Async install.");
- this.installed = false;
-
- ProcessStartInfo psi = new ProcessStartInfo(downloader.DownloadingTo);
- psi.Arguments = application.Options.InstallerArguments;
- if (application.Options.SilentInstall || InstallPadApp.AppList.InstallationOptions.SilentInstall)
- {
- // Coding in special rules here for apps. Each of these special rules should be moved
- // to another class, or a seperate file. Make sure there is a space before the command line arguments.
- // TODO: externalize this information.
- if (application.FileName.ToLower().Contains("firefox"))
- psi.Arguments=psi.Arguments + " -ms";
- else if (application.FileName.ToLower().Contains("itunessetup")){
- // Args are: /s /v"SILENT_INSTALL=1 ALLUSERS=1 /qb"
- psi.Arguments = psi.Arguments + " /s /v\"SILENT_INSTALL=1 ALLUSERS=1 /qb\"";
- }else if (application.FileName.ToLower().Contains("spybot")){
- psi.Arguments = psi.Arguments + " /VERYSILENT";
-
- }else if (application.FileName.ToLower().Contains("adberdr")){
- // Adobe Acrobat Reader. Argh adobe...
- psi.Arguments = psi.Arguments +
- " /S /w /v\"/qb-! /norestart EULA_ACCEPT=YES\"";
- }
- else
- // This will work for most installers - /S for nullsoft installers, and -s for InstallShield
- psi.Arguments = psi.Arguments + " /S -s";
- }
-
- installProcess = new Process();
- installProcess.StartInfo = psi;
- installProcess.EnableRaisingEvents = true;
- installProcess.Exited += new EventHandler(process_Exited);
+
- Exception ex = null;
- try
- {
- installProcess.Start();
- }
- catch (Exception e)
- {
- ex = e;
- }
- if (ex != null)
- {
- this.installProcess = null;
- this.Invoke(new EventHandler(delegate
- {
- // Show an error
- installErrorBox.DetailsText = String.Format("Couldn't install {0} : {1}",
- downloader.DownloadingTo, ex.Message);
- installErrorBox.Visible = true;
- //this.labelStatus.Visible = false;
- }));
- SetInstalLinkText("Install");
- // We're done running the installer..
- OnFinishedInstalling();
- }
- //p.WaitForExit();
- }
-
- void downloader_ProgressChanged(object sender, DownloadEventArgs e)
- {
- // Sometimes we may get events fired even after we're done downloading.
- // Don't react to them.
- if (!this.Downloading)
- return;
- this.Invoke(new EventHandler(delegate
- {
- if (e.PercentDone <= 100)
- {
- this.progressBar.Value = e.PercentDone;
- UpdateProgressLabel(e);
- }
- }));
- //Debug.WriteLine(e.PercentDone);
- }
/// <summary>
/// Sets the text of a label that's right aligned to the control; the control
/// is then repositioned so it's a constant width from the right side of the
/// control, even after the text changes.
/// </summary>
- private void MoveControlToTheLeftOf(Control control,int point){
+ private void MoveControlToTheLeftOf(Control control, int point)
+ {
control.Left = point - control.Width - labelDistanceFromRight;
}
private void UpdateProgressLabel(DownloadEventArgs e)
- {
+ {
// If the total file size is 0, then the downloader doesn't know its progress. Might as well not show it
if (e.TotalFileSize == 0 && e.CurrentFileSize == 0)
this.labelProgress.Visible = false;
- else{
+ else
+ {
this.labelProgress.Visible = true;
this.labelProgress.Text = DownloadProgressString.ProgressString(e.CurrentFileSize, e.TotalFileSize);
MoveControlToTheLeftOf(labelProgress, this.progressBar.Left);
- //this.progressBar);
}
}
-
- void process_Exited(object sender, EventArgs e)
- {
- OnFinishedInstalling();
-
- }
-
private void checkboxEnabled_CheckedChanged(object sender, EventArgs e)
{
-
}
}
/// <summary>
- /// This class has utility methods to process and format a progress string
+ /// Utility methods to process and format a progress string
/// given current and total bytes in a download. Used for UI display
/// </summary>
class DownloadProgressString
@@ -497,16 +231,16 @@ public static string ProgressString(long current, long total)//, long totalBytes
// If we don't know the total, then just return the current
if (totalk <= 0)
{
- if (currentk <=0)
+ if (currentk <= 0)
return "0K";
- else if (currentk<1000)
+ else if (currentk < 1000)
return currentk + "K";
- else
+ else
return InMegabytes(current).ToString("N1") + "MB";
}
-
- if (totalk<1000)
- return String.Format("{0} of {1} KB",currentk,totalk);
+
+ if (totalk < 1000)
+ return String.Format("{0} of {1} KB", currentk, totalk);
else
return String.Format("{0} of {1} MB", MegabyteString(InMegabytes(current)),
MegabyteString(InMegabytes(total)));
@@ -521,11 +255,8 @@ private static string MegabyteString(double mb)
}
private static double InMegabytes(long bytes)
{
- // TODO: need to reduce the number of decimal digits here. Can be 1.6123123 etc.
long k = InKilobytes(bytes);
- //return (k < 1000) ? 0 : ((double)k) / 1000;
return ((double)k) / 1000;
-
}
private static long InKilobytes(long bytes)
{
View
2 src/InstallPad.cs
@@ -332,7 +332,7 @@ private void SetControlsEnabled(bool enabled)
void controlList_Resize(object sender, EventArgs e)
{
- if (appListErrorBox.Visible)
+ if (appListErrorBox!=null && appListErrorBox.Visible)
UpdateErrorBoxLocation();
}
/// <summary>
View
1 src/downloader/FileDownloader.cs
@@ -365,7 +365,6 @@ private WebRequest GetRequest(string url)
{
request.Credentials = CredentialCache.DefaultCredentials;
Uri result = request.Proxy.GetProxy(new Uri("http://www.google.com"));
- int a = 5;
}
if (this.proxy != null)

0 comments on commit a980378

Please sign in to comment.
Something went wrong with that request. Please try again.