Skip to content

Commit

Permalink
Added ability to clear application directory before extracting update…
Browse files Browse the repository at this point in the history
…. This resolves #506.
  • Loading branch information
ravibpatel committed Jan 13, 2022
1 parent 2b5fc27 commit faed8d4
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 48 deletions.
12 changes: 6 additions & 6 deletions AutoUpdater.NET/AutoUpdater.NET.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ProjectGuid>{FB9E7E6B-B19F-4F37-A708-2996190CEF13}</ProjectGuid>
Expand All @@ -10,17 +10,17 @@
<AssemblyTitle>AutoUpdater.NET</AssemblyTitle>
<Company>RBSoft</Company>
<Product>AutoUpdater.NET</Product>
<Copyright>Copyright © 2012-2021 RBSoft</Copyright>
<Version>1.7.0.0</Version>
<AssemblyVersion>1.7.0.0</AssemblyVersion>
<FileVersion>1.7.0.0</FileVersion>
<Copyright>Copyright © 2012-2022 RBSoft</Copyright>
<Version>1.7.1.0</Version>
<AssemblyVersion>1.7.1.0</AssemblyVersion>
<FileVersion>1.7.1.0</FileVersion>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>AutoUpdater.NET.snk</AssemblyOriginatorKeyFile>
<NeutralLanguage>en</NeutralLanguage>
<PackageId>Autoupdater.NET.Official</PackageId>
<IncludeSymbols>true</IncludeSymbols>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageVersion>1.7.0.0</PackageVersion>
<PackageVersion>1.7.1.0</PackageVersion>
<Title>AutoUpdater.NET</Title>
<Authors>rbsoft</Authors>
<Description>AutoUpdater.NET is a class library that allows .NET developers to easily add auto update functionality to their classic desktop application projects.</Description>
Expand Down
5 changes: 5 additions & 0 deletions AutoUpdater.NET/AutoUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ public static class AutoUpdater
/// </summary>
public static bool Synchronous = false;

/// <summary>
/// Set this to true if you want to clear application directory before extracting update.
/// </summary>
public static bool ClearAppDirectory = false;

///<summary>
/// Set this to true if you want to ignore previously assigned Remind Later and Skip settings. It will also hide Remind Later and Skip buttons.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions AutoUpdater.NET/DownloadUpdateDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ private void WebClientOnDownloadFileCompleted(object sender, AsyncCompletedEvent

StringBuilder arguments =
new StringBuilder($"\"{tempPath}\" \"{extractionPath}\" \"{executablePath}\"");

if (AutoUpdater.ClearAppDirectory)
{
arguments.Append(" -c");
}

string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++)
{
Expand Down
8 changes: 4 additions & 4 deletions AutoUpdater.NET/build/Autoupdater.NET.Official.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
<package xmlns="http:https://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Autoupdater.NET.Official</id>
<version>1.7.0.0</version>
<version>1.7.1.0</version>
<title>AutoUpdater.NET</title>
<authors>rbsoft</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
<projectUrl>https://github.com/ravibpatel/AutoUpdater.NET</projectUrl>
<description>AutoUpdater.NET is a class library that allows .NET developers to easily add auto update functionality to their classic desktop application projects.</description>
<description>AutoUpdater.NET is a class library that allows .NET developers to easily add auto update functionality to their WinForms or WPF application projects.</description>
<releaseNotes>https://github.com/ravibpatel/AutoUpdater.NET/releases</releaseNotes>
<copyright>Copyright © 2012-2021 RBSoft</copyright>
<copyright>Copyright © 2012-2022 RBSoft</copyright>
<tags>autoupdate updater c# vb wpf winforms</tags>
<dependencies>
<group targetFramework=".NETFramework4.5" />
<group targetFramework=".NETCoreApp3.1" />
<group targetFramework="net5.0-windows" />
<group targetFramework="net5.0-windows7.0" />
</dependencies>
<frameworkAssemblies>
<frameworkAssembly assemblyName="System.Data" targetFramework=".NETFramework4.5" />
Expand Down
11 changes: 7 additions & 4 deletions AutoUpdaterTest/FormMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ private void FormMain_Load(object sender, EventArgs e)
//Uncomment following line if you don't want the library to determine the installed version from assembly.
//AutoUpdater.InstalledVersion = new Version("2.0.0.1");

//Uncomment following line if you want to clear application directory before update zip is extracted.
//AutoUpdater.ClearAppDirectory = true;

AutoUpdater.Start("https://rbsoft.org/updates/AutoUpdaterTest.xml");
}

Expand Down Expand Up @@ -169,8 +172,8 @@ private void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
dialogResult =
MessageBox.Show(
$@"There is new version {args.CurrentVersion} available. You are using version {
args.InstalledVersion
}. This is required update. Press Ok to begin updating the application.",
args.InstalledVersion
}. This is required update. Press Ok to begin updating the application.",
@"Update Available",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
Expand All @@ -180,8 +183,8 @@ private void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
dialogResult =
MessageBox.Show(
$@"There is new version {args.CurrentVersion} available. You are using version {
args.InstalledVersion
}. Do you want to update the application now?", @"Update Available",
args.InstalledVersion
}. Do you want to update the application now?", @"Update Available",
MessageBoxButtons.YesNo,
MessageBoxIcon.Information);
}
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2012-2021 RBSoft
Copyright (c) 2012-2022 RBSoft

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ PM> Install-Package Autoupdater.NET.Official
* .NET Core 3.1
* .NET 5.0 or above

This library only works for WinForms or WPF application projects.

## How it works

AutoUpdater.NET downloads the XML file containing update information from your server. It uses this XML file to get the information about the latest version of the software. If the latest version of the software is greater than the current version of the software installed on User's PC then AutoUpdater.NET shows update dialog to the user. If user press the update button to update the software then It downloads the update file (Installer) from URL provided in XML file and executes the installer file it just downloaded. It is a job of installer after this point to carry out the update. If you provide zip file URL instead of installer then AutoUpdater.NET will extract the contents of zip file to application directory.
Expand All @@ -29,10 +31,10 @@ AutoUpdater.NET uses XML file located on a server to get the release information
````xml
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>2.0.0.0</version>
<url>http:https://rbsoft.org/downloads/AutoUpdaterTest.zip</url>
<changelog>https://github.com/ravibpatel/AutoUpdater.NET/releases</changelog>
<mandatory>false</mandatory>
<version>2.0.0.0</version>
<url>https:https://rbsoft.org/downloads/AutoUpdaterTest.zip</url>
<changelog>https://github.com/ravibpatel/AutoUpdater.NET/releases</changelog>
<mandatory>false</mandatory>
</item>
````

Expand All @@ -48,7 +50,7 @@ There are two things you need to provide in XML file as you can see above.
<mandatory mode="2">true</mandatory>
````

* minVersion (Attribute, Optional): You can also prvoide minVersion attribute on mandatory element. When you provide it, Mandatory option will be triggered only if the installed version of the app is less than the mininum version you specified here.
* minVersion (Attribute, Optional): You can also provide minVersion attribute on mandatory element. When you provide it, Mandatory option will be triggered only if the installed version of the app is less than the minimum version you specified here.

````xml
<mandatory minVersion="1.2.0.0">true</mandatory>
Expand All @@ -72,7 +74,7 @@ using AutoUpdaterDotNET;
Now you just need to add following line to your main form constructor or in Form_Load event. You can add this line anywhere you like. If you don't like to check for update when application starts then you can create a Check for update button and add this line to Button_Click event.

````csharp
AutoUpdater.Start("http:https://rbsoft.org/updates/AutoUpdaterTest.xml");
AutoUpdater.Start("https:https://rbsoft.org/updates/AutoUpdaterTest.xml");
````

Start method of AutoUpdater class takes URL of the XML file you uploaded to server as a parameter.
Expand All @@ -90,7 +92,7 @@ Version specified in XML file should be higher than Assembly version to trigger
If you want to provide your own Assembly then you can do it by providing second argument of Start method as shown below.

````csharp
AutoUpdater.Start("http:https://rbsoft.org/updates/AutoUpdaterTest.xml", myAssembly);
AutoUpdater.Start("https:https://rbsoft.org/updates/AutoUpdaterTest.xml", myAssembly);
````

## Configuration Options
Expand Down Expand Up @@ -241,6 +243,14 @@ if (currentDirectory.Parent != null)
}
````

### Clear application directory before extracting update file

Sometimes it is necessary to clear previous version files before doing an update. In this case, you can specify whether to clear the application directory before extracting the update file using the below code.

````csharp
AutoUpdater.ClearAppDirectory = true;
````

### Specify size of the UpdateForm

You can specify the size of the update form by using below code.
Expand Down Expand Up @@ -276,7 +286,7 @@ System.Timers.Timer timer = new System.Timers.Timer
};
timer.Elapsed += delegate
{
AutoUpdater.Start("http:https://rbsoft.org/updates/AutoUpdaterTest.xml");
AutoUpdater.Start("https:https://rbsoft.org/updates/AutoUpdaterTest.xml");
};
timer.Start();
````
Expand All @@ -287,7 +297,7 @@ timer.Start();
DispatcherTimer timer = new DispatcherTimer {Interval = TimeSpan.FromMinutes(2)};
timer.Tick += delegate
{
AutoUpdater.Start("http:https://rbsoft.org/updates/AutoUpdaterTestWPF.xml");
AutoUpdater.Start("https:https://rbsoft.org/updates/AutoUpdaterTestWPF.xml");
};
timer.Start();
````
Expand Down Expand Up @@ -398,7 +408,7 @@ If you want to use other format instead of XML as an AppCast file then you need

````csharp
AutoUpdater.ParseUpdateInfoEvent += AutoUpdaterOnParseUpdateInfoEvent;
AutoUpdater.Start("http:https://rbsoft.org/updates/AutoUpdaterTest.json");
AutoUpdater.Start("https:https://rbsoft.org/updates/AutoUpdaterTest.json");

private void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
{
Expand Down Expand Up @@ -428,7 +438,7 @@ private void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
````json
{
"version":"2.0.0.0",
"url":"http:https://rbsoft.org/downloads/AutoUpdaterTest.zip",
"url":"https:https://rbsoft.org/downloads/AutoUpdaterTest.zip",
"changelog":"https://github.com/ravibpatel/AutoUpdater.NET/releases",
"mandatory":{
"value":true,
Expand Down
46 changes: 34 additions & 12 deletions ZipExtractor/FormMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public partial class FormMain : Form
{
private const int MaxRetries = 2;
private BackgroundWorker _backgroundWorker;
private readonly StringBuilder _logBuilder = new StringBuilder();
private readonly StringBuilder _logBuilder = new();

public FormMain()
{
Expand All @@ -40,7 +40,11 @@ private void FormMain_Shown(object sender, EventArgs e)

if (args.Length >= 4)
{
string zipPath = args[1];
string extractionPath = args[2];
string executablePath = args[3];
bool clearAppDirectory = args.Length > 4 && args[4] == "-c";
string commandLineArgs = args.Length > 5 ? args[5] : string.Empty;

// Extract all the files.
_backgroundWorker = new BackgroundWorker
Expand Down Expand Up @@ -70,26 +74,44 @@ private void FormMain_Shown(object sender, EventArgs e)
}
_logBuilder.AppendLine("BackgroundWorker started successfully.");
var path = args[2];
// Ensures that the last character on the extraction path
// is the directory separator char.
// Without this, a malicious zip file could try to traverse outside of the expected
// extraction path.
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
if (!extractionPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
{
path += Path.DirectorySeparatorChar;
extractionPath += Path.DirectorySeparatorChar;
}
var archive = ZipFile.OpenRead(args[1]);
var archive = ZipFile.OpenRead(zipPath);
var entries = archive.Entries;
_logBuilder.AppendLine($"Found total of {entries.Count} files and folders inside the zip file.");
try
{
int progress = 0;
if (clearAppDirectory)
{
_logBuilder.AppendLine($"Removing all files and folders from {extractionPath}.");
DirectoryInfo directoryInfo = new DirectoryInfo(extractionPath);
foreach (FileInfo file in directoryInfo.GetFiles())
{
_logBuilder.AppendLine($"Removing a file located at {file.FullName}.");
_backgroundWorker.ReportProgress(0, string.Format(Resources.Removing, file.FullName));
file.Delete();
}
foreach (DirectoryInfo directory in directoryInfo.GetDirectories())
{
_logBuilder.AppendLine($"Removing a directory located at {directory.FullName} and all its contents.");
_backgroundWorker.ReportProgress(0, string.Format(Resources.Removing, directory.FullName));
directory.Delete(true);
}
}
_logBuilder.AppendLine($"Found total of {entries.Count} files and folders inside the zip file.");
for (var index = 0; index < entries.Count; index++)
{
if (_backgroundWorker.CancellationPending)
Expand All @@ -109,7 +131,7 @@ private void FormMain_Shown(object sender, EventArgs e)
string filePath = String.Empty;
try
{
filePath = Path.Combine(path, entry.FullName);
filePath = Path.Combine(extractionPath, entry.FullName);
if (!entry.IsDirectory())
{
var parentDirectory = Path.GetDirectoryName(filePath);
Expand All @@ -126,7 +148,7 @@ private void FormMain_Shown(object sender, EventArgs e)
const int errorSharingViolation = 0x20;
const int errorLockViolation = 0x21;
var errorCode = Marshal.GetHRForException(exception) & 0x0000FFFF;
if (errorCode == errorSharingViolation || errorCode == errorLockViolation)
if (errorCode is errorSharingViolation or errorLockViolation)
{
retries++;
if (retries > MaxRetries)
Expand Down Expand Up @@ -212,9 +234,9 @@ private void FormMain_Shown(object sender, EventArgs e)
try
{
ProcessStartInfo processStartInfo = new ProcessStartInfo(executablePath);
if (args.Length > 4)
if (!string.IsNullOrEmpty(commandLineArgs))
{
processStartInfo.Arguments = args[4];
processStartInfo.Arguments = commandLineArgs;
}
Process.Start(processStartInfo);
Expand Down
9 changes: 9 additions & 0 deletions ZipExtractor/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ZipExtractor/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,7 @@
<data name="ZipExtractor" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ZipExtractor.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Removing" xml:space="preserve">
<value>Removing {0}</value>
</data>
</root>
15 changes: 8 additions & 7 deletions ZipExtractor/ZipExtractor.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ProjectGuid>{91DE558C-6DB8-429B-A069-C0491DCFF15B}</ProjectGuid>
Expand All @@ -8,18 +8,18 @@
<AssemblyTitle>ZipExtractor</AssemblyTitle>
<Company>RBSoft</Company>
<Product>ZipExtractor</Product>
<Copyright>Copyright © 2012-2021 RBSoft</Copyright>
<Version>1.3.0.0</Version>
<AssemblyVersion>1.3.0.0</AssemblyVersion>
<FileVersion>1.3.0.0</FileVersion>
<ApplicationVersion>1.3.0.0</ApplicationVersion>
<Copyright>Copyright © 2012-2022 RBSoft</Copyright>
<Version>1.3.1.0</Version>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.1.0</FileVersion>
<ApplicationVersion>1.3.1.0</ApplicationVersion>
<ApplicationIcon>ZipExtractor.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>ZipExtractor.snk</AssemblyOriginatorKeyFile>
<NeutralLanguage>en</NeutralLanguage>
<LangVersion>default</LangVersion>
<PackageVersion>1.3.0.0</PackageVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' != 'net45' ">
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
Expand All @@ -35,6 +35,7 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>..\AutoUpdater.NET\Resources</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
Expand Down
Loading

0 comments on commit faed8d4

Please sign in to comment.