📄 downloader.cs
字号:
//Walk files
FileInfo[] Files = Source.GetFiles();
foreach (FileInfo pFile in Files)
{
//File check here
if (!Keys.ValidateAssembly(pFile.FullName))
{
throw new Exception("Invalid assembly: " + pFile.FullName);
}
}
//Recurse into subdirectories
DirectoryInfo[] Directories = Source.GetDirectories();
foreach (DirectoryInfo pDirectory in Directories)
{
ValidateDirectory(Path.Combine(source,pDirectory.Name));
}
}
catch (Exception e)
{
Debug.WriteLine("APPMANAGER: Failed to validate new version.");
Debug.WriteLine("APPMANAGER: " + e.ToString());
UpdateEventArgs.ErrorMessage = e.Message;
throw;
}
}
//**************************************************************
// Scavenge()
//**************************************************************
private void Scavenge()
{
DirectoryInfo Root = new DirectoryInfo(GetParentFolder(AppDomain.CurrentDomain.BaseDirectory));
DirectoryInfo[] Directories = Root.GetDirectories();
foreach (DirectoryInfo Directory in Directories)
{
if (((MakeValidPath(Directory.FullName)).ToLower(new CultureInfo("en-US"))
!= AppDomain.CurrentDomain.BaseDirectory.ToLower(new CultureInfo("en-US")))
&& ((MakeValidPath(Directory.FullName)).ToLower(new CultureInfo("en-US"))
!= Config.AppPath.ToLower(new CultureInfo("en-US"))) &&
Directory.Name.ToLower(new CultureInfo("en-US")) != "bin")
{
try
{
HardDirectoryDelete(MakeValidPath(Directory.FullName));
}
catch (Exception)
{
//If we can't delete it, just leave it.
}
}
}
}
//**************************************************************
// Merge()
//**************************************************************
private void MergeDirectory(string source, string destination)
{
try
{
//Get a reference to the source directory
DirectoryInfo Source = new DirectoryInfo(source);
//Create this directory if it doesn't exist
if (!Directory.Exists(destination))
{
Directory.CreateDirectory(destination);
//copy the attributes
DirectoryInfo Destination = new DirectoryInfo(destination);
Destination.Attributes = Source.Attributes;
}
//Copy files
FileInfo[] Files = Source.GetFiles();
foreach (FileInfo pFile in Files)
{
if (!File.Exists(Path.Combine(destination,pFile.Name))
&& (!isManifestFile(pFile.Name)))
pFile.CopyTo(Path.Combine(destination,pFile.Name),true);
}
//Recurse into subdirectories
DirectoryInfo[] Directories = Source.GetDirectories();
foreach (DirectoryInfo pDirectory in Directories)
{
MergeDirectory(Path.Combine(source,pDirectory.Name),Path.Combine(destination,pDirectory.Name));
}
}
catch (Exception e)
{
Debug.WriteLine("APPMANAGER: FAILED to copy: " + source + " to " + destination);
Debug.WriteLine("APPMANAGER: " + e.ToString());
UpdateEventArgs.ErrorMessage = "Copy of user files from the current app directory '" + source
+ "' to the new app directory'" + destination + "' failed with the following error: " + e.Message;
throw;
}
}
//**************************************************************
// FinalizeUpdate()
//**************************************************************
private void FinalizeUpdate()
{
//Create & reserve the properly named new version directory based on the
//assembly version of the downloaded version
try
{
if (AppMan.Manifest.State.NewVersionDirectory =="")
{
AppMan.Manifest.State.NewVersionDirectory = CreateNewVersionDirectory();
AppMan.Manifest.Update();
}
}
catch (Exception)
{
UpdateEventArgs.ErrorMessage = "Failed to create the New Version Directory, using temp download directory as final destination.";
AppMan.Manifest.State.NewVersionDirectory = AppMan.Manifest.State.DownloadDestination;
AppMan.Manifest.Update();
}
//Copy the downloaded version into the new directory
try
{
if (AppMan.Manifest.State.NewVersionDirectory.ToLower(new CultureInfo("en-US")) != AppMan.Manifest.State.DownloadDestination.ToLower(new CultureInfo("en-US")))
CopyDirectory(AppMan.Manifest.State.DownloadDestination,AppMan.Manifest.State.NewVersionDirectory);
}
catch (Exception e)
{
UpdateEventArgs.ErrorMessage = "Failed to copy the downloaded update at: '"+AppMan.Manifest.State.DownloadDestination
+"' to the new version directory at: '" + AppMan.Manifest.State.NewVersionDirectory + "'" ;
throw e;
}
//Write the new version location into the AppConfig file.
//This is the act that makes the update officially complete
try
{
char[] MyChar={'\\'};
Config.AppFolderName = Path.GetFileName(AppMan.Manifest.State.NewVersionDirectory.TrimEnd(MyChar));
Config.Udpate();
}
catch (Exception e)
{
UpdateEventArgs.ErrorMessage = "Failed to write to 'AppStart.config'";
throw e;
}
try
{
if (AppMan.Manifest.State.NewVersionDirectory.ToLower(new CultureInfo("en-US")) != AppMan.Manifest.State.DownloadDestination.ToLower(new CultureInfo("en-US")))
HardDirectoryDelete(AppMan.Manifest.State.DownloadDestination);
}
catch (Exception)
{
//Don't fail the update just because the download copy can't be deleted.
//It will be scavenged later.
}
}
//**************************************************************
// CreateTempDirectory()
//**************************************************************
private string CreateTempDirectory()
{
const int DirectoryCreateRetryAttempts = 50;
int counter = 0;
Random Rand = new Random();
string RandomAddition = "";
string RootDirectory = GetParentFolder(AppDomain.CurrentDomain.BaseDirectory);
string TempDirectory;
do
{
TempDirectory = RootDirectory + "AppUpdate" + RandomAddition + "\\";
RandomAddition = "_"+Rand.Next(10000).ToString();
counter++;
} while (counter <= DirectoryCreateRetryAttempts && Directory.Exists(TempDirectory));
if (counter >= DirectoryCreateRetryAttempts)
{
Debug.WriteLine("APPMANAGER: Failed to create temporary download Directory after 1000 attempts");
UpdateEventArgs.ErrorMessage = "Failed to created temporary download directory in: '"+RootDirectory+"'";
throw (new Exception("Failed to create temporary download Directory after 1000 attempts"));
}
else
{
try
{
Directory.CreateDirectory(TempDirectory);
}
catch (Exception e)
{
Debug.WriteLine("APPMANAGER: Failed to create temporary download Directory");
Debug.WriteLine("APPMANAGER: " + e.ToString());
throw e;
}
}
return TempDirectory;
}
//**************************************************************
// CreateNewVersionDirectory()
//**************************************************************
private string CreateNewVersionDirectory()
{
string NewExePath;
NewExePath = AppMan.Manifest.State.DownloadDestination;
NewExePath += Config.AppExeName;
string NewDirectoryName;
NewDirectoryName = GetFileVersion(NewExePath);
string NewDirectoryRoot = GetParentFolder(AppMan.Manifest.State.DownloadDestination);
string NewDirectoryFullPath = "";
const int DirectoryCreateRetryAttempts = 999;
int counter = 1;
bool FileOpSucceeded = false;
string RandomAddition = "";
do
{
NewDirectoryFullPath = NewDirectoryRoot + NewDirectoryName + RandomAddition + "\\";
RandomAddition = "_"+counter.ToString();
counter++;
try
{
if (!Directory.Exists(NewDirectoryFullPath))
{
Directory.CreateDirectory(NewDirectoryFullPath);
FileOpSucceeded = true;
}
}
catch (Exception)
{
FileOpSucceeded = false;
Debug.WriteLine("APPMANAGER: Failed to rename download Directory to: " + NewDirectoryFullPath);
Debug.WriteLine("APPMANAGER: Trying to rename again.");
}
} while (counter <= DirectoryCreateRetryAttempts && !FileOpSucceeded);
if (counter >= DirectoryCreateRetryAttempts)
{
Debug.WriteLine("APPMANAGER: Failed to rename temporary download Directory after 1000 tries");
Debug.WriteLine("APPMANAGER: Leaving in temporary directory");
NewDirectoryFullPath = AppMan.Manifest.State.DownloadDestination;
}
return NewDirectoryFullPath;
}
//**************************************************************
// MakeValidPath()
//**************************************************************
private string MakeValidPath(string source)
{
if (source.EndsWith(@"\"))
return source;
else
return (source + @"\");
}
//**************************************************************
// CopyDirectory()
//**************************************************************
private void CopyDirectory(string source, string destination)
{
try
{
//Get a reference to the source directory
DirectoryInfo Source = new DirectoryInfo(source);
//Create this directory if it doesn't exist
if (!Directory.Exists(destination))
{
Directory.CreateDirectory(destination);
//copy the attributes
DirectoryInfo Destination = new DirectoryInfo(destination);
Destination.Attributes = Source.Attributes;
}
//Copy files
FileInfo[] Files = Source.GetFiles();
foreach (FileInfo pFile in Files)
{
if (!File.Exists(Path.Combine(destination,pFile.Name)))
pFile.CopyTo(Path.Combine(destination,pFile.Name),true);
}
//Recurse into subdirectories
DirectoryInfo[] Directories = Source.GetDirectories();
foreach (DirectoryInfo pDirectory in Directories)
{
CopyDirectory(Path.Combine(source,pDirectory.Name),Path.Combine(destination,pDirectory.Name));
}
}
catch (Exception e)
{
Debug.WriteLine("UPDATER: FAILED to copy: " + source + " to " + destination);
Debug.WriteLine("UPDATER: " + e.ToString());
throw e;
}
}
//**************************************************************
// HardDirectoryDelete()
//**************************************************************
private void HardDirectoryDelete(string source)
{
try
{
if (!Directory.Exists(source))
return;
//Get a reference to the source directory
DirectoryInfo Source = new DirectoryInfo(source);
Source.Attributes = FileAttributes.Normal;
//Clear the attributes on the files
FileInfo[] Files = Source.GetFiles();
foreach (FileInfo pFile in Files)
{
pFile.Attributes = FileAttributes.Normal;
}
//Recurse into subdirectories
DirectoryInfo[] Directories = Source.GetDirectories();
foreach (DirectoryInfo pDirectory in Directories)
{
HardDirectoryDelete(Path.Combine(source,pDirectory.Name));
}
Source.Delete(true);
}
catch (Exception e)
{
Debug.WriteLine("APPMANAGER: FAILED to delete: " + source);
Debug.WriteLine("APPMANAGER: " + e.ToString());
throw e;
}
}
//**************************************************************
// GetFileVersion()
//**************************************************************
private string GetFileVersion(string filePath)
{
AssemblyName AN = AssemblyName.GetAssemblyName(filePath);
return AN.Version.ToString();
}
//**************************************************************
// GetParentFolder()
//**************************************************************
private string GetParentFolder(string filePath)
{
DirectoryInfo DI = new DirectoryInfo(filePath);
return (DI.Parent.Parent.FullName + @"\");
}
//**************************************************************
// isManifestFile()
//**************************************************************
private bool isManifestFile(string name)
{
string ManifestName = Path.GetFileName(AppMan.Manifest.FilePath);
if (ManifestName.ToLower(new CultureInfo("en-US")) == name.ToLower(new CultureInfo("en-US")))
return true;
else
return false;
}
}
//**************************************************************
// UpdateCompleteEventArgs Class
//**************************************************************
public class UpdateCompleteEventArgs:EventArgs
{
private bool _UpdateSucceeded;
public bool UpdateSucceeded
{ get { return _UpdateSucceeded; } set { _UpdateSucceeded = value; } }
private Exception _FailureException;
public Exception FailureException
{ get { return _FailureException; } set { _FailureException = value; } }
private string _ErrorMessage;
public string ErrorMessage
{ get { return _ErrorMessage; } set { _ErrorMessage = value; } }
private Version _NewVersion;
public Version NewVersion
{ get { return _NewVersion; } set { _NewVersion = value; } }
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -