1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-05-31 22:41:37 +00:00

Port MakeDist to WPF

The only tricky part is the RichTextBox, but that's mostly copy and
paste from the regression test harness.
This commit is contained in:
Andy McFadden 2019-07-19 17:40:35 -07:00
parent b6132b029a
commit 38b5027af1
15 changed files with 1035 additions and 0 deletions

6
MakeDistWPF/App.config Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
</configuration>

9
MakeDistWPF/App.xaml Normal file
View File

@ -0,0 +1,9 @@
<Application x:Class="MakeDistWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MakeDistWPF"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

15
MakeDistWPF/App.xaml.cs Normal file
View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace MakeDistWPF {
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application {
}
}

View File

@ -0,0 +1,40 @@
<!--
Copyright 2019 faddenSoft
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Window x:Class="MakeDistWPF.CopyProgress"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MakeDistWPF"
mc:Ignorable="d"
Title="Copy Distribution Files"
Width="1200" Height="600" MinWidth="300" MinHeight="200" ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
Loaded="Window_Loaded">
<DockPanel Margin="8">
<Button Name="cancelButton" DockPanel.Dock="Bottom" Content="Cancel" IsCancel="True" Width="70"
HorizontalAlignment="Right" Margin="0,8,0,0"/>
<RichTextBox Name="progressRichTextBox" VerticalScrollBarVisibility="Visible">
<RichTextBox.Resources>
<!-- remove excess vertical space between paragraphs -->
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0"/>
</Style>
</RichTextBox.Resources>
</RichTextBox>
</DockPanel>
</Window>

View File

@ -0,0 +1,132 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using CommonWPF;
namespace MakeDistWPF {
/// <summary>
/// Show progress log while copying files.
/// </summary>
public partial class CopyProgress : Window {
/// <summary>
/// Progress message, with colorful text. This is generated by the worker thread and
/// passed to the UI thread.
/// </summary>
public class ProgressMessage {
public string Text { get; private set; }
public Color Color { get; private set; }
public bool HasColor { get { return Color.A != 0; } }
public ProgressMessage(string msg) : this(msg, Colors.Transparent) { }
public ProgressMessage(string msg, Color color) {
Text = msg;
Color = color;
}
}
private BackgroundWorker mWorker;
private FlowDocument mFlowDoc = new FlowDocument();
private Color mDefaultColor;
// Copy parameters.
private FileCopier.BuildType mBuildType;
private bool mCopyTestFiles;
public CopyProgress(Window owner, FileCopier.BuildType buildType, bool copyTestFiles) {
InitializeComponent();
Owner = owner;
DataContext = this;
mBuildType = buildType;
mCopyTestFiles = copyTestFiles;
mDefaultColor = ((SolidColorBrush)progressRichTextBox.Foreground).Color;
// Create and configure the BackgroundWorker.
mWorker = new BackgroundWorker();
mWorker.WorkerReportsProgress = true;
mWorker.WorkerSupportsCancellation = true;
mWorker.DoWork += BackgroundWorker_DoWork;
mWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
mWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
progressRichTextBox.Document = mFlowDoc;
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
mWorker.RunWorkerAsync();
}
// NOTE: executes on work thread. DO NOT do any UI work here. Pass the test
// results through e.Result.
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
FileCopier copier = new FileCopier(mBuildType, mCopyTestFiles);
e.Result = copier.CopyAllFiles(worker);
if (worker.CancellationPending) {
e.Cancel = true;
}
}
// Callback that fires when a progress update is made.
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
// We get progress from GenTest, and from the IAssembler/IGenerator classes. This
// is necessary to make cancellation work right, and allows us to show the
// asm/gen progress messages if we want to.
if (e.UserState is ProgressMessage) {
ProgressMessage msg = e.UserState as ProgressMessage;
if (msg.HasColor) {
progressRichTextBox.AppendText(msg.Text, msg.Color);
} else {
// plain foreground text color
progressRichTextBox.AppendText(msg.Text, mDefaultColor);
}
progressRichTextBox.ScrollToEnd();
} else {
// Most progress updates have an e.ProgressPercentage value and a blank string.
if (!string.IsNullOrEmpty((string)e.UserState)) {
Debug.WriteLine("Sub-progress: " + e.UserState);
}
}
}
// Callback that fires when execution completes.
private void BackgroundWorker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e) {
if (e.Cancelled) {
Debug.WriteLine("Test halted -- user cancellation");
} else if (e.Error != null) {
Debug.WriteLine("Test failed: " + e.Error.ToString());
progressRichTextBox.AppendText("\r\n");
progressRichTextBox.AppendText(e.Error.ToString(), mDefaultColor);
progressRichTextBox.ScrollToEnd();
} else {
Debug.WriteLine("Copy complete");
}
cancelButton.Content = "Close";
}
}
}

320
MakeDistWPF/FileCopier.cs Normal file
View File

@ -0,0 +1,320 @@
/*
* Copyright 2018 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Media;
namespace MakeDistWPF {
public class FileCopier {
private const string SOURCEGEN_DIRNAME = "SourceGen";
/// <summary>
/// Type of build to gather files for.
/// </summary>
public enum BuildType { Unknown, Release, Debug };
private enum SourceFileSpec {
Unknown = 0,
All,
List,
RegressionTests,
AsmSources,
NotBins,
}
private class CopySpec {
public string SourceDir { get; private set; }
public string DestDir { get; private set; }
public SourceFileSpec FileSpec { get; private set; }
public bool IsRecursive { get; private set; }
public string[] FileList { get; private set; }
public CopySpec(string srcDir, string dstDir, SourceFileSpec spec, bool recursive,
string[] fileList) {
SourceDir = srcDir;
DestDir = dstDir;
FileSpec = spec;
IsRecursive = recursive;
FileList = fileList;
}
}
private static CopySpec[] sMainSpec = {
new CopySpec(".", ".",
SourceFileSpec.List, false, new string[] { "README.md" }),
new CopySpec("Asm65/bin/{BUILD_TYPE}/netstandard2.0/", ".",
SourceFileSpec.List, false, new string[] { "Asm65.dll" }),
new CopySpec("CommonUtil/bin/{BUILD_TYPE}/netstandard2.0/", ".",
SourceFileSpec.List, false, new string[] { "CommonUtil.dll" }),
new CopySpec("CommonWinForms/bin/{BUILD_TYPE}/", ".",
SourceFileSpec.List, false, new string[] { "CommonWinForms.dll" }),
new CopySpec("PluginCommon/bin/{BUILD_TYPE}/netstandard2.0/", ".",
SourceFileSpec.List, false, new string[] { "PluginCommon.dll" }),
new CopySpec("SourceGen/bin/{BUILD_TYPE}/", ".",
SourceFileSpec.List, false, new string[] { "SourceGen.exe" }),
new CopySpec("SourceGen/RuntimeData", "RuntimeData",
SourceFileSpec.NotBins, true, null),
new CopySpec("SourceGen/Examples", "Examples",
SourceFileSpec.All, true, null),
};
private static CopySpec[] sTestSpec = {
new CopySpec("SourceGen/SGTestData", "SGTestData",
SourceFileSpec.RegressionTests, false, null),
new CopySpec("SourceGen/SGTestData", "SGTestData",
SourceFileSpec.List, false, new string[] { "README.md" }),
new CopySpec("SourceGen/SGTestData/Expected", "SGTestData/Expected",
SourceFileSpec.AsmSources, false, null),
new CopySpec("SourceGen/SGTestData/Source", "SGTestData/Source",
SourceFileSpec.AsmSources, false, null),
new CopySpec("SourceGen/SGTestData/FunkyProjects", "SGTestData/FunkyProjects",
SourceFileSpec.All, false, null),
};
private static string sBasePath;
// We want all of the regression test binaries, plus the .sym65, .dis65, and .cs,
// but nothing with an underscore in the part before the extension.
private const string TestCasePattern = @"^\d\d\d\d-[A-Za-z0-9-]+(\..*)?$";
private static Regex sTestCaseRegex = new Regex(TestCasePattern);
private BuildType mBuildType;
private bool mCopyTestFiles;
private BackgroundWorker mWorker;
public FileCopier(BuildType buildType, bool copyTestFiles) {
mBuildType = buildType;
mCopyTestFiles = copyTestFiles;
}
private void ReportProgress(string msg) {
mWorker.ReportProgress(0, new CopyProgress.ProgressMessage(msg + "\r\n"));
// This allows the RichTextBox, which appears to be updated by a low-priority thread,
// to update while we run. If we don't sleep, the window doesn't update until the
// entire run has finished. (Win10, WPF4.5, SSD drive)
System.Threading.Thread.Sleep(5);
}
private void ReportProgress(string msg, Color color) {
mWorker.ReportProgress(0, new CopyProgress.ProgressMessage(msg + "\r\n", color));
}
private void ReportErrMsg(string msg) {
ReportProgress(msg + "\r\n", Colors.Red);
}
/// <summary>
/// Main entry point.
/// </summary>
/// <param name="worker">Background task interface object.</param>
/// <returns>True on success.</returns>
public bool CopyAllFiles(BackgroundWorker worker) {
mWorker = worker;
ReportProgress("Preparing... build type is " + mBuildType + ", test files are " +
(mCopyTestFiles ? "" : "NOT ") + "included.");
ReportProgress(""); // the first CRLF is ignored by RichTextBox??
string buildStr = mBuildType.ToString();
string basePath = FindBasePath();
Debug.Assert(basePath != null);
string distPath = Path.Combine(basePath, "DIST_" + buildStr);
// TODO(maybe): recursively delete distPath
if (!CopySpecList(sMainSpec, basePath, distPath, buildStr)) {
return false;
}
if (mCopyTestFiles) {
if (!CopySpecList(sTestSpec, basePath, distPath, buildStr)) {
return false;
}
}
ReportProgress("Success", Colors.Green);
return true;
}
private bool CopySpecList(CopySpec[] specList, string basePath, string distPath,
string buildStr) {
foreach (CopySpec cs in specList) {
string srcDir = Path.GetFullPath(Path.Combine(basePath,
cs.SourceDir.Replace("{BUILD_TYPE}", buildStr)));
string dstDir = Path.GetFullPath(Path.Combine(distPath, cs.DestDir));
ReportProgress("Scanning [" + cs.FileSpec + "] " + srcDir);
if (!CopyBySpec(srcDir, dstDir, cs.FileSpec, cs.FileList, cs.IsRecursive)) {
return false;
}
}
return true;
}
private bool CopyBySpec(string srcDir, string dstDir, SourceFileSpec sfspec,
string[] specFileList, bool isRecursive) {
if (!EnsureDirectoryExists(dstDir)) {
return false;
}
string[] fileList;
if (sfspec == SourceFileSpec.List) {
fileList = specFileList;
} else {
fileList = Directory.GetFiles(srcDir);
}
foreach (string str in fileList) {
// Spec list is filenames, GetFiles is paths; convert to simple filename.
string fileName = Path.GetFileName(str);
switch (sfspec) {
case SourceFileSpec.All:
case SourceFileSpec.List:
// keep all
break;
case SourceFileSpec.NotBins:
// Mostly this means "skip obj and bin dirs", which happens later.
// Rather than specify everything we do want, just omit this one thing.
if (fileName == "RuntimeData.csproj") {
continue;
}
break;
case SourceFileSpec.AsmSources:
if (!fileName.ToUpperInvariant().EndsWith(".S")) {
continue;
}
break;
case SourceFileSpec.RegressionTests:
MatchCollection matches = sTestCaseRegex.Matches(fileName);
if (matches.Count != 1) {
continue;
}
// Could probably do this with regex... but why.
if (fileName.StartsWith("1") && fileName.EndsWith(".dis65")) {
continue;
}
break;
default:
throw new Exception("Unsupported spec " + sfspec);
}
string srcPath = Path.Combine(srcDir, fileName);
string dstPath = Path.Combine(dstDir, fileName);
if (!CopyFile(srcPath, dstPath)) {
return false;
}
}
if (isRecursive) {
string[] dirList = Directory.GetDirectories(srcDir);
foreach (string str in dirList) {
string dirFileName = Path.GetFileName(str);
if (sfspec == SourceFileSpec.NotBins &&
(dirFileName == "obj" || dirFileName == "bin")) {
continue;
}
if (!CopyBySpec(Path.Combine(srcDir, dirFileName),
Path.Combine(dstDir, dirFileName),
sfspec, specFileList, isRecursive)) {
return false;
}
}
}
return true;
}
private bool EnsureDirectoryExists(string dirPath) {
if (Directory.Exists(dirPath)) {
return true;
}
if (File.Exists(dirPath)) {
ReportErrMsg("File exists and is not directory: " + dirPath);
return false;
}
try {
Directory.CreateDirectory(dirPath);
ReportProgress(" Created " + dirPath);
} catch (Exception ex) {
ReportErrMsg("Failed creating directory " + dirPath + ": " + ex.Message);
return false;
}
return true;
}
private bool CopyFile(string srcPath, string dstPath) {
// Poll cancel button.
if (mWorker.CancellationPending) {
ReportErrMsg("Cancel\r\n");
return false;
}
ReportProgress(" Copy " + srcPath + " --> " + dstPath);
try {
File.Copy(srcPath, dstPath, true);
} catch (Exception ex) {
ReportErrMsg("Failed: " + ex.Message);
return false;
}
return true;
}
/// <summary>
/// Returns the base directory of the 6502bench installation.
/// </summary>
/// <returns></returns>
private static string FindBasePath() {
if (sBasePath != null) {
return sBasePath;
}
string exeName = Process.GetCurrentProcess().MainModule.FileName;
string baseDir = Path.GetDirectoryName(exeName);
if (string.IsNullOrEmpty(baseDir)) {
return null;
}
string tryPath;
// Use the SourceGen directory as a sentinel.
tryPath = Path.Combine(baseDir, SOURCEGEN_DIRNAME);
if (Directory.Exists(tryPath)) {
sBasePath = Path.GetFullPath(tryPath);
return sBasePath;
}
string upThree = Path.GetDirectoryName(
Path.GetDirectoryName(Path.GetDirectoryName(baseDir)));
tryPath = Path.Combine(upThree, SOURCEGEN_DIRNAME);
if (Directory.Exists(tryPath)) {
sBasePath = Path.GetFullPath(upThree);
return sBasePath;
}
Debug.WriteLine("Unable to find RuntimeData dir near " + exeName);
return null;
}
}
}

View File

@ -0,0 +1,53 @@
<!--
Copyright 2019 faddenSoft
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Window x:Class="MakeDistWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MakeDistWPF"
mc:Ignorable="d"
Title="6502bench Distribution Maker"
SizeToContent="WidthAndHeight" ResizeMode="NoResize">
<StackPanel Margin="8">
<TextBlock>This program gathers up all the files needed for a 6502bench distribution. A</TextBlock>
<TextBlock>full debug or release build should be performed before running this.</TextBlock>
<Grid Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GroupBox Grid.Column="0" Header="Distribution Type">
<StackPanel>
<RadioButton Content="Release" Margin="0,4,0,0" IsChecked="{Binding IsReleaseChecked}"/>
<RadioButton Content="Debug" Margin="0,4,0,0" IsChecked="{Binding IsDebugChecked}"/>
</StackPanel>
</GroupBox>
<Button Grid.Column="1" Content="BUILD" FontWeight="Bold" Margin="12"
Click="BuildButton_Click"/>
</Grid>
<DockPanel LastChildFill="False">
<CheckBox Content="Include regression test files" Margin="0,8,0,0"
IsChecked="{Binding DoIncludeRegressionTests}"/>
<Button DockPanel.Dock="Right" Content="Close" IsCancel="True" Width="70" Margin="0,5,0,0"
Click="CloseButton_Click"/>
</DockPanel>
</StackPanel>
</Window>

View File

@ -0,0 +1,75 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows;
namespace MakeDistWPF {
/// <summary>
/// Distribution maker.
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged {
public bool IsReleaseChecked {
get { return mIsReleaseChecked; }
set { mIsReleaseChecked = value; OnPropertyChanged(); }
}
private bool mIsReleaseChecked;
public bool IsDebugChecked {
get { return mIsDebugChecked; }
set { mIsDebugChecked = value; OnPropertyChanged(); }
}
private bool mIsDebugChecked;
public bool DoIncludeRegressionTests {
get { return mDoIncludeRegressionTests; }
set { mDoIncludeRegressionTests = value; OnPropertyChanged(); }
}
private bool mDoIncludeRegressionTests;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainWindow() {
InitializeComponent();
DataContext = this;
IsReleaseChecked = true;
}
private void BuildButton_Click(object sender, RoutedEventArgs e) {
Debug.WriteLine("rel=" + IsReleaseChecked + " dbg=" + IsDebugChecked +
" incl=" + DoIncludeRegressionTests);
FileCopier.BuildType buildType;
if (IsReleaseChecked) {
buildType = FileCopier.BuildType.Release;
} else {
buildType = FileCopier.BuildType.Debug;
}
bool copyTestFiles = DoIncludeRegressionTests;
CopyProgress dlg = new CopyProgress(this, buildType, copyTestFiles);
dlg.ShowDialog();
}
private void CloseButton_Click(object sender, RoutedEventArgs e) {
Close();
}
}
}

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D9A0BD5E-8CA8-4207-81C8-DDF4BE6AB02A}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>MakeDistWPF</RootNamespace>
<AssemblyName>MakeDistWPF</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="CopyProgress.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="CopyProgress.xaml.cs">
<DependentUpon>CopyProgress.xaml</DependentUpon>
</Compile>
<Compile Include="FileCopier.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonWPF\CommonWPF.csproj">
<Project>{1299aa2e-606d-4f3e-b3a9-3f9421e44667}</Project>
<Name>CommonWPF</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MakeDistWPF")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MakeDistWPF")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[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)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MakeDistWPF.Properties {
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MakeDistWPF.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MakeDistWPF.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -32,6 +32,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenWPF", "SourceGenWP
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonWPF", "CommonWPF\CommonWPF.csproj", "{1299AA2E-606D-4F3E-B3A9-3F9421E44667}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MakeDistWPF", "MakeDistWPF\MakeDistWPF.csproj", "{D9A0BD5E-8CA8-4207-81C8-DDF4BE6AB02A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -78,6 +80,10 @@ Global
{1299AA2E-606D-4F3E-B3A9-3F9421E44667}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1299AA2E-606D-4F3E-B3A9-3F9421E44667}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1299AA2E-606D-4F3E-B3A9-3F9421E44667}.Release|Any CPU.Build.0 = Release|Any CPU
{D9A0BD5E-8CA8-4207-81C8-DDF4BE6AB02A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9A0BD5E-8CA8-4207-81C8-DDF4BE6AB02A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9A0BD5E-8CA8-4207-81C8-DDF4BE6AB02A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9A0BD5E-8CA8-4207-81C8-DDF4BE6AB02A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE