Pesmith master/continue with code polish changes (#10)

* Updating screen and header sizes to be more consistant. Many common BITS jobs will now neatly fit into the screen without wrapping.

* Checking in installer and bumped the assembly version number

* BITS Manager may be used outside of Microsoft

* Fixed typo in .wxs file and .ps1 should work on Win32 machines

* Installer creates a shortcut that allows BITS Manager to run as admin (requires substantial changes to installer); fixed incorrect XAML reference to renamed UI elements for automation; added the installer files to the project so that Visual Studio can diff them more easily (the installer doesn't run from VS)

* Including Installer files in the CSPROJ (allows for easier diffs when the installer files change) and added a catch for UnauthorizedAccessException for getting custom headers (you can't get the custom headers of e.g. system jobs)

* Updated with improved assembly version scheme

* Updating XAML UI files based on Narrator feedback; text boxes and combo boxes are now named based on their headers.

* Per Diego's comment, changed all URI/URL to be Uri for System.Uri items and Url for everything else. BITS terminology is URL (it's also the most common name outside of Microsoft)
This commit is contained in:
Peter Smith 2019-01-04 09:59:40 -08:00 коммит произвёл GitHub
Родитель fdd514578e
Коммит 68b27666bd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 151 добавлений и 47 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
Installer/BITSManager.msi
# User-specific files
*.suo
*.user

Просмотреть файл

@ -14,11 +14,13 @@ Licensed under the MIT License.
ShowInTaskbar="False">
<Border Margin="2">
<StackPanel VerticalAlignment="Stretch">
<TextBlock Text="{x:Static p:Resources.DialogUrl}" />
<TextBox x:Name="_uiUri" HorizontalAlignment="Stretch" Margin="20,0,0,0" TabIndex="1" TextChanged="OnUriChanged" />
<TextBlock Text="{x:Static p:Resources.DialogUrl}" x:Name="_uiUrlHeader" />
<TextBox x:Name="_uiUrl" HorizontalAlignment="Stretch" Margin="20,0,0,0" TabIndex="1" TextChanged="OnUrlChanged"
AutomationProperties.LabeledBy="{Binding ElementName=_uiUrlHeader}"/>
<TextBlock Text="{x:Static p:Resources.DialogFile}" />
<TextBox x:Name="_uiFile" Margin="20,0,0,0" HorizontalAlignment="Stretch" TabIndex="2" KeyDown="OnFileChangedViaKeyboard" />
<TextBlock Text="{x:Static p:Resources.DialogFile}" x:Name="_uiFileHeader" />
<TextBox x:Name="_uiFile" Margin="20,0,0,0" HorizontalAlignment="Stretch" TabIndex="2" KeyDown="OnFileChangedViaKeyboard"
AutomationProperties.LabeledBy="{Binding ElementName=_uiFileHeader}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,20,0,0">
<Button Content="{x:Static p:Resources.DialogOK}" IsDefault="True" Click="OnOK" MinWidth="60" TabIndex="3" />

Просмотреть файл

@ -12,7 +12,7 @@ namespace BITSManager
/// </summary>
public partial class AddFileToJobWindow : Window
{
public string RemoteUri { get { return _uiUri.Text; } }
public string RemoteUrl { get { return _uiUrl.Text; } }
public string LocalFile { get { return _uiFile.Text; } }
private bool _fileHasChanged = false;
@ -24,7 +24,7 @@ namespace BITSManager
private void AddFileToJobWindowControl_Loaded(object sender, RoutedEventArgs e)
{
_uiUri.Focus();
_uiUrl.Focus();
}
private void OnCancel(object sender, RoutedEventArgs e)
@ -37,11 +37,11 @@ namespace BITSManager
DialogResult = true;
}
private void OnUriChanged(object sender, TextChangedEventArgs e)
private void OnUrlChanged(object sender, TextChangedEventArgs e)
{
string newUriText = _uiUri.Text;
string newUrlText = _uiUrl.Text;
Uri uri;
var parseSucceeded = Uri.TryCreate(newUriText, UriKind.Absolute, out uri);
var parseSucceeded = Uri.TryCreate(newUrlText, UriKind.Absolute, out uri);
if (parseSucceeded && uri.Segments.Length >= 1 && !_fileHasChanged)
{
// Make a corresponding file name. If the user has changed the file text,

Просмотреть файл

@ -204,6 +204,12 @@ Licensed under the MIT License.
<Link>README.md</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="..\Installer\BITSManager.wxs">
<Link>InstallerFiles\BITSManager.wxs</Link>
</None>
<None Include="..\Installer\MakeInstaller.ps1">
<Link>InstallerFiles\MakeInstaller.ps1</Link>
</None>
<None Include="BITSManager_TemporaryKey.pfx" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>

Просмотреть файл

@ -15,10 +15,11 @@ Licensed under the MIT License.
ShowInTaskbar="False">
<Border Margin="2">
<StackPanel VerticalAlignment="Stretch" Margin="20,10,20,10">
<TextBlock Text="{x:Static p:Resources.CreateNewJobJobName}" />
<TextBox x:Name="_uiJobName" HorizontalAlignment="Stretch" TabIndex="1" />
<TextBlock Text="{x:Static p:Resources.CreateNewJobJobType}" Margin="0,10,0,0" />
<ComboBox SelectedIndex="0" x:Name="_uiJobType" MinWidth="250" HorizontalAlignment="Left">
<TextBlock Text="{x:Static p:Resources.CreateNewJobJobName}" x:Name="_uiJobNameHeader" />
<TextBox x:Name="_uiJobName" HorizontalAlignment="Stretch" TabIndex="1" AutomationProperties.LabeledBy="{Binding ElementName=_uiJobNameHeader}" />
<TextBlock Text="{x:Static p:Resources.CreateNewJobJobType}" Margin="0,10,0,0" x:Name="_uiJobTypeHeader" />
<ComboBox SelectedIndex="0" x:Name="_uiJobType" MinWidth="250" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=_uiJobTypeHeader}">
<!-- Tag values should not be localized -->
<ComboBoxItem Tag="Download" Content="{x:Static p:Resources.JobTypeDownload}" />
<ComboBoxItem Tag="Upload" Content="{x:Static p:Resources.JobTypeUpload}" />

Просмотреть файл

@ -257,6 +257,12 @@ namespace BITSManager
Properties.Resources.JobCustomHeadersException,
ex.Message);
}
catch (System.UnauthorizedAccessException ex)
{
_uiJobCustomHeaders.Text = String.Format(
Properties.Resources.JobCustomHeadersException,
ex.Message);
}
}
// Update the list of files associated with the job.

Просмотреть файл

@ -9,7 +9,7 @@ Licensed under the MIT License.
xmlns:local="clr-namespace:BITSManager"
xmlns:p="clr-namespace:BITSManager.Properties"
mc:Ignorable="d"
Title="{x:Static p:Resources.Title}" Height="450" Width="800">
Title="{x:Static p:Resources.Title}" Height="450" Width="900">
<Window.CommandBindings>
<CommandBinding Command="{x:Static local:MainWindow.QuickFileDownloadCommand}" Executed="OnMenuJobQuickFileDownload" />
</Window.CommandBindings>
@ -53,14 +53,14 @@ Licensed under the MIT License.
<ListView Grid.Row="2" Grid.Column="0" x:Name="_uiJobList"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch"
SelectionMode="Single" SelectionChanged="OnJobSelectionChanged"
AutomationProperties.LabeledBy="{Binding ElementName=uiJobListHeader}"
AutomationProperties.LabeledBy="{Binding ElementName=_uiJobListHeader}"
IsTabStop="True">
</ListView>
<!-- The selected job details -->
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="_uiJobDetailHeader" Text="{x:Static p:Resources.JobDetails}" FontSize="18" FontWeight="Bold" />
<local:JobDetailViewControl Grid.Row="2" Grid.Column="1" x:Name="_uiJobDetails"
AutomationProperties.LabeledBy="{Binding ElementName=uiJobDetailHeader}"
AutomationProperties.LabeledBy="{Binding ElementName=_uiJobDetailHeader}"
IsTabStop="True" />
</Grid>
</Window>

Просмотреть файл

@ -443,13 +443,13 @@ namespace BITSManager
var result = dlg.ShowDialog();
if (result.HasValue && result.Value)
{
var remoteUri = dlg.RemoteUri;
var remoteUrl = dlg.RemoteUrl;
var localFile = dlg.LocalFile;
if (!string.IsNullOrEmpty(remoteUri) && !string.IsNullOrEmpty(localFile))
if (!string.IsNullOrEmpty(remoteUrl) && !string.IsNullOrEmpty(localFile))
{
try
{
job.AddFile(remoteUri, localFile);
job.AddFile(remoteUrl, localFile);
}
catch (System.Runtime.InteropServices.COMException ex)
{

Просмотреть файл

@ -47,5 +47,7 @@ using System.Windows;
// 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.7.1.30")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// BITS Manager uses the AssemblyVersion for the Help-->About dialog and the AssemblyFileVersion
// for the installer version. Always update both numbers.
[assembly: AssemblyVersion("1.11.0.4")]
[assembly: AssemblyFileVersion("1.11.0.4")]

2
BITSManager/Properties/Resources.Designer.cs сгенерированный
Просмотреть файл

@ -514,7 +514,7 @@ namespace BITSManager.Properties {
}
/// <summary>
/// Looks up a localized string similar to Cost.
/// Looks up a localized string similar to Cost .
/// </summary>
public static string JobCost {
get {

Просмотреть файл

@ -289,10 +289,6 @@
<value>Error: Unable to add file</value>
<comment>Title of message box when a file can't be added to a job</comment>
</data>
<data name="JobCost" xml:space="preserve">
<value>Cost</value>
<comment>One of the Job properties</comment>
</data>
<data name="JobCostAlways" xml:space="preserve">
<value>Always</value>
<comment>One of the Job cost property values</comment>
@ -704,4 +700,8 @@ Version {0}</value>
<value>Allow implicit proxy credentials</value>
<comment>One of the Job properties</comment>
</data>
<data name="JobCost" xml:space="preserve">
<value>Cost </value>
<comment>One of the Job properties. There are 10 extra spaces so that the field values line up neatly. For EN-US, any number of spaces from 7 to 20 results in good alignment; the value will be different in different languages and fonts.</comment>
</data>
</root>

Просмотреть файл

@ -15,11 +15,13 @@ Licensed under the MIT License.
ShowInTaskbar="False">
<Border Margin="2">
<StackPanel Margin="20,10,20,10">
<TextBlock Text="{x:Static p:Resources.DialogUrl}" />
<TextBox x:Name="_uiUri" HorizontalAlignment="Stretch" TabIndex="1" TextChanged="OnUriChanged" />
<TextBlock Text="{x:Static p:Resources.DialogUrl}" x:Name="_uiUrlHeader" />
<TextBox x:Name="_uiUrl" HorizontalAlignment="Stretch" TabIndex="1" TextChanged="OnUrlChanged"
AutomationProperties.LabeledBy="{Binding ElementName=_uiUrlHeader}"/>
<TextBlock Text="{x:Static p:Resources.DialogFile}" />
<TextBox x:Name="_uiFile" HorizontalAlignment="Stretch" TabIndex="2" KeyDown="OnFileChangedViaKeyboard" />
<TextBlock Text="{x:Static p:Resources.DialogFile}" x:Name="_uiFileHeader" />
<TextBox x:Name="_uiFile" HorizontalAlignment="Stretch" TabIndex="2" KeyDown="OnFileChangedViaKeyboard"
AutomationProperties.LabeledBy="{Binding ElementName=_uiFileHeader}"/>
<Expander Header="{x:Static p:Resources.DialogMoreProperties}">
<local:SetJobPropertyControl x:Name="_uiJobProperty" Margin="0,16,0,0" />

Просмотреть файл

@ -38,7 +38,7 @@ namespace BITSManager
private void QuickFileDownloadControl_Loaded(object sender, RoutedEventArgs e)
{
_uiUri.Focus();
_uiUrl.Focus();
}
private void OnCancel(object sender, RoutedEventArgs e)
@ -50,7 +50,7 @@ namespace BITSManager
{
Job = null; // Clear out the old value, if any.
DialogResult = true;
if (String.IsNullOrEmpty(_uiUri.Text))
if (String.IsNullOrEmpty(_uiUrl.Text))
{
MessageBox.Show(Properties.Resources.ErrorEmptyRemoteUrl, Properties.Resources.ErrorTitle);
return;
@ -60,14 +60,14 @@ namespace BITSManager
MessageBox.Show(Properties.Resources.ErrorEmptyLocalFile, Properties.Resources.ErrorTitle);
return;
}
Job = DownloadFile(_uiUri.Text, _uiFile.Text);
Job = DownloadFile(_uiUrl.Text, _uiFile.Text);
}
private void OnUriChanged(object sender, TextChangedEventArgs e)
private void OnUrlChanged(object sender, TextChangedEventArgs e)
{
string newUriText = _uiUri.Text;
string newUrlText = _uiUrl.Text;
Uri uri;
var createSucceeded = Uri.TryCreate(newUriText, UriKind.Absolute, out uri);
var createSucceeded = Uri.TryCreate(newUrlText, UriKind.Absolute, out uri);
if (createSucceeded && uri.Segments.Length >= 1 && !_fileHasChangedViaKeyboard)
{
// Make a corresponding file name. If the user has changed the file text,

Просмотреть файл

@ -12,8 +12,9 @@ Licensed under the MIT License.
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel>
<TextBlock Text="{x:Static p:Resources.JobCost}" />
<ComboBox x:Name="_uiCosts" SelectedIndex="-1" MinWidth="200" HorizontalAlignment="Left">
<TextBlock Text="{x:Static p:Resources.JobCost}" x:Name="_uiJobCostHeader" />
<ComboBox x:Name="_uiCosts" SelectedIndex="-1" MinWidth="200" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=_uiJobCostHeader}">
<!-- The cost tags values are my own enum value that matches the BITS enum. -->
<ComboBoxItem Tag="{x:Static conversions:BitsCosts.TRANSFER_ALWAYS}" Content="{x:Static p:Resources.JobCostAlways}" />
<ComboBoxItem Tag="{x:Static conversions:BitsCosts.TRANSFER_NOT_ROAMING}" Content="{x:Static p:Resources.JobCostNotRoaming}" />
@ -21,8 +22,9 @@ Licensed under the MIT License.
<ComboBoxItem Tag="{x:Static conversions:BitsCosts.TRANSFER_STANDARD}" Content="{x:Static p:Resources.JobCostStandard}" />
<ComboBoxItem Tag="{x:Static conversions:BitsCosts.TRANSFER_UNRESTRICTED}" Content="{x:Static p:Resources.JobCostUnrestricted}" />
</ComboBox>
<TextBlock Text="{x:Static p:Resources.JobPriority}" />
<ComboBox x:Name="_uiPriority" SelectedIndex="-1" MinWidth="200" HorizontalAlignment="Left">
<TextBlock Text="{x:Static p:Resources.JobPriority}" x:Name="_uiJobPriorityHeader" />
<ComboBox x:Name="_uiPriority" SelectedIndex="-1" MinWidth="200" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=_uiJobPriorityHeader}">
<!-- The priority tags match the BITS enum values. -->
<ComboBoxItem Tag="0" Content="{x:Static p:Resources.JobPriorityForeground}" />
<ComboBoxItem Tag="1" Content="{x:Static p:Resources.JobPriorityHigh}" />
@ -32,8 +34,9 @@ Licensed under the MIT License.
<CheckBox x:Name="_uiDynamic" Content="{x:Static p:Resources.JobPropertyDynamic}" IsChecked="{x:Null}" />
<CheckBox x:Name="_uiHighPerformance" Content="{x:Static p:Resources.JobPropertyHighPerformance}" IsChecked="{x:Null}" />
<TextBlock Text="{x:Static p:Resources.JobAuthScheme}" Margin="0,10,0,0" />
<ComboBox x:Name="_uiAuthScheme" SelectedIndex="-1" MinWidth="200" HorizontalAlignment="Left">
<TextBlock Text="{x:Static p:Resources.JobAuthScheme}" Margin="0,10,0,0" x:Name="_uiJobAuthSchemeHeader" />
<ComboBox x:Name="_uiAuthScheme" SelectedIndex="-1" MinWidth="200" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=_uiJobAuthSchemeHeader}">
<!-- The auth scheme tags match the BITS enum values. -->
<ComboBoxItem Tag="0" Content="{x:Static p:Resources.JobAuthSchemeBasic}" />
<ComboBoxItem Tag="1" Content="{x:Static p:Resources.JobAuthSchemeDigest}" />
@ -42,9 +45,9 @@ Licensed under the MIT License.
<ComboBoxItem Tag="4" Content="{x:Static p:Resources.JobAuthSchemePassport}" />
</ComboBox>
<CheckBox x:Name="_uiAuthProxyImplicit" Content="{x:Static p:Resources.JobAuthProxyImplicit}" IsChecked="{x:Null}" />
<TextBlock Text="{x:Static p:Resources.JobUserName}" />
<TextBox x:Name="_uiUserName" HorizontalAlignment="Stretch" />
<TextBlock Text="{x:Static p:Resources.JobPassword}" />
<TextBox x:Name="_uiPassword" HorizontalAlignment="Stretch" />
<TextBlock Text="{x:Static p:Resources.JobUserName}" x:Name="_uiJobUserNameHeader" />
<TextBox x:Name="_uiUserName" HorizontalAlignment="Stretch" AutomationProperties.LabeledBy="{Binding ElementName=_uiJobUserNameHeader}" />
<TextBlock Text="{x:Static p:Resources.JobPassword}" x:Name="_uiJobPasswordHeader" />
<TextBox x:Name="_uiPassword" HorizontalAlignment="Stretch" AutomationProperties.LabeledBy="{Binding ElementName=_uiJobPasswordHeader}" />
</StackPanel>
</UserControl>

Просмотреть файл

@ -55,7 +55,7 @@ namespace BITSManager
public static string GetAlignedSpaces(int length)
{
const int TabSize = 8;
const int TargetLength = 3 * TabSize;
const int TargetLength = 2 * TabSize;
// Handle the case of length being larger than TargetLength.
// We want some N such that (length + N) % TabSize == 0

37
Installer/BITSManager.wxs Normal file
Просмотреть файл

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Name="BITS Manager" Version="1.11.0.4" Id="*" UpgradeCode="63107792-32df-418d-a9f1-c93b65d7b614" Language="1033" Codepage="1252" Manufacturer="Contoso.com">
<Package Id="*" Keywords="Installer" Description="BITS Manager Installer" InstallerVersion="100" Languages="1033" Compressed="yes" SummaryCodepage="1252" />
<Media Id="1" Cabinet="BITSManager.cab" EmbedCab="yes" DiskPrompt="CD-ROM #1" />
<Property Id="DiskPrompt" Value="BITS Manager Installation [1]" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="BITSMANAGER" Name="BITS Manager">
<Component Id="COMPONENT" Guid="AE10933A-1557-4876-864A-25A2EFD6F2A7">
<File Name="BitsManager.exe" DiskId="1" Source="..\BITSManager\bin\Release\BitsManager.exe" Id="BITSMANAGEREXE" />
<File Name="BITSReference1_5.dll" DiskId="1" Source="..\BITSManager\BITSReferenceDLLs\BITSReference1_5.dll" Id="BITSReference1_5DLL" />
<File Name="BITSReference4_0.dll" DiskId="1" Source="..\BITSManager\BITSReferenceDLLs\BITSReference4_0.dll" Id="BITSReference4_0DLL" />
<File Name="BITSReference5_0.dll" DiskId="1" Source="..\BITSManager\BITSReferenceDLLs\BITSReference5_0.dll" Id="BITSReference5_0DLL" />
<File Name="BITSReference10_1.dll" DiskId="1" Source="..\BITSManager\BITSReferenceDLLs\BITSReference10_1.dll" Id="BITSReference10_1DLL" />
<File Name="BITSReference10_2.dll" DiskId="1" Source="..\BITSManager\BITSReferenceDLLs\BITSReference10_2.dll" Id="BITSReference10_2DLL" />
<File Name="LICENSE" DiskId="1" Source="..\LICENSE" Id="MYAPPLICENSE" />
</Component>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="0B659D35-F420-4652-8438-1802E11F2955">
<Shortcut Id="SHORTCUT_DESKTOP" Name="BITS Manager" Description="Runs the BITS Manager sample program" Target="[BITSMANAGER]BitsManager.exe" WorkingDirectory="INSTALLDIR" Icon="BitsManager.exe" Advertise="no" />
<RemoveFolder Id="DesktopFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software/BITSManager" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Directory>
</Directory>
<Icon Id="BitsManager.exe" SourceFile="..\BITSManager\bin\Release\BITSManager.exe" />
<Property Id="ARPPRODUCTICON" Value="BitsManager.exe" />
<Feature Id="FEATURE" Level="1">
<ComponentRef Id="COMPONENT" />
<ComponentRef Id="ApplicationShortcutDesktop" />
</Feature>
<MajorUpgrade DowngradeErrorMessage="Sorry, you already have a more recent version of this program" />
</Product>
</Wix>

Просмотреть файл

@ -0,0 +1,43 @@
# PowerShell file to rebuild the BITS Manager installer BITSManager.msi
#
# This file will first "stamp" the installer with the BITS Manager AssemblyVersion
# which is taken from AssemblyInfo.cs and put into the .wxs file
#
# The installer toolkit used is WIX, a common open-source
# Windows installer. This file assumes that you have version 3.11.1
# installed from https://github.com/wixtoolset/wix3/releases/tag/wix3111rtm
#
# Learn more about WiX from https://wixtoolset.org
#
$relativeFile="..\BITSManager\bin\Release\BITSManager.exe"
$fullFile=Resolve-Path $relativeFile
$assemblyVersion=[System.Diagnostics.FileVersionInfo]::GetVersionInfo($fullFile).FileVersion
if ("$($assemblyVersion)" -ne "")
{
$wixxml=[xml](get-content ".\BITSManager.wxs")
$wixVersion=$wixxml.Wix.Product.Version
write-host "Extracted original wix version=$($wixVersion)"
write-host "New wix version=$($assemblyVersion)"
$wixxml.Wix.Product.Version=$assemblyVersion
$outfile = "$($(get-location).Path)\BITSManager.wxs"
write-host "Writing to file $($outfile)"
$wixxml.Save($outfile)
}
else
{
write-error "ERROR: unable to get assembly version number"
}
# Make the installer programing using the WiX Toolset.
# The version 3.11 was the most recent when this sample was made.
$WIXDIR="${env:ProgramFiles(x86)}\WiX Toolset v3.11\bin"
& $WIXDIR"\candle.exe" BITSManager.wxs
& $WIXDIR"\light.exe" BITSManager.wixobj
del BITSManager.wixobj
del BITSManager.wixpdb