效果图:
核心代码:
class DownloadService
{
/// <summary> 下载文件 </summary>
/// <param name="URL">下载文件地址</param>
/// <param name="Filename">下载后的存放地址</param>
/// <param name="Prog">用于显示的进度条</param>
///
public static void DownloadFile(string URL, string filename, Action<string, string> percentAction = null, int refreshTime = 1000)
{
float percent = 0;
int total = 0;
int current = 0;
HttpWebRequest Myrq = HttpWebRequest.Create(URL) as HttpWebRequest;
Myrq.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)";
//Myrq.Headers.Add("Token", Token);
HttpWebResponse myrp = (HttpWebResponse)Myrq.GetResponse();
long totalBytes = myrp.ContentLength;
total = (int)totalBytes;
Stream st = myrp.GetResponseStream();
if (File.Exists(filename))
{
///生成时间戳
int index= filename.LastIndexOf('.');
string insertStr="["+ System.Text.RegularExpressions.Regex.Replace(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), @"[^\d]*", "") +"]";
filename=filename.Insert(index, insertStr);
}
Stream so = new FileStream(filename, FileMode.Create);
long totalDownloadedByte = 0;
byte[] by = new byte[1024];
int osize = st.Read(by, 0, (int)by.Length);
// Todo :定时刷新进度
if (percentAction != null)
{
Action action = () =>
{
while (true)
{
Thread.Sleep(refreshTime);
// Todo :返回进度
percentAction(current.ToString(), total.ToString());
if (current == total) break;
}
};
Task task = new Task(action);
task.Start();
}
while (osize > 0)
{
totalDownloadedByte = osize + totalDownloadedByte;
so.Write(by, 0, osize);
current = (int)totalDownloadedByte;
osize = st.Read(by, 0, (int)by.Length);
percent = (float)totalDownloadedByte / (float)totalBytes * 100;
}
so.Close();
st.Close();
}
}
private string Log { get; set; }
private void Download_Click(object sender, RoutedEventArgs e)
{
string URL = @"http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4";
if (string.IsNullOrEmpty(URL))
{
this.Log = "请求的下载地址是空,请检查!";
logTextBlock.Text = Log;
return;
}
this.updataGrid.Visibility = Visibility.Collapsed;
this.progressGrid.Visibility = Visibility.Visible;
string save = "C:\\Update";
if (!Directory.Exists(save))
{
Directory.CreateDirectory(save);
}
string fileName = System.IO.Path.GetFileName(URL);
string savePath = System.IO.Path.Combine(save, fileName);
Action<string, string> action = (current, total) =>
{
this.Dispatcher.Invoke(() =>
{
this.Log = $"正在下载...{FormatBytes(long.Parse(current)).PadLeft(10, ' ')},共计{FormatBytes(long.Parse(total))}";
logTextBlock.Text = Log;
this.progress.Value = (int)((double.Parse(current) / double.Parse(total)) * 100);
if (current == total)
{
this.progress.Value = 100;
Task.Delay(1000).ContinueWith(l =>
{
this.Dispatcher.Invoke(() =>
{
this.Log = $"下载完成!";
logTextBlock.Text = Log;
});
});
var result = MessageBox.Show("是否打开文件?","温馨提示",MessageBoxButton.OKCancel,MessageBoxImage.Question,MessageBoxResult.OK);
if (result==MessageBoxResult.OK)
{
Process.Start(savePath);
}
this.confirmGrid.Visibility = Visibility.Visible;
this.updataGrid.Visibility = Visibility.Collapsed;
this.progressGrid.Visibility = Visibility.Collapsed;
}
});
};
Task.Run(() =>
{
DownloadService.DownloadFile(URL, savePath, action, 1000);
});
}
public static string FormatBytes(long bytes)
{
string[] Suffix = { "Byte", "KB", "MB", "GB", "TB" };
int i = 0;
double dblSByte = bytes;
if (bytes > 1024)
for (i = 0; (bytes / 1024) > 0; i++, bytes /= 1024)
dblSByte = bytes / 1024.0;
return String.Format("{0:0.##}{1}", dblSByte, Suffix[i]);
}
private void Confirm_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
<Window.Resources>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" x:Key="linear">
<GradientStop Offset="0" Color="#FFCF980C"/>
<GradientStop Offset="0.5" Color="#FFC59416"/>
<GradientStop Offset="1" Color="#FFBD8902"/>
</LinearGradientBrush>
<Style TargetType="Button" >
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Foreground" Value="AliceBlue"/>
<Setter Property="Background" Value="{StaticResource linear}"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="0" CornerRadius="5,5,5,5" Background="{StaticResource linear}">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" ></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Height" Value="15"/>
<Setter Property="Background" Value="{StaticResource linear}"/>
<Setter Property="FontSize" Value="10"/>
<Setter Property="Padding" Value="5,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid Background="#00000000">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever">
<PointAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)">
<EasingPointKeyFrame KeyTime="0:0:0" Value="0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:1.5" Value="1.95,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:3" Value="0.5,0.5"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Height="{TemplateBinding Height}">
<Border Background="#000000" CornerRadius="7.5" Opacity="0.05"/>
<Border BorderBrush="#000000" BorderThickness="1" CornerRadius="7.5" Opacity="0.1"/>
<Grid Margin="{TemplateBinding BorderThickness}">
<Border x:Name="PART_Track"/>
<Grid x:Name="PART_Indicator" ClipToBounds="True" HorizontalAlignment="Left" >
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="width1"/>
<ColumnDefinition x:Name="width2" Width="0"/>
</Grid.ColumnDefinitions>
<Grid x:Name="Animation" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" ScaleX="1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Border Background="{TemplateBinding Background}" CornerRadius="7.5">
<Viewbox HorizontalAlignment="Left" StretchDirection="DownOnly" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<TextBlock Foreground="#ffffff" SnapsToDevicePixels="True" FontSize="{TemplateBinding FontSize}" VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Value,StringFormat={}{0}%}" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="1" ScaleX="-1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Viewbox>
</Border>
<Border BorderBrush="#000000" BorderThickness="1" CornerRadius="7.5" Opacity="0.1"/>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#c5c5c5"/>
</Trigger>
<Trigger Property="IsIndeterminate" Value="true">
<Setter TargetName="width1" Property="Width" Value="0.25*"/>
<Setter TargetName="width2" Property="Width" Value="0.725*"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="50" GlassFrameThickness="1" />
</WindowChrome.WindowChrome>
<Grid>
<Border CornerRadius="5" BorderThickness="2" BorderBrush="White" Margin="-3" >
<Border.Effect>
<DropShadowEffect ShadowDepth="1" Color="#FF414141" BlurRadius="8"/>
</Border.Effect>
</Border>
<Grid Height="289" Margin="0 0 0 0">
<Grid.RowDefinitions>
<RowDefinition Height="1.5*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="1 1 1 0" Background="{StaticResource linear}">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="AliceBlue">
<Run Text="发现新版本: V1.2.6" FontSize="24"/>
<LineBreak/>
<LineBreak/>
<Run Text="1、增加了更新提示" FontSize="16"/>
<LineBreak/>
<Run Text="2、增加了换肤功能" FontSize="16"/>
<LineBreak/>
<Run Text="3、优化了部分功能" FontSize="16"/>
</TextBlock>
</Grid>
<Grid Grid.Row="1" x:Name="updataGrid" >
<Button Width="171" Height="38" Content="立即升级" Click="Download_Click" />
</Grid>
<Grid Grid.Row="1" x:Name="progressGrid" Visibility="Collapsed">
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<ProgressBar Width="520" Height="24" x:Name="progress" />
<TextBlock Width="Auto" Text="正在加载中..." Height="38" x:Name="logTextBlock" HorizontalAlignment="Right"
Margin="0 4 10 0 " Foreground="#FF646A70" />
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="confirmGrid" Visibility="Collapsed">
<Button Width="171" Height="38" Content="确认关闭" Click="Confirm_Click" />
</Grid>
</Grid>
</Grid>