Updated screen shots with latest code; fixed typo; when creating a ne… (#11)
* Updated screen shots with latest code; fixed typo; when creating a new job, you can specify custom HTTP headers * Fixing whitespace issue + tooltip * Add \r\n to the start of custom headers when they are more than 1 line long. This improves the appearance of the output
|
@ -112,13 +112,13 @@ namespace BITSManager
|
|||
Error.GetErrorDescription((uint)langid, out ErrorDescription);
|
||||
Error.GetErrorContextDescription((uint)langid, out ErrorContextDescription);
|
||||
|
||||
var errorText = String.Format ("\t{0} \t0x{1:X08}\n\t{2} \t{3}{4}\t{5} \t{6}",
|
||||
Properties.Resources.JobErrorHRESULT,
|
||||
var errorText = String.Format("\t{0} \t0x{1:X08}\n\t{2} \t{3}{4}\t{5} \t{6}",
|
||||
Properties.Resources.JobErrorHRESULT,
|
||||
ErrorHRESULT,
|
||||
Properties.Resources.JobErrorDescription,
|
||||
Properties.Resources.JobErrorDescription,
|
||||
ErrorDescription,
|
||||
ErrorDescription.EndsWith("\n") ? "" : "\n",
|
||||
Properties.Resources.JobErrorContext,
|
||||
Properties.Resources.JobErrorContext,
|
||||
ErrorContextDescription
|
||||
);
|
||||
_uiJobError.Text = errorText;
|
||||
|
@ -247,8 +247,10 @@ namespace BITSManager
|
|||
try
|
||||
{
|
||||
httpOptions.GetCustomHeaders(out customHeaders);
|
||||
var headers = customHeaders ?? Properties.Resources.JobCustomHeadersNotSet;
|
||||
headers = TabifyHttpHeaders.AddTabs(headers);
|
||||
var headers = customHeaders == null
|
||||
? Properties.Resources.JobCustomHeadersNotSet
|
||||
: TabifyHttpHeaders.AddTabs(TabifyHttpHeaders.PrependCRLF(customHeaders))
|
||||
;
|
||||
_uiJobCustomHeaders.Text = headers;
|
||||
}
|
||||
catch (System.Runtime.InteropServices.COMException ex)
|
||||
|
|
|
@ -378,6 +378,33 @@ namespace BITSManager.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Add.
|
||||
/// </summary>
|
||||
public static string JobAddHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("JobAddHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Adds the custom HTTP header.
|
||||
/// </summary>
|
||||
public static string JobAddHeaderToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("JobAddHeaderToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to All custom HTTP headers.
|
||||
/// </summary>
|
||||
public static string JobAllCustomHeaders {
|
||||
get {
|
||||
return ResourceManager.GetString("JobAllCustomHeaders", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Allow implicit proxy credentials.
|
||||
/// </summary>
|
||||
|
@ -513,6 +540,24 @@ namespace BITSManager.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Clear.
|
||||
/// </summary>
|
||||
public static string JobClearHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("JobClearHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Clear the custom headers.
|
||||
/// </summary>
|
||||
public static string JobClearHeaderToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("JobClearHeaderToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cost .
|
||||
/// </summary>
|
||||
|
@ -586,7 +631,7 @@ namespace BITSManager.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Custom HTTP.
|
||||
/// Looks up a localized string similar to Custom HTTP Headers.
|
||||
/// </summary>
|
||||
public static string JobCustomHeaders {
|
||||
get {
|
||||
|
@ -621,6 +666,15 @@ namespace BITSManager.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Add custom HTTP headers.
|
||||
/// </summary>
|
||||
public static string JobCustomHeadersTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("JobCustomHeadersTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Description.
|
||||
/// </summary>
|
||||
|
|
|
@ -318,7 +318,7 @@
|
|||
<comment>One of the Job properties</comment>
|
||||
</data>
|
||||
<data name="JobCustomHeaders" xml:space="preserve">
|
||||
<value>Custom HTTP</value>
|
||||
<value>Custom HTTP Headers</value>
|
||||
<comment>One of the Job properties</comment>
|
||||
</data>
|
||||
<data name="JobCustomHeadersException" xml:space="preserve">
|
||||
|
@ -704,4 +704,28 @@ Version {0}</value>
|
|||
<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>
|
||||
<data name="JobCustomHeadersTitle" xml:space="preserve">
|
||||
<value>Add custom HTTP headers</value>
|
||||
<comment>Title of the text box for entering custom HTTP headers</comment>
|
||||
</data>
|
||||
<data name="JobAddHeader" xml:space="preserve">
|
||||
<value>Add</value>
|
||||
<comment>Button content for adding headers</comment>
|
||||
</data>
|
||||
<data name="JobAddHeaderToolTip" xml:space="preserve">
|
||||
<value>Adds the custom HTTP header</value>
|
||||
<comment>Hover text for adding a custom HTTP header to a job</comment>
|
||||
</data>
|
||||
<data name="JobAllCustomHeaders" xml:space="preserve">
|
||||
<value>All custom HTTP headers</value>
|
||||
<comment>Header for the textblock with all custom HTTP headers</comment>
|
||||
</data>
|
||||
<data name="JobClearHeader" xml:space="preserve">
|
||||
<value>Clear</value>
|
||||
<comment>Button for clearing the custom HTTP headers</comment>
|
||||
</data>
|
||||
<data name="JobClearHeaderToolTip" xml:space="preserve">
|
||||
<value>Clear the custom headers</value>
|
||||
<comment>Hover text for clearing the custom HTTP headers</comment>
|
||||
</data>
|
||||
</root>
|
|
@ -218,7 +218,7 @@ namespace BITSManager
|
|||
|
||||
public void JobModification(BITS.IBackgroundCopyJob pJob, uint dwReserved)
|
||||
{
|
||||
// JobModification has to exist to satify the interface. But unless
|
||||
// JobModification has to exist to satisfy the interface. But unless
|
||||
// the call to job.SetNotifyInterface includes the BG_NOTIFY_JOB_MODIFICATION flag,
|
||||
// this method won't be called.
|
||||
}
|
||||
|
|
|
@ -49,5 +49,19 @@ Licensed under the MIT License.
|
|||
<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}" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{x:Static p:Resources.JobCustomHeadersTitle}" x:Name="_uiJobCustomHeadersHeader" />
|
||||
<Button Grid.Column="1" Content="{x:Static p:Resources.JobAddHeader}" ToolTip="{x:Static p:Resources.JobAddHeaderToolTip}" Click="OnAddNewCustomHeader" />
|
||||
<Button Grid.Column="2" Content="{x:Static p:Resources.JobClearHeader}" ToolTip="{x:Static p:Resources.JobClearHeaderToolTip}" Click="OnClearCustomHeaders" Margin="2,0,0,0" />
|
||||
|
||||
</Grid>
|
||||
<TextBox x:Name="_uiNewCustomHeader" HorizontalAlignment="Stretch" AutomationProperties.LabeledBy="{Binding ElementName=_uiJobCustomHeadersHeader}" />
|
||||
<TextBlock Text="{x:Static p:Resources.JobAllCustomHeaders}" x:Name="_uiJobCustomHeadersAllHeader" />
|
||||
<TextBlock x:Name="_uiCustomHeadersAll" HorizontalAlignment="Stretch" AutomationProperties.LabeledBy="{Binding ElementName=_uiJobCustomHeadersAllHeader}" MinHeight="50" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Windows.Controls;
|
|||
|
||||
// Set up the needed BITS namespaces
|
||||
using BITS = BITSReference1_5;
|
||||
using BITS4 = BITSReference4_0;
|
||||
using BITS5 = BITSReference5_0;
|
||||
|
||||
namespace BITSManager
|
||||
|
@ -23,6 +24,7 @@ namespace BITSManager
|
|||
{
|
||||
var job2 = (BITS.IBackgroundCopyJob2)job; // Job2 exists on all supported version of Windows.
|
||||
var job5 = job as BITS5.IBackgroundCopyJob5; // Job5 will be null on, e.g., Windows 7 and earlier.
|
||||
var jobHttpOptions = job as BITS4.IBackgroundCopyJobHttpOptions;
|
||||
|
||||
if (job5 != null)
|
||||
{
|
||||
|
@ -52,6 +54,15 @@ namespace BITSManager
|
|||
}
|
||||
}
|
||||
|
||||
if (jobHttpOptions != null)
|
||||
{
|
||||
var text = _uiCustomHeadersAll.Text;
|
||||
if (!String.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
jobHttpOptions.SetCustomHeaders(text);
|
||||
}
|
||||
}
|
||||
|
||||
var priority = _jobPriority;
|
||||
if (priority.HasValue)
|
||||
{
|
||||
|
@ -159,5 +170,16 @@ namespace BITSManager
|
|||
return (BITS.BG_JOB_PRIORITY)value;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClearCustomHeaders(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
_uiCustomHeadersAll.Text = "";
|
||||
}
|
||||
|
||||
private void OnAddNewCustomHeader(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
var newHeader = _uiNewCustomHeader.Text + "\r\n";
|
||||
_uiCustomHeadersAll.Text += newHeader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BITSManager
|
||||
|
@ -77,5 +78,21 @@ namespace BITSManager
|
|||
}
|
||||
return tabs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a string, prepend a \r\n if the string is a multi-line string.
|
||||
/// Multi-line means that the string has more than 1 \n character.
|
||||
/// </summary>
|
||||
/// <param name="text">Input text (can be null)</param>
|
||||
/// <returns>Returns either the original text OR the original text prepended with \r\n</returns>
|
||||
public static string PrependCRLF(string text)
|
||||
{
|
||||
if (text == null) return text;
|
||||
// Note that the customHeaders use \r\n per the HTTP specs.
|
||||
// What's displayed to the user also uses \r\n
|
||||
var nline = text.Count(f => f == '\n');
|
||||
text = nline > 1 ? "\r\n" + text : text;
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,5 +51,18 @@ namespace BITSManager.Tests
|
|||
Assert.AreEqual(" ", TabifyHttpHeaders.GetAlignedSpaces(-1));
|
||||
Assert.AreEqual(" ", TabifyHttpHeaders.GetAlignedSpaces(-99999999));
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void PrependCRLFTest()
|
||||
{
|
||||
Assert.AreEqual(TabifyHttpHeaders.PrependCRLF(null), null);
|
||||
Assert.AreEqual(TabifyHttpHeaders.PrependCRLF(""), "");
|
||||
Assert.AreEqual(TabifyHttpHeaders.PrependCRLF("abc"), "abc");
|
||||
Assert.AreEqual(TabifyHttpHeaders.PrependCRLF("abc\rdef\rghi"), "abc\rdef\rghi");
|
||||
Assert.AreEqual(TabifyHttpHeaders.PrependCRLF("abc\ndef"), "abc\ndef");
|
||||
Assert.AreEqual(TabifyHttpHeaders.PrependCRLF("abc\ndef\nghi"), "\r\nabc\ndef\nghi");
|
||||
|
||||
Assert.Fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Двоичные данные
Screenshots/BITSManagerOverview-Annotated.png
До Ширина: | Высота: | Размер: 97 KiB После Ширина: | Высота: | Размер: 147 KiB |
Двоичные данные
Screenshots/v01_Menu_Jobs.png
До Ширина: | Высота: | Размер: 89 KiB После Ширина: | Высота: | Размер: 254 KiB |
Двоичные данные
Screenshots/v01_QuickFileDownload.png
До Ширина: | Высота: | Размер: 46 KiB После Ширина: | Высота: | Размер: 46 KiB |
Двоичные данные
Screenshots/v01_State_Acknowledged.png
До Ширина: | Высота: | Размер: 86 KiB После Ширина: | Высота: | Размер: 244 KiB |
Двоичные данные
Screenshots/v01_State_Connecting.png
До Ширина: | Высота: | Размер: 129 KiB После Ширина: | Высота: | Размер: 91 KiB |
Двоичные данные
Screenshots/v01_State_Transferred.png
До Ширина: | Высота: | Размер: 86 KiB После Ширина: | Высота: | Размер: 103 KiB |