Added bit.ly support for distiributives download; Updated year in copyright text;
This commit is contained in:
parent
8b7b150da7
commit
2dc3ced5cf
12 changed files with 1210 additions and 955 deletions
|
@ -63,6 +63,24 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_5FD334A6C47943FA9A98232EA921C90B"
|
||||||
|
"OwnerKey" = "8:_05F59A142DD147798C90054A203C0EE9"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
|
"MsmKey" = "8:_5FD334A6C47943FA9A98232EA921C90B"
|
||||||
|
"OwnerKey" = "8:_1239E87E938248B1BAF9BF75C32D3EDC"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
|
"MsmKey" = "8:_5FD334A6C47943FA9A98232EA921C90B"
|
||||||
|
"OwnerKey" = "8:_CFB0AE8275767700870555C8CDA92C96"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_BD9DC4338DFD4472BE5D099C388608B6"
|
"MsmKey" = "8:_BD9DC4338DFD4472BE5D099C388608B6"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -294,6 +312,37 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"IsolateTo" = "8:"
|
||||||
}
|
}
|
||||||
|
"{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_5FD334A6C47943FA9A98232EA921C90B"
|
||||||
|
{
|
||||||
|
"AssemblyRegister" = "3:1"
|
||||||
|
"AssemblyIsInGAC" = "11:FALSE"
|
||||||
|
"AssemblyAsmDisplayName" = "8:Ionic.Zip.Reduced, Version=1.8.4.28, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL"
|
||||||
|
"ScatterAssemblies"
|
||||||
|
{
|
||||||
|
"_5FD334A6C47943FA9A98232EA921C90B"
|
||||||
|
{
|
||||||
|
"Name" = "8:Ionic.Zip.Reduced.dll"
|
||||||
|
"Attributes" = "3:512"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"SourcePath" = "8:Ionic.Zip.Reduced.dll"
|
||||||
|
"TargetName" = "8:"
|
||||||
|
"Tag" = "8:"
|
||||||
|
"Folder" = "8:_E742E59BFE4D43C59AA65A07792B89FB"
|
||||||
|
"Condition" = "8:"
|
||||||
|
"Transitive" = "11:FALSE"
|
||||||
|
"Vital" = "11:TRUE"
|
||||||
|
"ReadOnly" = "11:FALSE"
|
||||||
|
"Hidden" = "11:FALSE"
|
||||||
|
"System" = "11:FALSE"
|
||||||
|
"Permanent" = "11:FALSE"
|
||||||
|
"SharedLegacy" = "11:FALSE"
|
||||||
|
"PackageAs" = "3:1"
|
||||||
|
"Register" = "3:1"
|
||||||
|
"Exclude" = "11:FALSE"
|
||||||
|
"IsDependency" = "11:TRUE"
|
||||||
|
"IsolateTo" = "8:"
|
||||||
|
}
|
||||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BD9DC4338DFD4472BE5D099C388608B6"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BD9DC4338DFD4472BE5D099C388608B6"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:Banner.bmp"
|
"SourcePath" = "8:Banner.bmp"
|
||||||
|
@ -407,15 +456,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:WebsitePanel Installer"
|
"ProductName" = "8:WebsitePanel Installer"
|
||||||
"ProductCode" = "8:{09BCDF68-1964-4FC6-9570-9AB3B8512CF6}"
|
"ProductCode" = "8:{A22F374C-4AFC-4B5D-A509-7456A6107588}"
|
||||||
"PackageCode" = "8:{D94FF2E6-1D7D-4E33-8528-C7B6BFADEC99}"
|
"PackageCode" = "8:{401F157D-6D55-4F66-A2C6-419F87BBF97D}"
|
||||||
"UpgradeCode" = "8:{2950A907-11E7-436C-86CE-049C414AFD08}"
|
"UpgradeCode" = "8:{2950A907-11E7-436C-86CE-049C414AFD08}"
|
||||||
"AspNetVersion" = "8:4.0.30319.0"
|
"AspNetVersion" = "8:4.0.30319.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:FALSE"
|
"RemovePreviousVersions" = "11:FALSE"
|
||||||
"DetectNewerInstalledVersion" = "11:FALSE"
|
"DetectNewerInstalledVersion" = "11:FALSE"
|
||||||
"InstallAllUsers" = "11:TRUE"
|
"InstallAllUsers" = "11:TRUE"
|
||||||
"ProductVersion" = "8:1.2.0"
|
"ProductVersion" = "8:1.2.1"
|
||||||
"Manufacturer" = "8:Outercurve Foundation"
|
"Manufacturer" = "8:Outercurve Foundation"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -35,7 +35,7 @@ using System.Reflection;
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyCompany("Outercurve Foundation")]
|
[assembly: AssemblyCompany("Outercurve Foundation")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2011 Outercurve Foundation.")]
|
[assembly: AssemblyCopyright("Copyright © 2012 Outercurve Foundation.")]
|
||||||
[assembly: AssemblyVersion("1.2.0.0")]
|
[assembly: AssemblyVersion("1.2.1.0")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0.38")]
|
[assembly: AssemblyFileVersion("1.2.1.0")]
|
||||||
[assembly: AssemblyInformationalVersion("1.2.0")]
|
[assembly: AssemblyInformationalVersion("1.2.1")]
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -34,43 +34,43 @@ using System.IO;
|
||||||
namespace WebsitePanel.Installer.Common
|
namespace WebsitePanel.Installer.Common
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// File utils.
|
/// File utils.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class FileUtils
|
public sealed class FileUtils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the class.
|
/// Initializes a new instance of the class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private FileUtils()
|
private FileUtils()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates drectory with the specified directory.
|
/// Creates drectory with the specified directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The directory path to create.</param>
|
/// <param name="path">The directory path to create.</param>
|
||||||
public static void CreateDirectory(string path)
|
public static void CreateDirectory(string path)
|
||||||
{
|
{
|
||||||
string dir = Path.GetDirectoryName(path);
|
string dir = Path.GetDirectoryName(path);
|
||||||
if(!Directory.Exists(dir))
|
if(!Directory.Exists(dir))
|
||||||
{
|
{
|
||||||
// create directory structure
|
// create directory structure
|
||||||
Directory.CreateDirectory(dir);
|
Directory.CreateDirectory(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves file content.
|
/// Saves file content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">File name.</param>
|
/// <param name="fileName">File name.</param>
|
||||||
/// <param name="content">The array of bytes to write.</param>
|
/// <param name="content">The array of bytes to write.</param>
|
||||||
public static void SaveFileContent(string fileName, byte[] content)
|
public static void SaveFileContent(string fileName, byte[] content)
|
||||||
{
|
{
|
||||||
FileStream stream = new FileStream(fileName, FileMode.Create);
|
FileStream stream = new FileStream(fileName, FileMode.Create);
|
||||||
stream.Write(content, 0, content.Length);
|
stream.Write(content, 0, content.Length);
|
||||||
stream.Close();
|
stream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves file content.
|
/// Saves file content.
|
||||||
|
@ -84,188 +84,203 @@ namespace WebsitePanel.Installer.Common
|
||||||
stream.Close();
|
stream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified file.
|
/// Deletes the specified file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">The name of the file to be deleted.</param>
|
/// <param name="fileName">The name of the file to be deleted.</param>
|
||||||
public static void DeleteFile(string fileName)
|
public static void DeleteFile(string fileName)
|
||||||
{
|
{
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DeleteFileInternal(fileName);
|
DeleteFileInternal(fileName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
if (attempts > 2)
|
if (attempts > 2)
|
||||||
throw;
|
throw;
|
||||||
|
|
||||||
attempts++;
|
attempts++;
|
||||||
System.Threading.Thread.Sleep(1000);
|
System.Threading.Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified file.
|
/// Deletes the specified file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">The name of the file to be deleted.</param>
|
/// <param name="fileName">The name of the file to be deleted.</param>
|
||||||
private static void DeleteReadOnlyFile(string fileName)
|
private static void DeleteReadOnlyFile(string fileName)
|
||||||
{
|
{
|
||||||
FileInfo info = new FileInfo(fileName);
|
FileInfo info = new FileInfo(fileName);
|
||||||
info.Attributes = FileAttributes.Normal;
|
info.Attributes = FileAttributes.Normal;
|
||||||
info.Delete();
|
info.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified file.
|
/// Deletes the specified file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">The name of the file to be deleted.</param>
|
/// <param name="fileName">The name of the file to be deleted.</param>
|
||||||
private static void DeleteFileInternal(string fileName)
|
private static void DeleteFileInternal(string fileName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Delete(fileName);
|
File.Delete(fileName);
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException)
|
catch (UnauthorizedAccessException)
|
||||||
{
|
{
|
||||||
DeleteReadOnlyFile(fileName);
|
DeleteReadOnlyFile(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified directory.
|
/// Deletes the specified directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="directory">The name of the directory to be deleted.</param>
|
/// <param name="directory">The name of the directory to be deleted.</param>
|
||||||
public static void DeleteDirectory(string directory)
|
public static void DeleteDirectory(string directory)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// iterate through child folders
|
// iterate through child folders
|
||||||
string[] dirs = Directory.GetDirectories(directory);
|
string[] dirs = Directory.GetDirectories(directory);
|
||||||
foreach (string dir in dirs)
|
foreach (string dir in dirs)
|
||||||
{
|
{
|
||||||
DeleteDirectory(dir);
|
DeleteDirectory(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate through child files
|
// iterate through child files
|
||||||
string[] files = Directory.GetFiles(directory);
|
string[] files = Directory.GetFiles(directory);
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
DeleteFile(file);
|
DeleteFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to delete dir for 3 times
|
//try to delete dir for 3 times
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DeleteDirectoryInternal(directory);
|
DeleteDirectoryInternal(directory);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
if (attempts > 2)
|
if (attempts > 2)
|
||||||
throw;
|
throw;
|
||||||
|
|
||||||
attempts++;
|
attempts++;
|
||||||
System.Threading.Thread.Sleep(1000);
|
System.Threading.Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified directory.
|
/// Deletes the specified directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="directory">The name of the directory to be deleted.</param>
|
/// <param name="directory">The name of the directory to be deleted.</param>
|
||||||
private static void DeleteDirectoryInternal(string directory)
|
private static void DeleteDirectoryInternal(string directory)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.Delete(directory);
|
Directory.Delete(directory);
|
||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
DeleteReadOnlyDirectory(directory);
|
DeleteReadOnlyDirectory(directory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the specified directory.
|
/// Deletes the specified directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="directory">The name of the directory to be deleted.</param>
|
/// <param name="directory">The name of the directory to be deleted.</param>
|
||||||
private static void DeleteReadOnlyDirectory(string directory)
|
private static void DeleteReadOnlyDirectory(string directory)
|
||||||
{
|
{
|
||||||
DirectoryInfo info = new DirectoryInfo(directory);
|
DirectoryInfo info = new DirectoryInfo(directory);
|
||||||
info.Attributes = FileAttributes.Normal;
|
info.Attributes = FileAttributes.Normal;
|
||||||
info.Delete();
|
info.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified file exists.
|
/// Determines whether the specified file exists.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">The path to check.</param>
|
/// <param name="fileName">The path to check.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool FileExists(string fileName)
|
public static bool FileExists(string fileName)
|
||||||
{
|
{
|
||||||
return File.Exists(fileName);
|
return File.Exists(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the given path refers to an existing directory on disk.
|
/// Determines whether the given path refers to an existing directory on disk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path to test.</param>
|
/// <param name="path">The path to test.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool DirectoryExists(string path)
|
public static bool DirectoryExists(string path)
|
||||||
{
|
{
|
||||||
return Directory.Exists(path);
|
return Directory.Exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns current application path.
|
/// Returns current application path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Curent application path.</returns>
|
/// <returns>Curent application path.</returns>
|
||||||
public static string GetCurrentDirectory()
|
public static string GetCurrentDirectory()
|
||||||
{
|
{
|
||||||
return AppDomain.CurrentDomain.BaseDirectory;
|
return AppDomain.CurrentDomain.BaseDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns application temp directory.
|
/// Returns application temp directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Application temp directory.</returns>
|
/// <returns>Application temp directory.</returns>
|
||||||
public static string GetTempDirectory()
|
public static string GetTempDirectory()
|
||||||
{
|
{
|
||||||
return Path.Combine(GetCurrentDirectory(), "Tmp");
|
return Path.Combine(GetCurrentDirectory(), "Tmp");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns application data directory.
|
/// Returns application data directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Application data directory.</returns>
|
/// <returns>Application data directory.</returns>
|
||||||
public static string GetDataDirectory()
|
public static string GetDataDirectory()
|
||||||
{
|
{
|
||||||
return Path.Combine(GetCurrentDirectory(), "Data");
|
return Path.Combine(GetCurrentDirectory(), "Data");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes application temp directory.
|
/// Deletes application's Data folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void DeleteTempDirectory()
|
public static void DeleteDataDirectory()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DeleteDirectory(GetTempDirectory());
|
DeleteDirectory(GetDataDirectory());
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.WriteError("IO Error", ex);
|
Log.WriteError("IO Error", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes application Tmp directory.
|
||||||
|
/// </summary>
|
||||||
|
public static void DeleteTempDirectory()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DeleteDirectory(GetTempDirectory());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.WriteError("IO Error", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -45,6 +45,7 @@ using System.Threading;
|
||||||
using WebsitePanel.Installer.Core;
|
using WebsitePanel.Installer.Core;
|
||||||
using WebsitePanel.Installer.Configuration;
|
using WebsitePanel.Installer.Configuration;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
namespace WebsitePanel.Installer.Common
|
namespace WebsitePanel.Installer.Common
|
||||||
{
|
{
|
||||||
|
@ -389,5 +390,23 @@ namespace WebsitePanel.Installer.Common
|
||||||
mutex = new Mutex(true, "WebsitePanel Installer", out createdNew);
|
mutex = new Mutex(true, "WebsitePanel Installer", out createdNew);
|
||||||
return createdNew;
|
return createdNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetDistributiveLocationInfo(string ccode, string cversion)
|
||||||
|
{
|
||||||
|
var service = ServiceProviderProxy.GetInstallerWebService();
|
||||||
|
//
|
||||||
|
DataSet ds = service.GetReleaseFileInfo(ccode, cversion);
|
||||||
|
//
|
||||||
|
if (ds == null || ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0)
|
||||||
|
{
|
||||||
|
Log.WriteInfo("Component code: {0}; Component version: {1};", ccode, cversion);
|
||||||
|
//
|
||||||
|
throw new ServiceComponentNotFoundException("Seems that the Service has no idea about the component requested.");
|
||||||
|
}
|
||||||
|
//
|
||||||
|
DataRow row = ds.Tables[0].Rows[0];
|
||||||
|
//
|
||||||
|
return row["FullFilePath"].ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -36,380 +36,495 @@ using System.Text;
|
||||||
using Ionic.Zip;
|
using Ionic.Zip;
|
||||||
|
|
||||||
using WebsitePanel.Installer.Common;
|
using WebsitePanel.Installer.Common;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace WebsitePanel.Installer.Core
|
namespace WebsitePanel.Installer.Core
|
||||||
{
|
{
|
||||||
public class LoaderEventArgs<T> : EventArgs
|
public class LoaderEventArgs<T> : EventArgs
|
||||||
{
|
{
|
||||||
public string StatusMessage { get; set; }
|
public string StatusMessage { get; set; }
|
||||||
public T EventData { get; set; }
|
public T EventData { get; set; }
|
||||||
public bool Cancellable { get; set; }
|
public bool Cancellable { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static class LoaderFactory
|
||||||
/// Loader form.
|
{
|
||||||
/// </summary>
|
/// <summary>
|
||||||
public partial class Loader
|
/// Instantiates either BitlyLoader or InstallerServiceLoader based on remote file format.
|
||||||
{
|
/// </summary>
|
||||||
public const string ConnectingRemotServiceMessage = "Connecting...";
|
/// <param name="remoteFile"></param>
|
||||||
public const string DownloadingSetupFilesMessage = "Downloading setup files...";
|
/// <returns></returns>
|
||||||
public const string CopyingSetupFilesMessage = "Copying setup files...";
|
public static Loader CreateFileLoader(string remoteFile)
|
||||||
public const string PreparingSetupFilesMessage = "Please wait while Setup prepares the necessary files...";
|
{
|
||||||
public const string DownloadProgressMessage = "{0} KB of {1} KB";
|
Debug.Assert(!String.IsNullOrEmpty(remoteFile), "Remote file is empty");
|
||||||
public const string PrepareSetupProgressMessage = "{0}%";
|
|
||||||
|
|
||||||
private const int ChunkSize = 262144;
|
if (remoteFile.StartsWith("http://bit.ly/"))
|
||||||
private Thread thread;
|
{
|
||||||
private string localFile;
|
return new BitlyLoader(remoteFile);
|
||||||
private string remoteFile;
|
}
|
||||||
private string componentCode;
|
else
|
||||||
private string version;
|
{
|
||||||
|
return new Loader(remoteFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public event EventHandler<LoaderEventArgs<String>> StatusChanged;
|
public class BitlyLoader : Loader
|
||||||
public event EventHandler<LoaderEventArgs<Exception>> OperationFailed;
|
{
|
||||||
public event EventHandler<LoaderEventArgs<Int32>> ProgressChanged;
|
public const string WEB_PI_USER_AGENT_HEADER = "PI-Integrator/3.0.0.0({0})";
|
||||||
public event EventHandler<EventArgs> OperationCompleted;
|
|
||||||
|
|
||||||
public Loader(string remoteFile)
|
private WebClient fileLoader;
|
||||||
{
|
|
||||||
this.remoteFile = remoteFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Loader(string localFile, string componentCode, string version)
|
public BitlyLoader(string remoteFile)
|
||||||
{
|
: base(remoteFile)
|
||||||
this.localFile = localFile;
|
{
|
||||||
this.componentCode = componentCode;
|
InitFileLoader();
|
||||||
this.version = version;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadAppDistributive()
|
private void InitFileLoader()
|
||||||
{
|
{
|
||||||
thread = new Thread(new ThreadStart(LoadAppDistributiveInternal));
|
fileLoader = new WebClient();
|
||||||
thread.Start();
|
// Set HTTP header for Codeplex to allow direct downloads
|
||||||
}
|
fileLoader.Headers.Add("User-Agent", String.Format(WEB_PI_USER_AGENT_HEADER, Assembly.GetExecutingAssembly().FullName));
|
||||||
|
}
|
||||||
|
|
||||||
private void RaiseOnStatusChangedEvent(string statusMessage)
|
protected override Task GetDownloadFileTask(string remoteFile, string tmpFile, CancellationToken ct)
|
||||||
{
|
{
|
||||||
RaiseOnStatusChangedEvent(statusMessage, String.Empty);
|
var downloadFileTask = new Task(() =>
|
||||||
}
|
{
|
||||||
|
if (!File.Exists(tmpFile))
|
||||||
|
{
|
||||||
|
// Mimic synchronous file download operation because we need to track the download progress
|
||||||
|
// and be able to cancel the operation in progress
|
||||||
|
AutoResetEvent autoEvent = new AutoResetEvent(false);
|
||||||
|
|
||||||
private void RaiseOnStatusChangedEvent(string statusMessage, string eventData)
|
if (fileLoader.IsBusy.Equals(true))
|
||||||
{
|
{
|
||||||
RaiseOnStatusChangedEvent(statusMessage, eventData, true);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RaiseOnStatusChangedEvent(string statusMessage, string eventData, bool cancellable)
|
ct.Register(() =>
|
||||||
{
|
{
|
||||||
if (StatusChanged == null)
|
fileLoader.CancelAsync();
|
||||||
{
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
// No event data for status updates
|
|
||||||
StatusChanged(this, new LoaderEventArgs<String> {
|
|
||||||
StatusMessage = statusMessage,
|
|
||||||
EventData = eventData,
|
|
||||||
Cancellable = cancellable
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RaiseOnProgressChangedEvent(int eventData)
|
Log.WriteStart("Downloading file");
|
||||||
{
|
Log.WriteInfo("Downloading file \"{0}\" to \"{1}\"", remoteFile, tmpFile);
|
||||||
RaiseOnProgressChangedEvent(eventData, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RaiseOnProgressChangedEvent(int eventData, bool cancellable)
|
// Attach event handlers to track status of the download process
|
||||||
{
|
fileLoader.DownloadProgressChanged += (obj, e) =>
|
||||||
if (ProgressChanged == null)
|
{
|
||||||
{
|
if (ct.IsCancellationRequested)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
//
|
|
||||||
ProgressChanged(this, new LoaderEventArgs<int> {
|
|
||||||
EventData = eventData,
|
|
||||||
Cancellable = cancellable
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RaiseOnOperationFailedEvent(Exception ex)
|
RaiseOnProgressChangedEvent(e.ProgressPercentage);
|
||||||
{
|
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage,
|
||||||
if (OperationFailed == null)
|
String.Format(DownloadProgressMessage, e.BytesReceived / 1024, e.TotalBytesToReceive / 1024));
|
||||||
{
|
};
|
||||||
return;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
OperationFailed(this, new LoaderEventArgs<Exception> { EventData = ex });
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RaiseOnOperationCompletedEvent()
|
fileLoader.DownloadFileCompleted += (obj, e) =>
|
||||||
{
|
{
|
||||||
if (OperationCompleted == null)
|
if (ct.IsCancellationRequested == false)
|
||||||
{
|
{
|
||||||
return;
|
RaiseOnProgressChangedEvent(100);
|
||||||
}
|
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage, "100%");
|
||||||
//
|
}
|
||||||
OperationCompleted(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
if (e.Cancelled)
|
||||||
/// Displays process progress.
|
{
|
||||||
/// </summary>
|
CancelDownload(tmpFile);
|
||||||
private void LoadAppDistributiveInternal()
|
}
|
||||||
{
|
|
||||||
//
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var service = ServiceProviderProxy.GetInstallerWebService();
|
|
||||||
//
|
|
||||||
string dataFolder = FileUtils.GetDataDirectory();
|
|
||||||
string tmpFolder = FileUtils.GetTempDirectory();
|
|
||||||
|
|
||||||
if (!Directory.Exists(dataFolder))
|
autoEvent.Set();
|
||||||
{
|
};
|
||||||
Directory.CreateDirectory(dataFolder);
|
|
||||||
Log.WriteInfo("Data directory created");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists(tmpFolder))
|
fileLoader.DownloadFileAsync(new Uri(remoteFile), tmpFile);
|
||||||
{
|
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage);
|
||||||
FileUtils.DeleteTempDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Directory.Exists(tmpFolder))
|
autoEvent.WaitOne();
|
||||||
{
|
}
|
||||||
Directory.CreateDirectory(tmpFolder);
|
}, ct);
|
||||||
Log.WriteInfo("Tmp directory created");
|
|
||||||
}
|
|
||||||
|
|
||||||
string fileToDownload = null;
|
return downloadFileTask;
|
||||||
if (!string.IsNullOrEmpty(localFile))
|
}
|
||||||
{
|
}
|
||||||
fileToDownload = localFile;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileToDownload = Path.GetFileName(remoteFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
string destinationFile = Path.Combine(dataFolder, fileToDownload);
|
/// <summary>
|
||||||
string tmpFile = Path.Combine(tmpFolder, fileToDownload);
|
/// Loader form.
|
||||||
|
/// </summary>
|
||||||
|
public class Loader
|
||||||
|
{
|
||||||
|
public const string ConnectingRemotServiceMessage = "Connecting...";
|
||||||
|
public const string DownloadingSetupFilesMessage = "Downloading setup files...";
|
||||||
|
public const string CopyingSetupFilesMessage = "Copying setup files...";
|
||||||
|
public const string PreparingSetupFilesMessage = "Please wait while Setup prepares the necessary files...";
|
||||||
|
public const string DownloadProgressMessage = "{0} KB of {1} KB";
|
||||||
|
public const string PrepareSetupProgressMessage = "{0}%";
|
||||||
|
|
||||||
//check whether file already downloaded
|
private const int ChunkSize = 262144;
|
||||||
if (!File.Exists(destinationFile))
|
private string remoteFile;
|
||||||
{
|
private CancellationTokenSource cts;
|
||||||
if (string.IsNullOrEmpty(remoteFile))
|
|
||||||
{
|
|
||||||
//need to get remote file name
|
|
||||||
RaiseOnStatusChangedEvent(ConnectingRemotServiceMessage);
|
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(0);
|
|
||||||
//
|
|
||||||
DataSet ds = service.GetReleaseFileInfo(componentCode, version);
|
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(100);
|
|
||||||
//
|
|
||||||
if (ds != null &&
|
|
||||||
ds.Tables.Count > 0 &&
|
|
||||||
ds.Tables[0].Rows.Count > 0)
|
|
||||||
{
|
|
||||||
DataRow row = ds.Tables[0].Rows[0];
|
|
||||||
remoteFile = row["FullFilePath"].ToString();
|
|
||||||
fileToDownload = Path.GetFileName(remoteFile);
|
|
||||||
destinationFile = Path.Combine(dataFolder, fileToDownload);
|
|
||||||
tmpFile = Path.Combine(tmpFolder, fileToDownload);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Installer not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// download file to tmp folder
|
public event EventHandler<LoaderEventArgs<String>> StatusChanged;
|
||||||
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage);
|
public event EventHandler<LoaderEventArgs<Exception>> OperationFailed;
|
||||||
//
|
public event EventHandler<LoaderEventArgs<Int32>> ProgressChanged;
|
||||||
RaiseOnProgressChangedEvent(0);
|
public event EventHandler<EventArgs> OperationCompleted;
|
||||||
//
|
|
||||||
DownloadFile(remoteFile, tmpFile);
|
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(100);
|
|
||||||
|
|
||||||
// copy downloaded file to data folder
|
public Loader(string remoteFile)
|
||||||
RaiseOnStatusChangedEvent(CopyingSetupFilesMessage);
|
{
|
||||||
//
|
this.remoteFile = remoteFile;
|
||||||
RaiseOnProgressChangedEvent(0);
|
}
|
||||||
|
|
||||||
// Ensure that the target does not exist.
|
public void LoadAppDistributive()
|
||||||
if (File.Exists(destinationFile))
|
{
|
||||||
FileUtils.DeleteFile(destinationFile);
|
ThreadPool.QueueUserWorkItem(q => LoadAppDistributiveInternal());
|
||||||
File.Move(tmpFile, destinationFile);
|
}
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unzip file
|
protected void RaiseOnStatusChangedEvent(string statusMessage)
|
||||||
RaiseOnStatusChangedEvent(PreparingSetupFilesMessage);
|
{
|
||||||
//
|
RaiseOnStatusChangedEvent(statusMessage, String.Empty);
|
||||||
RaiseOnProgressChangedEvent(0);
|
}
|
||||||
//
|
|
||||||
UnzipFile(destinationFile, tmpFolder);
|
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(100);
|
|
||||||
//
|
|
||||||
RaiseOnOperationCompletedEvent();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (Utils.IsThreadAbortException(ex))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Log.WriteError("Loader module error", ex);
|
protected void RaiseOnStatusChangedEvent(string statusMessage, string eventData)
|
||||||
//
|
{
|
||||||
RaiseOnOperationFailedEvent(ex);
|
RaiseOnStatusChangedEvent(statusMessage, eventData, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void DownloadFile(string sourceFile, string destinationFile)
|
protected void RaiseOnStatusChangedEvent(string statusMessage, string eventData, bool cancellable)
|
||||||
{
|
{
|
||||||
try
|
if (StatusChanged == null)
|
||||||
{
|
{
|
||||||
var service = ServiceProviderProxy.GetInstallerWebService();
|
return;
|
||||||
//
|
}
|
||||||
Log.WriteStart("Downloading file");
|
// No event data for status updates
|
||||||
Log.WriteInfo(string.Format("Downloading file \"{0}\" to \"{1}\"", sourceFile, destinationFile));
|
StatusChanged(this, new LoaderEventArgs<String>
|
||||||
|
{
|
||||||
|
StatusMessage = statusMessage,
|
||||||
|
EventData = eventData,
|
||||||
|
Cancellable = cancellable
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
long downloaded = 0;
|
protected void RaiseOnProgressChangedEvent(int eventData)
|
||||||
long fileSize = service.GetFileSize(sourceFile);
|
{
|
||||||
if (fileSize == 0)
|
RaiseOnProgressChangedEvent(eventData, true);
|
||||||
{
|
}
|
||||||
throw new FileNotFoundException("Service returned empty file.", sourceFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] content;
|
protected void RaiseOnProgressChangedEvent(int eventData, bool cancellable)
|
||||||
|
{
|
||||||
|
if (ProgressChanged == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
ProgressChanged(this, new LoaderEventArgs<int>
|
||||||
|
{
|
||||||
|
EventData = eventData,
|
||||||
|
Cancellable = cancellable
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
while (downloaded < fileSize)
|
protected void RaiseOnOperationFailedEvent(Exception ex)
|
||||||
{
|
{
|
||||||
content = service.GetFileChunk(sourceFile, (int)downloaded, ChunkSize);
|
if (OperationFailed == null)
|
||||||
if (content == null)
|
{
|
||||||
{
|
return;
|
||||||
throw new FileNotFoundException("Service returned NULL file content.", sourceFile);
|
}
|
||||||
}
|
//
|
||||||
FileUtils.AppendFileContent(destinationFile, content);
|
OperationFailed(this, new LoaderEventArgs<Exception> { EventData = ex });
|
||||||
downloaded += content.Length;
|
}
|
||||||
//update progress bar
|
|
||||||
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage,
|
|
||||||
string.Format(DownloadProgressMessage, downloaded / 1024, fileSize / 1024));
|
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(Convert.ToInt32((downloaded * 100) / fileSize));
|
|
||||||
|
|
||||||
if (content.Length < ChunkSize)
|
protected void RaiseOnOperationCompletedEvent()
|
||||||
break;
|
{
|
||||||
}
|
if (OperationCompleted == null)
|
||||||
//
|
{
|
||||||
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage, "100%");
|
return;
|
||||||
//
|
}
|
||||||
Log.WriteEnd(string.Format("Downloaded {0} bytes", downloaded));
|
//
|
||||||
}
|
OperationCompleted(this, EventArgs.Empty);
|
||||||
catch (Exception ex)
|
}
|
||||||
{
|
|
||||||
if (Utils.IsThreadAbortException(ex))
|
|
||||||
return;
|
|
||||||
|
|
||||||
throw;
|
/// <summary>
|
||||||
}
|
/// Executes a file download request asynchronously
|
||||||
}
|
/// </summary>
|
||||||
|
private void LoadAppDistributiveInternal()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string dataFolder;
|
||||||
|
string tmpFolder;
|
||||||
|
// Retrieve local storage configuration
|
||||||
|
GetLocalStorageInfo(out dataFolder, out tmpFolder);
|
||||||
|
// Initialize storage
|
||||||
|
InitializeLocalStorage(dataFolder, tmpFolder);
|
||||||
|
|
||||||
private void UnzipFile(string zipFile, string destFolder)
|
string fileToDownload = Path.GetFileName(remoteFile);
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int val = 0;
|
|
||||||
// Negative value means no progress made yet
|
|
||||||
int progress = -1;
|
|
||||||
//
|
|
||||||
Log.WriteStart("Unzipping file");
|
|
||||||
Log.WriteInfo(string.Format("Unzipping file \"{0}\" to the folder \"{1}\"", zipFile, destFolder));
|
|
||||||
|
|
||||||
long zipSize = 0;
|
string destinationFile = Path.Combine(dataFolder, fileToDownload);
|
||||||
var zipInfo = ZipFile.Read(zipFile);
|
string tmpFile = Path.Combine(tmpFolder, fileToDownload);
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (ZipEntry entry in zipInfo)
|
|
||||||
{
|
|
||||||
if (!entry.IsDirectory)
|
|
||||||
zipSize += entry.UncompressedSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (zipInfo != null)
|
|
||||||
{
|
|
||||||
zipInfo.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long unzipped = 0;
|
cts = new CancellationTokenSource();
|
||||||
//
|
CancellationToken token = cts.Token;
|
||||||
var zip = ZipFile.Read(zipFile);
|
|
||||||
//
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (ZipEntry entry in zip)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
entry.Extract(destFolder, ExtractExistingFileAction.OverwriteSilently);
|
|
||||||
//
|
|
||||||
if (!entry.IsDirectory)
|
|
||||||
unzipped += entry.UncompressedSize;
|
|
||||||
|
|
||||||
if (zipSize != 0)
|
try
|
||||||
{
|
{
|
||||||
val = Convert.ToInt32(unzipped * 100 / zipSize);
|
// Download the file requested
|
||||||
// Skip to raise the progress event change when calculated progress
|
Task downloadFileTask = GetDownloadFileTask(remoteFile, tmpFile, token);
|
||||||
// and the current progress value are even
|
// Move the file downloaded from temporary location to Data folder
|
||||||
if (val == progress)
|
var moveFileTask = downloadFileTask.ContinueWith((t) =>
|
||||||
{
|
{
|
||||||
continue;
|
if (File.Exists(tmpFile))
|
||||||
}
|
{
|
||||||
//
|
// copy downloaded file to data folder
|
||||||
RaiseOnStatusChangedEvent(
|
RaiseOnStatusChangedEvent(CopyingSetupFilesMessage);
|
||||||
PreparingSetupFilesMessage,
|
//
|
||||||
String.Format(PrepareSetupProgressMessage, val),
|
RaiseOnProgressChangedEvent(0);
|
||||||
false);
|
|
||||||
//
|
|
||||||
RaiseOnProgressChangedEvent(val, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Notify client the operation can be cancelled at this time
|
|
||||||
RaiseOnProgressChangedEvent(100);
|
|
||||||
//
|
|
||||||
Log.WriteEnd("Unzipped file");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (zip != null)
|
|
||||||
{
|
|
||||||
zip.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (Utils.IsThreadAbortException(ex))
|
|
||||||
return;
|
|
||||||
//
|
|
||||||
RaiseOnOperationFailedEvent(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AbortOperation()
|
// Ensure that the target does not exist.
|
||||||
{
|
if (File.Exists(destinationFile))
|
||||||
if (thread != null)
|
FileUtils.DeleteFile(destinationFile);
|
||||||
{
|
File.Move(tmpFile, destinationFile);
|
||||||
if (thread.IsAlive)
|
//
|
||||||
{
|
RaiseOnProgressChangedEvent(100);
|
||||||
thread.Abort();
|
}
|
||||||
}
|
}, TaskContinuationOptions.NotOnCanceled);
|
||||||
thread.Join();
|
// Unzip file downloaded
|
||||||
}
|
var unzipFileTask = moveFileTask.ContinueWith((t) =>
|
||||||
}
|
{
|
||||||
}
|
if (File.Exists(destinationFile))
|
||||||
|
{
|
||||||
|
RaiseOnStatusChangedEvent(PreparingSetupFilesMessage);
|
||||||
|
//
|
||||||
|
RaiseOnProgressChangedEvent(0);
|
||||||
|
//
|
||||||
|
UnzipFile(destinationFile, tmpFolder);
|
||||||
|
//
|
||||||
|
RaiseOnProgressChangedEvent(100);
|
||||||
|
}
|
||||||
|
}, token);
|
||||||
|
//
|
||||||
|
var notifyCompletionTask = unzipFileTask.ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
RaiseOnOperationCompletedEvent();
|
||||||
|
}, token);
|
||||||
|
|
||||||
|
downloadFileTask.Start();
|
||||||
|
downloadFileTask.Wait();
|
||||||
|
}
|
||||||
|
catch (AggregateException ae)
|
||||||
|
{
|
||||||
|
ae.Handle((e) =>
|
||||||
|
{
|
||||||
|
// We handle cancellation requests
|
||||||
|
if (e is OperationCanceledException)
|
||||||
|
{
|
||||||
|
CancelDownload(tmpFile);
|
||||||
|
Log.WriteInfo("Download has been cancelled by the user");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// But other issues just being logged
|
||||||
|
Log.WriteError("Could not download the file", e);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (Utils.IsThreadAbortException(ex))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Log.WriteError("Loader module error", ex);
|
||||||
|
//
|
||||||
|
RaiseOnOperationFailedEvent(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual Task GetDownloadFileTask(string sourceFile, string tmpFile, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var downloadFileTask = new Task(() =>
|
||||||
|
{
|
||||||
|
if (!File.Exists(tmpFile))
|
||||||
|
{
|
||||||
|
var service = ServiceProviderProxy.GetInstallerWebService();
|
||||||
|
|
||||||
|
RaiseOnProgressChangedEvent(0);
|
||||||
|
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage);
|
||||||
|
|
||||||
|
Log.WriteStart("Downloading file");
|
||||||
|
Log.WriteInfo(string.Format("Downloading file \"{0}\" to \"{1}\"", sourceFile, tmpFile));
|
||||||
|
|
||||||
|
long downloaded = 0;
|
||||||
|
long fileSize = service.GetFileSize(sourceFile);
|
||||||
|
if (fileSize == 0)
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("Service returned empty file.", sourceFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] content;
|
||||||
|
|
||||||
|
while (downloaded < fileSize)
|
||||||
|
{
|
||||||
|
// Throw OperationCancelledException if there is an incoming cancel request
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
content = service.GetFileChunk(sourceFile, (int)downloaded, ChunkSize);
|
||||||
|
if (content == null)
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("Service returned NULL file content.", sourceFile);
|
||||||
|
}
|
||||||
|
FileUtils.AppendFileContent(tmpFile, content);
|
||||||
|
downloaded += content.Length;
|
||||||
|
// Update download progress
|
||||||
|
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage,
|
||||||
|
string.Format(DownloadProgressMessage, downloaded / 1024, fileSize / 1024));
|
||||||
|
|
||||||
|
RaiseOnProgressChangedEvent(Convert.ToInt32((downloaded * 100) / fileSize));
|
||||||
|
|
||||||
|
if (content.Length < ChunkSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RaiseOnStatusChangedEvent(DownloadingSetupFilesMessage, "100%");
|
||||||
|
Log.WriteEnd(string.Format("Downloaded {0} bytes", downloaded));
|
||||||
|
}
|
||||||
|
}, ct);
|
||||||
|
|
||||||
|
return downloadFileTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void InitializeLocalStorage(string dataFolder, string tmpFolder)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(dataFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dataFolder);
|
||||||
|
Log.WriteInfo("Data directory created");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Directory.Exists(tmpFolder))
|
||||||
|
{
|
||||||
|
Directory.Delete(tmpFolder, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(tmpFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(tmpFolder);
|
||||||
|
Log.WriteInfo("Tmp directory created");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GetLocalStorageInfo(out string dataFolder, out string tmpFolder)
|
||||||
|
{
|
||||||
|
dataFolder = FileUtils.GetDataDirectory();
|
||||||
|
tmpFolder = FileUtils.GetTempDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnzipFile(string zipFile, string destFolder)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
// Negative value means no progress made yet
|
||||||
|
int progress = -1;
|
||||||
|
//
|
||||||
|
Log.WriteStart("Unzipping file");
|
||||||
|
Log.WriteInfo(string.Format("Unzipping file \"{0}\" to the folder \"{1}\"", zipFile, destFolder));
|
||||||
|
|
||||||
|
long zipSize = 0;
|
||||||
|
var zipInfo = ZipFile.Read(zipFile);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (ZipEntry entry in zipInfo)
|
||||||
|
{
|
||||||
|
if (!entry.IsDirectory)
|
||||||
|
zipSize += entry.UncompressedSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (zipInfo != null)
|
||||||
|
{
|
||||||
|
zipInfo.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long unzipped = 0;
|
||||||
|
//
|
||||||
|
var zip = ZipFile.Read(zipFile);
|
||||||
|
//
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (ZipEntry entry in zip)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
entry.Extract(destFolder, ExtractExistingFileAction.OverwriteSilently);
|
||||||
|
//
|
||||||
|
if (!entry.IsDirectory)
|
||||||
|
unzipped += entry.UncompressedSize;
|
||||||
|
|
||||||
|
if (zipSize != 0)
|
||||||
|
{
|
||||||
|
val = Convert.ToInt32(unzipped * 100 / zipSize);
|
||||||
|
// Skip to raise the progress event change when calculated progress
|
||||||
|
// and the current progress value are even
|
||||||
|
if (val == progress)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
RaiseOnStatusChangedEvent(
|
||||||
|
PreparingSetupFilesMessage,
|
||||||
|
String.Format(PrepareSetupProgressMessage, val),
|
||||||
|
false);
|
||||||
|
//
|
||||||
|
RaiseOnProgressChangedEvent(val, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Notify client the operation can be cancelled at this time
|
||||||
|
RaiseOnProgressChangedEvent(100);
|
||||||
|
//
|
||||||
|
Log.WriteEnd("Unzipped file");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (zip != null)
|
||||||
|
{
|
||||||
|
zip.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (Utils.IsThreadAbortException(ex))
|
||||||
|
return;
|
||||||
|
//
|
||||||
|
RaiseOnOperationFailedEvent(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleans up temporary file if the download process has been cancelled.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tmpFile">Path to the temporary file to cleanup</param>
|
||||||
|
protected virtual void CancelDownload(string tmpFile)
|
||||||
|
{
|
||||||
|
if (File.Exists(tmpFile))
|
||||||
|
{
|
||||||
|
File.Delete(tmpFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AbortOperation()
|
||||||
|
{
|
||||||
|
// Make sure we are in business
|
||||||
|
if (cts != null)
|
||||||
|
{
|
||||||
|
cts.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace WebsitePanel.Installer.Core
|
||||||
|
{
|
||||||
|
class ServiceComponentNotFoundException : Exception
|
||||||
|
{
|
||||||
|
private string p;
|
||||||
|
|
||||||
|
public ServiceComponentNotFoundException(string p)
|
||||||
|
: base(p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,7 @@
|
||||||
<Reference Include="Ionic.Zip.Reduced">
|
<Reference Include="Ionic.Zip.Reduced">
|
||||||
<HintPath>..\..\Lib\Ionic.Zip.Reduced.dll</HintPath>
|
<HintPath>..\..\Lib\Ionic.Zip.Reduced.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.configuration" />
|
<Reference Include="System.configuration" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
@ -80,6 +81,7 @@
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ServiceComponentNotFoundException.cs" />
|
||||||
<Compile Include="ServiceProviderProxy.cs">
|
<Compile Include="ServiceProviderProxy.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -211,7 +211,7 @@ namespace WebsitePanel.Installer.Controls
|
||||||
{
|
{
|
||||||
Log.WriteInfo(string.Format("Updating {0}", componentName));
|
Log.WriteInfo(string.Format("Updating {0}", componentName));
|
||||||
//download installer
|
//download installer
|
||||||
Loader form = new Loader(this.AppContext, fileName);
|
Loader form = new Loader(fileName, (e) => AppContext.AppForm.ShowError(e));
|
||||||
DialogResult result = form.ShowDialog(this);
|
DialogResult result = form.ShowDialog(this);
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
@ -273,7 +273,7 @@ namespace WebsitePanel.Installer.Controls
|
||||||
{
|
{
|
||||||
Log.WriteInfo(string.Format("Uninstalling {0}", componentName));
|
Log.WriteInfo(string.Format("Uninstalling {0}", componentName));
|
||||||
//download installer
|
//download installer
|
||||||
Loader form = new Loader(this.AppContext, installer, componentCode, release);
|
Loader form = new Loader(installer, componentCode, release, (e) => AppContext.AppForm.ShowError(e));
|
||||||
DialogResult result = form.ShowDialog(this);
|
DialogResult result = form.ShowDialog(this);
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
@ -326,15 +326,15 @@ namespace WebsitePanel.Installer.Controls
|
||||||
string path = element.GetStringSetting("InstallerPath");
|
string path = element.GetStringSetting("InstallerPath");
|
||||||
string type = element.GetStringSetting("InstallerType");
|
string type = element.GetStringSetting("InstallerType");
|
||||||
string componentId = element.ID;
|
string componentId = element.ID;
|
||||||
string componentCode = element.GetStringSetting("ComponentCode");
|
string ccode = element.GetStringSetting("ComponentCode");
|
||||||
string componentName = element.GetStringSetting("ComponentName");
|
string componentName = element.GetStringSetting("ComponentName");
|
||||||
string release = element.GetStringSetting("Release");
|
string cversion = element.GetStringSetting("Release");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.WriteInfo(string.Format("Setup {0} {1}", componentName, release));
|
Log.WriteInfo(string.Format("Setup {0} {1}", componentName, cversion));
|
||||||
//download installer
|
//download installer
|
||||||
Loader form = new Loader(this.AppContext, installer, componentCode, release);
|
Loader form = new Loader(installer, ccode, cversion, (e) => AppContext.AppForm.ShowError(e));
|
||||||
DialogResult result = form.ShowDialog(this);
|
DialogResult result = form.ShowDialog(this);
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -45,273 +45,273 @@ using WebsitePanel.Installer.Configuration;
|
||||||
|
|
||||||
namespace WebsitePanel.Installer.Controls
|
namespace WebsitePanel.Installer.Controls
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Components control
|
/// Components control
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal partial class ComponentsControl : ResultViewControl
|
internal partial class ComponentsControl : ResultViewControl
|
||||||
{
|
{
|
||||||
delegate void SetGridDataSourceCallback(object dataSource, string dataMember);
|
delegate void SetGridDataSourceCallback(object dataSource, string dataMember);
|
||||||
|
|
||||||
private string componentCode = null;
|
private string componentCode = null;
|
||||||
private string componentVersion = null;
|
private string componentVersion = null;
|
||||||
private string componentSettingsXml = null;
|
private string componentSettingsXml = null;
|
||||||
|
|
||||||
public ComponentsControl()
|
public ComponentsControl()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
grdComponents.AutoGenerateColumns = false;
|
grdComponents.AutoGenerateColumns = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Action on click Install link
|
/// Action on click Install link
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void OnInstallLinkClick(object sender, DataGridViewCellEventArgs e)
|
private void OnInstallLinkClick(object sender, DataGridViewCellEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.ColumnIndex == grdComponents.Columns.IndexOf(colLink))
|
if (e.ColumnIndex == grdComponents.Columns.IndexOf(colLink))
|
||||||
{
|
{
|
||||||
DataRowView row = grdComponents.Rows[e.RowIndex].DataBoundItem as DataRowView;
|
DataRowView row = grdComponents.Rows[e.RowIndex].DataBoundItem as DataRowView;
|
||||||
if (row != null)
|
if (row != null)
|
||||||
{
|
{
|
||||||
StartInstaller(row);
|
StartInstaller(row);
|
||||||
StartLoadingComponents();
|
StartLoadingComponents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
|
||||||
private void StartInstaller(DataRowView row)
|
}
|
||||||
{
|
}
|
||||||
string applicationName = Utils.GetDbString(row[Global.Parameters.ApplicationName]);
|
|
||||||
string componentName = Utils.GetDbString(row[Global.Parameters.ComponentName]);
|
|
||||||
string componentCode = Utils.GetDbString(row[Global.Parameters.ComponentCode]);
|
|
||||||
string componentDescription = Utils.GetDbString(row[Global.Parameters.ComponentDescription]);
|
|
||||||
string component = Utils.GetDbString(row[Global.Parameters.Component]);
|
|
||||||
string version = Utils.GetDbString(row[Global.Parameters.Version]);
|
|
||||||
string fileName = row[Global.Parameters.FullFilePath].ToString();
|
|
||||||
string installerPath = Utils.GetDbString(row[Global.Parameters.InstallerPath]);
|
|
||||||
string installerType = Utils.GetDbString(row[Global.Parameters.InstallerType]);
|
|
||||||
|
|
||||||
if (CheckForInstalledComponent(componentCode))
|
private void StartInstaller(DataRowView row)
|
||||||
{
|
{
|
||||||
AppContext.AppForm.ShowWarning(Global.Messages.ComponentIsAlreadyInstalled);
|
string applicationName = Utils.GetDbString(row[Global.Parameters.ApplicationName]);
|
||||||
return;
|
string componentName = Utils.GetDbString(row[Global.Parameters.ComponentName]);
|
||||||
}
|
string componentCode = Utils.GetDbString(row[Global.Parameters.ComponentCode]);
|
||||||
try
|
string componentDescription = Utils.GetDbString(row[Global.Parameters.ComponentDescription]);
|
||||||
{
|
string component = Utils.GetDbString(row[Global.Parameters.Component]);
|
||||||
// download installer
|
string version = Utils.GetDbString(row[Global.Parameters.Version]);
|
||||||
Loader form = new Loader(this.AppContext, fileName);
|
string fileName = row[Global.Parameters.FullFilePath].ToString();
|
||||||
DialogResult result = form.ShowDialog(this);
|
string installerPath = Utils.GetDbString(row[Global.Parameters.InstallerPath]);
|
||||||
|
string installerType = Utils.GetDbString(row[Global.Parameters.InstallerType]);
|
||||||
|
|
||||||
if (result == DialogResult.OK)
|
if (CheckForInstalledComponent(componentCode))
|
||||||
{
|
{
|
||||||
string tmpFolder = FileUtils.GetTempDirectory();
|
AppContext.AppForm.ShowWarning(Global.Messages.ComponentIsAlreadyInstalled);
|
||||||
string path = Path.Combine(tmpFolder, installerPath);
|
return;
|
||||||
Update();
|
}
|
||||||
string method = "Install";
|
try
|
||||||
Log.WriteStart(string.Format("Running installer {0}.{1} from {2}", installerType, method, path));
|
{
|
||||||
|
// download installer
|
||||||
|
Loader form = new Loader(fileName, (e) => AppContext.AppForm.ShowError(e));
|
||||||
|
DialogResult result = form.ShowDialog(this);
|
||||||
|
|
||||||
//prepare installer args
|
if (result == DialogResult.OK)
|
||||||
Hashtable args = new Hashtable();
|
{
|
||||||
|
string tmpFolder = FileUtils.GetTempDirectory();
|
||||||
|
string path = Path.Combine(tmpFolder, installerPath);
|
||||||
|
Update();
|
||||||
|
string method = "Install";
|
||||||
|
Log.WriteStart(string.Format("Running installer {0}.{1} from {2}", installerType, method, path));
|
||||||
|
|
||||||
args[Global.Parameters.ComponentName] = componentName;
|
//prepare installer args
|
||||||
args[Global.Parameters.ApplicationName] = applicationName;
|
Hashtable args = new Hashtable();
|
||||||
args[Global.Parameters.ComponentCode] = componentCode;
|
|
||||||
args[Global.Parameters.ComponentDescription] = componentDescription;
|
|
||||||
args[Global.Parameters.Version] = version;
|
|
||||||
args[Global.Parameters.InstallerFolder] = tmpFolder;
|
|
||||||
args[Global.Parameters.InstallerPath] = installerPath;
|
|
||||||
args[Global.Parameters.InstallerType] = installerType;
|
|
||||||
args[Global.Parameters.Installer] = Path.GetFileName(fileName);
|
|
||||||
args[Global.Parameters.ShellVersion] = AssemblyLoader.GetShellVersion();
|
|
||||||
args[Global.Parameters.BaseDirectory] = FileUtils.GetCurrentDirectory();
|
|
||||||
args[Global.Parameters.ShellMode] = Global.VisualInstallerShell;
|
|
||||||
args[Global.Parameters.IISVersion] = Global.IISVersion;
|
|
||||||
args[Global.Parameters.SetupXml] = this.componentSettingsXml;
|
|
||||||
args[Global.Parameters.ParentForm] = FindForm();
|
|
||||||
|
|
||||||
//run installer
|
args[Global.Parameters.ComponentName] = componentName;
|
||||||
DialogResult res = (DialogResult)AssemblyLoader.Execute(path, installerType, method, new object[] { args });
|
args[Global.Parameters.ApplicationName] = applicationName;
|
||||||
Log.WriteInfo(string.Format("Installer returned {0}", res));
|
args[Global.Parameters.ComponentCode] = componentCode;
|
||||||
Log.WriteEnd("Installer finished");
|
args[Global.Parameters.ComponentDescription] = componentDescription;
|
||||||
Update();
|
args[Global.Parameters.Version] = version;
|
||||||
if (res == DialogResult.OK)
|
args[Global.Parameters.InstallerFolder] = tmpFolder;
|
||||||
{
|
args[Global.Parameters.InstallerPath] = installerPath;
|
||||||
AppContext.AppForm.ReloadApplication();
|
args[Global.Parameters.InstallerType] = installerType;
|
||||||
}
|
args[Global.Parameters.Installer] = Path.GetFileName(fileName);
|
||||||
FileUtils.DeleteTempDirectory();
|
args[Global.Parameters.ShellVersion] = AssemblyLoader.GetShellVersion();
|
||||||
}
|
args[Global.Parameters.BaseDirectory] = FileUtils.GetCurrentDirectory();
|
||||||
}
|
args[Global.Parameters.ShellMode] = Global.VisualInstallerShell;
|
||||||
catch (Exception ex)
|
args[Global.Parameters.IISVersion] = Global.IISVersion;
|
||||||
{
|
args[Global.Parameters.SetupXml] = this.componentSettingsXml;
|
||||||
Log.WriteError("Installer error", ex);
|
args[Global.Parameters.ParentForm] = FindForm();
|
||||||
AppContext.AppForm.ShowError(ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
this.componentSettingsXml = null;
|
|
||||||
this.componentCode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
//run installer
|
||||||
|
DialogResult res = (DialogResult)AssemblyLoader.Execute(path, installerType, method, new object[] { args });
|
||||||
|
Log.WriteInfo(string.Format("Installer returned {0}", res));
|
||||||
|
Log.WriteEnd("Installer finished");
|
||||||
|
Update();
|
||||||
|
if (res == DialogResult.OK)
|
||||||
|
{
|
||||||
|
AppContext.AppForm.ReloadApplication();
|
||||||
|
}
|
||||||
|
FileUtils.DeleteTempDirectory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.WriteError("Installer error", ex);
|
||||||
|
AppContext.AppForm.ShowError(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.componentSettingsXml = null;
|
||||||
|
this.componentCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
private bool CheckForInstalledComponent(string componentCode)
|
}
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
List<string> installedComponents = new List<string>();
|
|
||||||
foreach (ComponentConfigElement componentConfig in AppConfigManager.AppConfiguration.Components)
|
|
||||||
{
|
|
||||||
string code = componentConfig.Settings["ComponentCode"].Value;
|
|
||||||
installedComponents.Add(code);
|
|
||||||
if (code == componentCode)
|
|
||||||
{
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (componentCode == "standalone")
|
|
||||||
{
|
|
||||||
if (installedComponents.Contains("server") ||
|
|
||||||
installedComponents.Contains("enterprise server") ||
|
|
||||||
installedComponents.Contains("portal"))
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
private bool CheckForInstalledComponent(string componentCode)
|
||||||
/// Displays component description when entering grid row
|
{
|
||||||
/// </summary>
|
bool ret = false;
|
||||||
/// <param name="sender"></param>
|
List<string> installedComponents = new List<string>();
|
||||||
/// <param name="e"></param>
|
foreach (ComponentConfigElement componentConfig in AppConfigManager.AppConfiguration.Components)
|
||||||
private void OnRowEnter(object sender, DataGridViewCellEventArgs e)
|
{
|
||||||
{
|
string code = componentConfig.Settings["ComponentCode"].Value;
|
||||||
DataRowView row = grdComponents.Rows[e.RowIndex].DataBoundItem as DataRowView;
|
installedComponents.Add(code);
|
||||||
if (row != null)
|
if (code == componentCode)
|
||||||
{
|
{
|
||||||
lblDescription.Text = Utils.GetDbString(row["ComponentDescription"]);
|
ret = true;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (componentCode == "standalone")
|
||||||
|
{
|
||||||
|
if (installedComponents.Contains("server") ||
|
||||||
|
installedComponents.Contains("enterprise server") ||
|
||||||
|
installedComponents.Contains("portal"))
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start new thread to load components
|
/// Displays component description when entering grid row
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void OnLoadComponentsClick(object sender, EventArgs e)
|
private void OnRowEnter(object sender, DataGridViewCellEventArgs e)
|
||||||
{
|
{
|
||||||
StartLoadingComponents();
|
DataRowView row = grdComponents.Rows[e.RowIndex].DataBoundItem as DataRowView;
|
||||||
}
|
if (row != null)
|
||||||
|
{
|
||||||
|
lblDescription.Text = Utils.GetDbString(row["ComponentDescription"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void StartLoadingComponents()
|
/// <summary>
|
||||||
{
|
/// Start new thread to load components
|
||||||
//load list of available components in the separate thread
|
/// </summary>
|
||||||
AppContext.AppForm.StartAsyncProgress("Connecting...", true);
|
/// <param name="sender"></param>
|
||||||
ThreadStart threadDelegate = new ThreadStart(LoadComponents);
|
/// <param name="e"></param>
|
||||||
Thread newThread = new Thread(threadDelegate);
|
private void OnLoadComponentsClick(object sender, EventArgs e)
|
||||||
newThread.Start();
|
{
|
||||||
}
|
StartLoadingComponents();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void StartLoadingComponents()
|
||||||
/// Loads list of available components via web service
|
{
|
||||||
/// </summary>
|
//load list of available components in the separate thread
|
||||||
private void LoadComponents()
|
AppContext.AppForm.StartAsyncProgress("Connecting...", true);
|
||||||
{
|
ThreadPool.QueueUserWorkItem(o => LoadComponents());
|
||||||
try
|
}
|
||||||
{
|
|
||||||
Log.WriteStart("Loading list of available components");
|
|
||||||
lblDescription.Text = string.Empty;
|
|
||||||
//load components via web service
|
|
||||||
var webService = ServiceProviderProxy.GetInstallerWebService();
|
|
||||||
DataSet dsComponents = webService.GetAvailableComponents();
|
|
||||||
//remove already installed components
|
|
||||||
foreach (DataRow row in dsComponents.Tables[0].Rows)
|
|
||||||
{
|
|
||||||
string componentCode = Utils.GetDbString(row["ComponentCode"]);
|
|
||||||
if (CheckForInstalledComponent(componentCode))
|
|
||||||
{
|
|
||||||
row.Delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dsComponents.AcceptChanges();
|
|
||||||
Log.WriteEnd("Available components loaded");
|
|
||||||
SetGridDataSource(dsComponents, dsComponents.Tables[0].TableName);
|
|
||||||
AppContext.AppForm.FinishProgress();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.WriteError("Web service error", ex);
|
|
||||||
AppContext.AppForm.FinishProgress();
|
|
||||||
AppContext.AppForm.ShowServerError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thread safe grid binding.
|
/// Loads list of available components via web service
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataSource">Data source</param>
|
private void LoadComponents()
|
||||||
/// <param name="dataMember">Data member</param>
|
{
|
||||||
private void SetGridDataSource(object dataSource, string dataMember)
|
try
|
||||||
{
|
{
|
||||||
// InvokeRequired required compares the thread ID of the
|
Log.WriteStart("Loading list of available components");
|
||||||
// calling thread to the thread ID of the creating thread.
|
lblDescription.Text = string.Empty;
|
||||||
// If these threads are different, it returns true.
|
//load components via web service
|
||||||
if (this.grdComponents.InvokeRequired)
|
var webService = ServiceProviderProxy.GetInstallerWebService();
|
||||||
{
|
DataSet dsComponents = webService.GetAvailableComponents();
|
||||||
SetGridDataSourceCallback callBack = new SetGridDataSourceCallback(SetGridDataSource);
|
//remove already installed components
|
||||||
this.grdComponents.Invoke(callBack, new object[] { dataSource, dataMember });
|
foreach (DataRow row in dsComponents.Tables[0].Rows)
|
||||||
}
|
{
|
||||||
else
|
string componentCode = Utils.GetDbString(row["ComponentCode"]);
|
||||||
{
|
if (CheckForInstalledComponent(componentCode))
|
||||||
this.grdComponents.DataSource = dataSource;
|
{
|
||||||
this.grdComponents.DataMember = dataMember;
|
row.Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dsComponents.AcceptChanges();
|
||||||
|
Log.WriteEnd("Available components loaded");
|
||||||
|
SetGridDataSource(dsComponents, dsComponents.Tables[0].TableName);
|
||||||
|
AppContext.AppForm.FinishProgress();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.WriteError("Web service error", ex);
|
||||||
|
AppContext.AppForm.FinishProgress();
|
||||||
|
AppContext.AppForm.ShowServerError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Installs component during unattended setup
|
/// Thread safe grid binding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="componentCode"></param>
|
/// <param name="dataSource">Data source</param>
|
||||||
internal void InstallComponent(string componentCode, string componentVersion, string settingsXml)
|
/// <param name="dataMember">Data member</param>
|
||||||
{
|
private void SetGridDataSource(object dataSource, string dataMember)
|
||||||
//load list of available components in the separate thread
|
{
|
||||||
this.componentCode = componentCode;
|
// InvokeRequired required compares the thread ID of the
|
||||||
this.componentVersion = componentVersion;
|
// calling thread to the thread ID of the creating thread.
|
||||||
this.componentSettingsXml = settingsXml;
|
// If these threads are different, it returns true.
|
||||||
AppContext.AppForm.StartAsyncProgress("Connecting...", true);
|
if (this.grdComponents.InvokeRequired)
|
||||||
ThreadStart threadDelegate = new ThreadStart(Install);
|
{
|
||||||
Thread newThread = new Thread(threadDelegate);
|
SetGridDataSourceCallback callBack = new SetGridDataSourceCallback(SetGridDataSource);
|
||||||
newThread.Start();
|
this.grdComponents.Invoke(callBack, new object[] { dataSource, dataMember });
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.grdComponents.DataSource = dataSource;
|
||||||
|
this.grdComponents.DataMember = dataMember;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads list of available components via web service and install specified component
|
/// Installs component during unattended setup
|
||||||
/// during unattended setup
|
/// </summary>
|
||||||
/// </summary>
|
/// <param name="componentCode"></param>
|
||||||
private void Install()
|
internal void InstallComponent(string componentCode, string componentVersion, string settingsXml)
|
||||||
{
|
{
|
||||||
LoadComponents();
|
//load list of available components in the separate thread
|
||||||
foreach (DataGridViewRow gridRow in grdComponents.Rows)
|
this.componentCode = componentCode;
|
||||||
{
|
this.componentVersion = componentVersion;
|
||||||
DataRowView row = gridRow.DataBoundItem as DataRowView;
|
this.componentSettingsXml = settingsXml;
|
||||||
if (row != null)
|
AppContext.AppForm.StartAsyncProgress("Connecting...", true);
|
||||||
{
|
ThreadPool.QueueUserWorkItem(o => Install());
|
||||||
string code = Utils.GetDbString(row["ComponentCode"]);
|
}
|
||||||
string version = Utils.GetDbString(row["Version"]);
|
|
||||||
if (code == componentCode)
|
/// <summary>
|
||||||
{
|
/// Loads list of available components via web service and install specified component
|
||||||
//check component version if specified
|
/// during unattended setup
|
||||||
if (!string.IsNullOrEmpty(componentVersion))
|
/// </summary>
|
||||||
{
|
private void Install()
|
||||||
if (version != componentVersion)
|
{
|
||||||
continue;
|
LoadComponents();
|
||||||
}
|
foreach (DataGridViewRow gridRow in grdComponents.Rows)
|
||||||
StartInstaller(row);
|
{
|
||||||
AppContext.AppForm.ProceedUnattendedSetup();
|
DataRowView row = gridRow.DataBoundItem as DataRowView;
|
||||||
break;
|
if (row != null)
|
||||||
}
|
{
|
||||||
}
|
string code = Utils.GetDbString(row["ComponentCode"]);
|
||||||
}
|
string version = Utils.GetDbString(row["Version"]);
|
||||||
}
|
if (code == componentCode)
|
||||||
}
|
{
|
||||||
|
//check component version if specified
|
||||||
|
if (!string.IsNullOrEmpty(componentVersion))
|
||||||
|
{
|
||||||
|
if (version != componentVersion)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
StartInstaller(row);
|
||||||
|
AppContext.AppForm.ProceedUnattendedSetup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -39,118 +39,156 @@ using Ionic.Zip;
|
||||||
|
|
||||||
using WebsitePanel.Installer.Services;
|
using WebsitePanel.Installer.Services;
|
||||||
using WebsitePanel.Installer.Common;
|
using WebsitePanel.Installer.Common;
|
||||||
|
using WebsitePanel.Installer.Core;
|
||||||
|
|
||||||
namespace WebsitePanel.Installer.Controls
|
namespace WebsitePanel.Installer.Controls
|
||||||
{
|
{
|
||||||
public delegate void OperationProgressDelegate(int percentage);
|
public delegate void OperationProgressDelegate(int percentage);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loader form.
|
/// Loader form.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal partial class Loader : Form
|
internal partial class Loader : Form
|
||||||
{
|
{
|
||||||
private AppContext appContext;
|
private Core.Loader appLoader;
|
||||||
private Core.Loader appLoader;
|
|
||||||
|
|
||||||
public Loader()
|
public Loader()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DialogResult = DialogResult.Cancel;
|
DialogResult = DialogResult.Cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Loader(AppContext context, string remoteFile)
|
public Loader(string remoteFile, Action<Exception> callback)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
this.appContext = context;
|
Start(remoteFile, callback);
|
||||||
//
|
}
|
||||||
appLoader = new Core.Loader(remoteFile);
|
|
||||||
//
|
|
||||||
Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Loader(AppContext context, string localFile, string componentCode, string version)
|
public Loader(string localFile, string componentCode, string version, Action<Exception> callback)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
this.appContext = context;
|
Start(componentCode, version, callback);
|
||||||
//
|
}
|
||||||
appLoader = new Core.Loader(localFile, componentCode, version);
|
|
||||||
//
|
|
||||||
Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Start()
|
/// <summary>
|
||||||
{
|
/// Resolves URL of the component's distributive and initiates download process.
|
||||||
//
|
/// </summary>
|
||||||
appLoader.OperationFailed += new EventHandler<Core.LoaderEventArgs<Exception>>(appLoader_OperationFailed);
|
/// <param name="componentCode">Component code to resolve</param>
|
||||||
appLoader.ProgressChanged += new EventHandler<Core.LoaderEventArgs<Int32>>(appLoader_ProgressChanged);
|
/// <param name="version">Component version to resolve</param>
|
||||||
appLoader.StatusChanged += new EventHandler<Core.LoaderEventArgs<String>>(appLoader_StatusChanged);
|
private void Start(string componentCode, string version, Action<Exception> callback)
|
||||||
appLoader.OperationCompleted += new EventHandler<EventArgs>(appLoader_OperationCompleted);
|
{
|
||||||
//
|
string remoteFile = Utils.GetDistributiveLocationInfo(componentCode, version);
|
||||||
appLoader.LoadAppDistributive();
|
|
||||||
}
|
|
||||||
|
|
||||||
void appLoader_OperationCompleted(object sender, EventArgs e)
|
Start(remoteFile, callback);
|
||||||
{
|
}
|
||||||
DialogResult = DialogResult.OK;
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void appLoader_StatusChanged(object sender, Core.LoaderEventArgs<String> e)
|
/// <summary>
|
||||||
{
|
/// Initializes and starts the app distributive download process.
|
||||||
lblProcess.Text = e.StatusMessage;
|
/// </summary>
|
||||||
lblValue.Text = e.EventData;
|
/// <param name="remoteFile">URL of the file to be downloaded</param>
|
||||||
// Adjust Cancel button availability for an operation being performed
|
private void Start(string remoteFile, Action<Exception> callback)
|
||||||
if (btnCancel.Enabled != e.Cancellable)
|
{
|
||||||
{
|
appLoader = Core.LoaderFactory.CreateFileLoader(remoteFile);
|
||||||
btnCancel.Enabled = e.Cancellable;
|
|
||||||
}
|
|
||||||
// This check allows to avoid extra form redrawing operations
|
|
||||||
if (ControlBox != e.Cancellable)
|
|
||||||
{
|
|
||||||
ControlBox = e.Cancellable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void appLoader_ProgressChanged(object sender, Core.LoaderEventArgs<Int32> e)
|
appLoader.OperationFailed += new EventHandler<Core.LoaderEventArgs<Exception>>(appLoader_OperationFailed);
|
||||||
{
|
appLoader.OperationFailed += (object sender, Core.LoaderEventArgs<Exception> e) => {
|
||||||
progressBar.Value = e.EventData;
|
if (callback != null)
|
||||||
// Adjust Cancel button availability for an operation being performed
|
{
|
||||||
if (btnCancel.Enabled != e.Cancellable)
|
try
|
||||||
{
|
{
|
||||||
btnCancel.Enabled = e.Cancellable;
|
callback(e.EventData);
|
||||||
}
|
}
|
||||||
// This check allows to avoid extra form redrawing operations
|
catch
|
||||||
if (ControlBox != e.Cancellable)
|
{
|
||||||
{
|
// Just swallow the exception as we have no interest in it.
|
||||||
ControlBox = e.Cancellable;
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
appLoader.ProgressChanged += new EventHandler<Core.LoaderEventArgs<Int32>>(appLoader_ProgressChanged);
|
||||||
|
appLoader.StatusChanged += new EventHandler<Core.LoaderEventArgs<String>>(appLoader_StatusChanged);
|
||||||
|
appLoader.OperationCompleted += new EventHandler<EventArgs>(appLoader_OperationCompleted);
|
||||||
|
|
||||||
void appLoader_OperationFailed(object sender, Core.LoaderEventArgs<Exception> e)
|
appLoader.LoadAppDistributive();
|
||||||
{
|
}
|
||||||
appContext.AppForm.ShowError(e.EventData);
|
|
||||||
//
|
|
||||||
DialogResult = DialogResult.Abort;
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btnCancel_Click(object sender, EventArgs e)
|
void appLoader_OperationCompleted(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Log.WriteInfo("Execution was canceled by user");
|
DialogResult = DialogResult.OK;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLoaderFormClosing(object sender, FormClosingEventArgs e)
|
void appLoader_StatusChanged(object sender, Core.LoaderEventArgs<String> e)
|
||||||
{
|
{
|
||||||
if (this.DialogResult == DialogResult.Cancel)
|
lblProcess.Text = e.StatusMessage;
|
||||||
{
|
lblValue.Text = e.EventData;
|
||||||
appLoader.AbortOperation();
|
// Adjust Cancel button availability for an operation being performed
|
||||||
}
|
if (btnCancel.Enabled != e.Cancellable)
|
||||||
// Remove event handlers
|
{
|
||||||
appLoader.OperationFailed -= new EventHandler<Core.LoaderEventArgs<Exception>>(appLoader_OperationFailed);
|
btnCancel.Enabled = e.Cancellable;
|
||||||
appLoader.ProgressChanged -= new EventHandler<Core.LoaderEventArgs<Int32>>(appLoader_ProgressChanged);
|
}
|
||||||
appLoader.StatusChanged -= new EventHandler<Core.LoaderEventArgs<String>>(appLoader_StatusChanged);
|
// This check allows to avoid extra form redrawing operations
|
||||||
appLoader.OperationCompleted -= new EventHandler<EventArgs>(appLoader_OperationCompleted);
|
if (ControlBox != e.Cancellable)
|
||||||
}
|
{
|
||||||
}
|
ControlBox = e.Cancellable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appLoader_ProgressChanged(object sender, Core.LoaderEventArgs<Int32> e)
|
||||||
|
{
|
||||||
|
bool updateControl = (progressBar.Value != e.EventData);
|
||||||
|
progressBar.Value = e.EventData;
|
||||||
|
// Adjust Cancel button availability for an operation being performed
|
||||||
|
if (btnCancel.Enabled != e.Cancellable)
|
||||||
|
{
|
||||||
|
btnCancel.Enabled = e.Cancellable;
|
||||||
|
}
|
||||||
|
// This check allows to avoid extra form redrawing operations
|
||||||
|
if (ControlBox != e.Cancellable)
|
||||||
|
{
|
||||||
|
ControlBox = e.Cancellable;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (updateControl)
|
||||||
|
{
|
||||||
|
progressBar.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appLoader_OperationFailed(object sender, Core.LoaderEventArgs<Exception> e)
|
||||||
|
{
|
||||||
|
DialogResult = DialogResult.Abort;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCancel_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
DetachEventHandlers();
|
||||||
|
Log.WriteInfo("Execution was canceled by user");
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DetachEventHandlers()
|
||||||
|
{
|
||||||
|
// Detach event handlers
|
||||||
|
if (appLoader != null)
|
||||||
|
{
|
||||||
|
appLoader.OperationFailed -= new EventHandler<Core.LoaderEventArgs<Exception>>(appLoader_OperationFailed);
|
||||||
|
appLoader.ProgressChanged -= new EventHandler<Core.LoaderEventArgs<Int32>>(appLoader_ProgressChanged);
|
||||||
|
appLoader.StatusChanged -= new EventHandler<Core.LoaderEventArgs<String>>(appLoader_StatusChanged);
|
||||||
|
appLoader.OperationCompleted -= new EventHandler<EventArgs>(appLoader_OperationCompleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLoaderFormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if (this.DialogResult == DialogResult.Cancel)
|
||||||
|
{
|
||||||
|
if (appLoader != null)
|
||||||
|
{
|
||||||
|
appLoader.AbortOperation();
|
||||||
|
appLoader = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2011, Outercurve Foundation.
|
// Copyright (c) 2012, Outercurve Foundation.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -1901,52 +1901,52 @@ namespace WebsitePanel.Setup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateWebConfigNamespaces()
|
private void UpdateWebConfigNamespaces()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// find all .config files in the installation directory
|
// find all .config files in the installation directory
|
||||||
string[] configFiles = Directory.GetFiles(Wizard.SetupVariables.InstallationFolder,
|
string[] configFiles = Directory.GetFiles(Wizard.SetupVariables.InstallationFolder,
|
||||||
"*.config", SearchOption.TopDirectoryOnly);
|
"*.config", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
if (configFiles != null && configFiles.Length > 0)
|
if (configFiles != null && configFiles.Length > 0)
|
||||||
{
|
{
|
||||||
foreach (string path in configFiles)
|
foreach (string path in configFiles)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.WriteStart(String.Format("Updating '{0}' file", path));
|
Log.WriteStart(String.Format("Updating '{0}' file", path));
|
||||||
|
|
||||||
// load configuration file in memory
|
// load configuration file in memory
|
||||||
string content = File.ReadAllText(path);
|
string content = File.ReadAllText(path);
|
||||||
|
|
||||||
// replace DotNetPark. to empty strings
|
// replace DotNetPark. to empty strings
|
||||||
content = Regex.Replace(content, "dotnetpark\\.", "", RegexOptions.IgnoreCase);
|
content = Regex.Replace(content, "dotnetpark\\.", "", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
// save updated config
|
// save updated config
|
||||||
File.WriteAllText(path, content);
|
File.WriteAllText(path, content);
|
||||||
|
|
||||||
Log.WriteEnd(String.Format("Updated '{0}' file", path));
|
Log.WriteEnd(String.Format("Updated '{0}' file", path));
|
||||||
InstallLog.AppendLine(String.Format("- Updated {0} file", path));
|
InstallLog.AppendLine(String.Format("- Updated {0} file", path));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (Utils.IsThreadAbortException(ex))
|
if (Utils.IsThreadAbortException(ex))
|
||||||
return;
|
return;
|
||||||
Log.WriteError(String.Format("Error updating '{0}' file", path), ex);
|
Log.WriteError(String.Format("Error updating '{0}' file", path), ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (Utils.IsThreadAbortException(ex))
|
if (Utils.IsThreadAbortException(ex))
|
||||||
return;
|
return;
|
||||||
Log.WriteError("Error listing *.config files", ex);
|
Log.WriteError("Error listing *.config files", ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateEnterpriseServerUrl()
|
private void UpdateEnterpriseServerUrl()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue