Skip to content

Commit

Permalink
Now using BuildArguments method used internally in .NET Standard to b…
Browse files Browse the repository at this point in the history
…uild arguments string in .NET Framework.
  • Loading branch information
ravibpatel committed Apr 28, 2023
1 parent 3d72caf commit 02662bb
Show file tree
Hide file tree
Showing 33 changed files with 390 additions and 1,393 deletions.
18 changes: 6 additions & 12 deletions AutoUpdater.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdater.NET", "AutoUpda
{91DE558C-6DB8-429B-A069-C0491DCFF15B} = {91DE558C-6DB8-429B-A069-C0491DCFF15B}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdaterTest", "AutoUpdaterTest\AutoUpdaterTest.csproj", "{FD5AE762-C630-49F8-B814-FCF70E7838D1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdaterTestWPF", "AutoUpdaterTestWPF\AutoUpdaterTestWPF.csproj", "{9AEE4F21-5ED5-4C7E-9249-8A680123B5E3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1DBD2EE1-6C31-4B24-9212-E221404F4ADE}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
Expand All @@ -22,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZipExtractor", "ZipExtractor\ZipExtractor.csproj", "{EDB311FC-50D3-468B-AC36-4CDFE04D29A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdaterTest", "AutoUpdaterTest\AutoUpdaterTest.csproj", "{5C1E186E-2622-425D-8E90-2CC6C25EDE29}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -32,18 +30,14 @@ Global
{FB9E7E6B-B19F-4F37-A708-2996190CEF13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB9E7E6B-B19F-4F37-A708-2996190CEF13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB9E7E6B-B19F-4F37-A708-2996190CEF13}.Release|Any CPU.Build.0 = Release|Any CPU
{FD5AE762-C630-49F8-B814-FCF70E7838D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD5AE762-C630-49F8-B814-FCF70E7838D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD5AE762-C630-49F8-B814-FCF70E7838D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD5AE762-C630-49F8-B814-FCF70E7838D1}.Release|Any CPU.Build.0 = Release|Any CPU
{9AEE4F21-5ED5-4C7E-9249-8A680123B5E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AEE4F21-5ED5-4C7E-9249-8A680123B5E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AEE4F21-5ED5-4C7E-9249-8A680123B5E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9AEE4F21-5ED5-4C7E-9249-8A680123B5E3}.Release|Any CPU.Build.0 = Release|Any CPU
{EDB311FC-50D3-468B-AC36-4CDFE04D29A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDB311FC-50D3-468B-AC36-4CDFE04D29A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDB311FC-50D3-468B-AC36-4CDFE04D29A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDB311FC-50D3-468B-AC36-4CDFE04D29A3}.Release|Any CPU.Build.0 = Release|Any CPU
{5C1E186E-2622-425D-8E90-2CC6C25EDE29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C1E186E-2622-425D-8E90-2CC6C25EDE29}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C1E186E-2622-425D-8E90-2CC6C25EDE29}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C1E186E-2622-425D-8E90-2CC6C25EDE29}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
4 changes: 2 additions & 2 deletions AutoUpdater.NET/AutoUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ public static class AutoUpdater
/// <param name="args">An object containing the AppCast file received from server.</param>
public delegate void ParseUpdateInfoHandler(ParseUpdateInfoEventArgs args);

private static Timer _remindLaterTimer;

private static bool _isWinFormsApplication;

private static Timer _remindLaterTimer;

internal static Uri BaseUri;

internal static bool Running;
Expand Down
29 changes: 20 additions & 9 deletions AutoUpdater.NET/DownloadUpdateDialog.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
Expand All @@ -7,7 +8,6 @@
using System.Net;
using System.Net.Mime;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using AutoUpdaterDotNET.Properties;

Expand Down Expand Up @@ -187,24 +187,35 @@ private void WebClientOnDownloadFileCompleted(object sender, AsyncCompletedEvent
};

#if NETFRAMEWORK
var arguments =
new StringBuilder(
$"--input \"{tempPath}\" --output \"{extractionPath}\" --current-exe \"{currentExe}\"");
var arguments = new Collection<string>
{
"--input",
tempPath,
"--output",
extractionPath,
"--current-exe",
currentExe
};

if (!string.IsNullOrWhiteSpace(updatedExe))
{
arguments.Append($" --updated-exe \"{updatedExe}\"");
arguments.Add("--updated-exe");
arguments.Add(updatedExe);
}

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

string args = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).Select(arg => $"\"{arg}\""));
arguments.Append($" --args \"{args}\"");
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 0)
{
arguments.Add("--args");
arguments.Add(string.Join(" ", args.Skip(1).Select(arg => $"\"{arg}\"")));
}

processStartInfo.Arguments = arguments.ToString().Replace("\\\"", "\\\\\"");
processStartInfo.Arguments = Utils.BuildArguments(arguments);
#else
processStartInfo.ArgumentList.Add("--input");
processStartInfo.ArgumentList.Add(tempPath);
Expand Down
5 changes: 4 additions & 1 deletion AutoUpdater.NET/UpdateForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Windows.Forms;
using Microsoft.Web.WebView2.Core;
using Microsoft.Win32;
using static System.Reflection.Assembly;

namespace AutoUpdaterDotNET;

Expand Down Expand Up @@ -146,7 +147,9 @@ private void UseLatestIE()
Registry.CurrentUser.OpenSubKey(
@"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
true);
registryKey?.SetValue(Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName),
registryKey?.SetValue(
Path.GetFileName(Process.GetCurrentProcess().MainModule?.FileName ??
GetEntryAssembly()?.Location ?? Application.ExecutablePath),
ieValue,
RegistryValueKind.DWord);
}
Expand Down
103 changes: 103 additions & 0 deletions AutoUpdater.NET/Utils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace AutoUpdaterDotNET;

internal static class Utils
{
public static string BuildArguments(Collection<string> argumentList)
{
var arguments = new StringBuilder();
if (argumentList is not { Count: > 0 })
{
return string.Empty;
}

foreach (string argument in argumentList) PasteArguments.AppendArgument(ref arguments, argument);
return arguments.ToString();
}
}

internal static class PasteArguments
{
private const char Quote = '\"';
private const char Backslash = '\\';

internal static void AppendArgument(ref StringBuilder stringBuilder, string argument)
{
if (stringBuilder.Length != 0)
{
stringBuilder.Append(' ');
}

// Parsing rules for non-argv[0] arguments:
// - Backslash is a normal character except followed by a quote.
// - 2N backslashes followed by a quote ==> N literal backslashes followed by unescaped quote
// - 2N+1 backslashes followed by a quote ==> N literal backslashes followed by a literal quote
// - Parsing stops at first whitespace outside of quoted region.
// - (post 2008 rule): A closing quote followed by another quote ==> literal quote, and parsing remains in quoting mode.
if (argument.Length != 0 && ContainsNoWhitespaceOrQuotes(argument))
{
// Simple case - no quoting or changes needed.
stringBuilder.Append(argument);
}
else
{
stringBuilder.Append(Quote);
var idx = 0;
while (idx < argument.Length)
{
char c = argument[idx++];
switch (c)
{
case Backslash:
{
var numBackSlash = 1;
while (idx < argument.Length && argument[idx] == Backslash)
{
idx++;
numBackSlash++;
}

if (idx == argument.Length)
{
// We'll emit an end quote after this so must double the number of backslashes.
stringBuilder.Append(Backslash, numBackSlash * 2);
}
else if (argument[idx] == Quote)
{
// Backslashes will be followed by a quote. Must double the number of backslashes.
stringBuilder.Append(Backslash, numBackSlash * 2 + 1);
stringBuilder.Append(Quote);
idx++;
}
else
{
// Backslash will not be followed by a quote, so emit as normal characters.
stringBuilder.Append(Backslash, numBackSlash);
}

continue;
}
case Quote:
// Escape the quote so it appears as a literal. This also guarantees that we won't end up generating a closing quote followed
// by another quote (which parses differently pre-2008 vs. post-2008.)
stringBuilder.Append(Backslash);
stringBuilder.Append(Quote);
continue;
default:
stringBuilder.Append(c);
break;
}
}

stringBuilder.Append(Quote);
}
}

private static bool ContainsNoWhitespaceOrQuotes(string s)
{
return s.All(c => !char.IsWhiteSpace(c) && c != Quote);
}
}
2 changes: 1 addition & 1 deletion AutoUpdaterTestWPF/App.xaml → AutoUpdaterTest/App.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Application x:Class="AutoUpdaterTestWPF.App"
<Application x:Class="AutoUpdaterTest.App"
xmlns="http:https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http:https://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
Expand Down
10 changes: 10 additions & 0 deletions AutoUpdaterTest/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

namespace AutoUpdaterTest;

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
10 changes: 10 additions & 0 deletions AutoUpdaterTest/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
107 changes: 13 additions & 94 deletions AutoUpdaterTest/AutoUpdaterTest.csproj
Original file line number Diff line number Diff line change
@@ -1,101 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http:https://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FD5AE762-C630-49F8-B814-FCF70E7838D1}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AutoUpdaterTest</RootNamespace>
<AssemblyName>AutoUpdaterTest</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile/>
<TargetFramework>net45</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<LangVersion>latest</LangVersion>
<Version>1.0.0</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp"/>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System"/>
<Reference Include="System.Data"/>
<Reference Include="System.Deployment"/>
<Reference Include="System.Drawing"/>
<Reference Include="System.Windows.Forms"/>
<Reference Include="System.Xml"/>
</ItemGroup>

<ItemGroup>
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs"/>
<Compile Include="Properties\AssemblyInfo.cs"/>
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="app.config"/>
<None Include="app.manifest"/>
<None Include="packages.config"/>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<ProjectReference Include="..\AutoUpdater.NET\AutoUpdater.NET.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AutoUpdater.NET\AutoUpdater.NET.csproj">
<Project>{fb9e7e6b-b19f-4f37-a708-2996190cef13}</Project>
<Name>AutoUpdater.NET</Name>
</ProjectReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

</Project>
Loading

0 comments on commit 02662bb

Please sign in to comment.