Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit 18c165f

Browse files
committed
0.8.2.9
What's new: 1. Task bar progress. 2. Other changes.
1 parent f5d13af commit 18c165f

25 files changed

+287
-114
lines changed
-178 Bytes
Binary file not shown.

.vs/UniversalGUI/v15/.suo

-112 KB
Binary file not shown.

.vs/UniversalGUI/v15/Server/sqlite3/db.lock

Whitespace-only changes.
-848 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.

README.md

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,55 @@
22

33
![001](https://s1.ax1x.com/2018/07/26/Pt7lQO.png)
44

5-
  假设你有一个多核心的CPU(现在谁还用单核!),同时,你有一批图片需要转换为WebP格式,但是WebP的编码器`cwebp`是一个命令行程序,一次只能处理一张图片,并且它**不支持多核**(虽然有`-mt`开关,但是并不怎么管用),怎么办?
5+
假设你有一个多核心的CPU(现在谁还用单核!),同时,你有一批图片需要转换为WebP格式,但是WebP的编码器`cwebp`是一个命令行程序,一次只能处理一张图片,并且它**不支持多核**(虽然有`-mt`开关,但是并不怎么管用),怎么办?
66

7-
  如果使用`XnConvert`之类的带GUI的集成转换器,可以解决手动输命令的问题。再多开几个,也**似乎**能解决CPU利用的问题,不过——
7+
如果使用`XnConvert`之类的带GUI的集成转换器,可以解决手动输命令的问题。再多开几个,也**似乎**能解决CPU利用的问题,不过——
88

9-
  若是`XnConvert`的其中一个实例已经转换完了所有你分配给这个实例的文件,而其他的实例还没完成任务,那么就不能最大化地利用CPU时间了!
9+
若是`XnConvert`的其中一个实例已完成了分配的任务,而其他的实例还没完成,那么就不能最大化地利用CPU时间了!
1010

11-
  再这么下去,最后也许会出现“仅一个实例未完成分配的任务,其他实例都完成了”这种蛋疼的局面,于是又回到了“一核有难x核围观”的状态。
11+
再这么下去,最后也许会出现“仅一个实例未完成分配的任务,其他实例都完成了”这种蛋疼的局面,于是又回到了“一核有难x核围观”的状态。
1212

13-
  所以——
13+
所以——
1414

15-
  来试试我的**Universal GUI**
15+
来试试我的**Universal GUI**
1616

1717
* 也许你已经猜出来了,我写这程序的初衷是为了解决**多核利用**问题,不过我不满足于此,就把它做成了一个还算友好的,通用的`GUI外壳`
1818

19-
* 顾名思义,这是**通用**的GUI外壳,不仅可用于举例的LibWebP,也可用于Lame、NeroAAC、LibPNG等命令行程序。当然,也不仅用于文件转换。
19+
* 顾名思义,这是**通用**的GUI外壳,不仅可用于举例的LibWebP,也可用于Lame、NeroAAC、Guetzli等命令行程序。当然,也不仅用于文件转换。
2020

2121
### How to Use?
2222

23-
  首先,我们需要看看源程序的帮助或者“Readme”,了解一下它的参数格式。下边是一个示例(LibWebP-cwebp):
23+
首先,我们需要看看源程序的帮助或者`Readme`,了解一下它的参数格式。下边是一个示例(LibWebP-cwebp):
24+
2425
```
2526
Usage: cwebp [-preset <...>] [options] in_file [-o out_file]
2627
```
2728

28-
* `[-preset <...>] [options]`是可供调整的选项,用`{UserParameters}`标记来表示。
29+
把参数中的各个部分抽象化,如下:
30+
31+
* `[-preset <...>] [options]`是可供调整的选项,用`{UserParameters}`标记表示。
2932

30-
* `in_file`是输入的文件,用`{InputFile}`标记来表示。本程序会用文件列表中的文件替换这个标记
33+
* `in_file`是输入文件名,用`{InputFile}`标记表示
3134

32-
* `-o`是输出文件名的开始标志,因此需要在`Argument templet`中填入
35+
* `-o`是输出文件名的开始标志,`Argument templet`中直接填入
3336

34-
* `out_file`是输出的文件,用`{OutputFile}`标记来表示。本程序根据输出文件名设置替换这个标记
37+
* `out_file`是输出文件名,用`{OutputFile}`标记表示
3538

36-
  综上,我们在`Universal GUI``Argument templet`中填入:`{UserParameters} {InputFile} -o {OutputFile}`。请留意在标记之间按需添加空格。
39+
综上,我们在`Universal GUI``Argument templet`中填入:`{UserParameters} {InputFile} -o {OutputFile}`。请留意在标记之间按需添加空格。
3740

38-
  接着在`Universal GUI``User arguments`中填入所需的参数,这些文本将会替换`{UserParameters}`标记。当然,你也可以直接在`Argument templet`中填入所需参数,不使用`{UserParameters}`标记(这可以适配一些对于输入文件有一些选项,对输出文件又有一些选项,并且这些选项在参数中不连续的程序)。
41+
接着在`Universal GUI``User arguments`中填入所需的参数,这些文本将会替换`{UserParameters}`标记。当然,你也可以直接在`Argument templet`中填入所需参数,不使用`{UserParameters}`标记(这可以适配一些对于输入文件有一些选项,对输出文件又有一些选项,并且这些选项在参数中的位置不连续的程序)。
3942

40-
  不过,`这程序的初衷`难道被我忘掉了?当然不。我们可以在`Thread number`这个Combo Box中选择线程数,这将同时运行多个源程序,并进行**异步调度**(多高大上),以弥补源程序不支持多核带来的不便
43+
不过,`这程序的初衷`难道被我忘掉了?当然不。我们可以在`Thread number`这个Combo Box中选择线程数,这将同时运行多个源程序,并进行**异步调度**(多高大上),以充分利用CPU时间
4144

42-
  其他的就没啥可说了。添加文件到列表中,给输出文件指定新的拓展名以及添加后缀……凡所应有,无所不有。Enjoy it!
45+
其他的就没啥可说了。添加文件到列表中,给输出文件指定新的拓展名以及添加后缀……凡所应有,无所不有。Enjoy it!
4346

4447
### Contrast
4548

4649
我使用`LibWebP-cwebp`将36张图片转换为WebP格式,使用`-m 6`以取得更好的压缩效果。
4750

48-
* 测试版本:`0.7.1.1`
51+
* `UniversalGUI`版本:`0.7.1.1`
52+
53+
* `LibWebP`版本:`1.0.0`
4954

5055
* 测试平台:`i3-2310m 2核心 4逻辑处理器(超线程)``2G DDR3 1333 内存`
5156

UniversalGUI/IniManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public void Write(string section, string key, double value)
100100
public void Write(string section, string key, object value)
101101
{
102102
string strValue = Convert.ToString(value);
103-
Write(section, key, strValue);
103+
Write(section, key, Convert.ToString(value));
104104
}
105105

106106
/// <summary>

UniversalGUI/LoadResourceDll.cs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Reflection;
5+
using System.Text.RegularExpressions;
6+
using System.Windows.Forms;
7+
8+
namespace UniversalGUI
9+
{
10+
/// <summary>
11+
/// 加载资源中的,程序集引用的DLL
12+
/// 原文链接: https://blog.csdn.net/yanhuatangtang/article/details/76228155
13+
/// </summary>
14+
public static class LoadResoureDll
15+
{
16+
/// <summary>
17+
/// 已加载DLL
18+
/// </summary>
19+
private static Dictionary<string, Assembly> LoadedDlls = new Dictionary<string, Assembly>();
20+
21+
/// <summary>
22+
/// 已处理程序集
23+
/// </summary>
24+
private static Dictionary<string, object> Assemblies = new Dictionary<string, object>();
25+
26+
/// <summary>
27+
/// 在对程序集解释失败时触发
28+
/// </summary>
29+
/// <param name="sender">AppDomain</param>
30+
/// <param name="args">事件参数</param>
31+
private static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
32+
{
33+
try
34+
{
35+
//程序集
36+
Assembly ass;
37+
//获取加载失败的程序集的全名
38+
var assName = new AssemblyName(args.Name).FullName;
39+
//判断Dlls集合中是否有已加载的同名程序集
40+
if (LoadedDlls.TryGetValue(assName, out ass) && ass != null)
41+
{
42+
LoadedDlls[assName] = null;//如果有则置空并返回
43+
return ass;
44+
}
45+
else
46+
{
47+
throw new DllNotFoundException(assName);//否则抛出加载失败的异常
48+
}
49+
}
50+
catch (Exception e)
51+
{
52+
MessageBox.Show("error:\n位置:AssemblyResolve()!\n描述:" + e.Message);
53+
return null;
54+
}
55+
}
56+
57+
/// <summary>
58+
/// 注册资源中的dll
59+
/// </summary>
60+
/// <param name="pattern">*表示连续的未知字符,_表示单个未知字符,如*.dll</param>
61+
public static void RegistDLL(string pattern = "*.dll")
62+
{
63+
System.IO.Directory.GetFiles("", "");
64+
//获取调用者的程序集
65+
var ass = new StackTrace(0).GetFrame(1).GetMethod().Module.Assembly;
66+
//判断程序集是否已经处理
67+
if (Assemblies.ContainsKey(ass.FullName))
68+
{
69+
return;
70+
}
71+
//程序集加入已处理集合
72+
Assemblies.Add(ass.FullName, null);
73+
//绑定程序集加载失败事件(这里我测试了,就算重复绑也是没关系的)
74+
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
75+
//获取所有资源文件文件名
76+
var res = ass.GetManifestResourceNames();
77+
var regex = new Regex("^" + pattern.Replace(".", "\\.").Replace("*", ".*").Replace("_", ".") + "$", RegexOptions.IgnoreCase);
78+
foreach (var r in res)
79+
{
80+
//如果是dll,则加载
81+
if (regex.IsMatch(r))
82+
{
83+
try
84+
{
85+
var s = ass.GetManifestResourceStream(r);
86+
var bts = new byte[s.Length];
87+
s.Read(bts, 0, (int)s.Length);
88+
var da = Assembly.Load(bts);
89+
//判断是否已经加载
90+
if (LoadedDlls.ContainsKey(da.FullName))
91+
{
92+
continue;
93+
}
94+
LoadedDlls[da.FullName] = da;
95+
}
96+
catch (Exception ex)
97+
{
98+
MessageBox.Show("error:加载dll失败\n位置:RegistDLL()!\n描述:" + ex.Message);
99+
}
100+
}
101+
}
102+
}
103+
}
104+
}

UniversalGUI/MainWindow.xaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2"
88
x:Class="UniversalGUI.MainWindow"
99
mc:Ignorable="d"
10-
Title="{DynamicResource Window_MainWindow_Title}" Height="500" Width="700" MinWidth="550" MinHeight="425" Closing="MainWindow_WindowClosing" Loaded="MainWindow_Loaded">
10+
Title="{DynamicResource Window_MainWindow_Title}" Height="425" Width="700" MinWidth="550" MinHeight="425" Closing="MainWindow_WindowClosing" Loaded="MainWindow_Loaded">
1111

1212
<Grid>
1313
<Button x:Name="StartTaskButton" Content="{DynamicResource Button_StartTask_Content_Start}" HorizontalAlignment="Right" Height="50" Margin="0,0,20,20" VerticalAlignment="Bottom" Width="100" FontSize="16" Click="StartTaskAsync" Style="{DynamicResource FlatButton}"/>
@@ -29,8 +29,9 @@
2929
<Button Content="..." HorizontalAlignment="Right" Height="20" Margin="0,25,5,0" VerticalAlignment="Top" Width="20" Foreground="#FF7F7F7F" Click="SwitchApplicationPath" Style="{DynamicResource FlatButton}" Panel.ZIndex="1" />
3030

3131
<TextBlock Height="20" Margin="5,55,5,0" Text="{DynamicResource TextBlock_ArgsTemplet_Text}" VerticalAlignment="Top"/>
32-
<TextBox x:Name="ArgsTemplet" Height="20" Margin="5,75,5,0" VerticalAlignment="Top" Text="{}{UserParameters} {InputFile} {OutputFile}"/>
33-
32+
<TextBox x:Name="ArgsTemplet" Height="20" Margin="5,75,24,0" VerticalAlignment="Top" Text="{}{UserParameters} {InputFile} {OutputFile}"/>
33+
<Button Content="?" HorizontalAlignment="Right" Height="20" Margin="0,75,5,0" VerticalAlignment="Top" Width="20" Foreground="#FF7F7F7F" Click="ShowArgsTempletHelp" Style="{DynamicResource FlatButton}" Panel.ZIndex="1" />
34+
3435
<TextBlock Height="20" Margin="5,105,5,0" Text="{DynamicResource TextBlock_UserArgs_Text}" VerticalAlignment="Top"/>
3536
<TextBox x:Name="UserArgs" Margin="5,125,5,5" TextWrapping="Wrap"/>
3637
</Grid>

UniversalGUI/MainWindow.xaml.cs

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Windows;
1111
using System.Windows.Media;
1212
using System.Windows.Threading;
13+
using Microsoft.WindowsAPICodePack.Taskbar;
1314

1415
namespace UniversalGUI
1516
{
@@ -97,14 +98,14 @@ await Task.Run(() =>
9798

9899
private string SumAppArgs(string argsTemplet, string inputFile, string userArgs, string outputSuffix, string outputExtension, string outputFloder)
99100
{
100-
//去所有引号(包括前后引号和中间的引号)
101-
inputFile = new Regex("\"").Replace(inputFile, "");
102-
argsTemplet = new Regex("\"").Replace(argsTemplet, "");
103-
userArgs = new Regex("\"").Replace(userArgs, "");
104-
outputSuffix = new Regex("\"").Replace(outputSuffix, "");
105-
outputExtension = new Regex("\"").Replace(outputExtension, "");
106-
outputFloder = new Regex("\"").Replace(outputFloder, "");
107-
101+
//去前后引号
102+
inputFile = new Regex("(^\")|(\"$)").Replace(inputFile, "");
103+
argsTemplet = new Regex("(^\")|(\"$)").Replace(argsTemplet, "");
104+
userArgs = new Regex("(^\")|(\"$)").Replace(userArgs, "");
105+
outputSuffix = new Regex("(^\")|(\"$)").Replace(outputSuffix, "");
106+
outputExtension = new Regex("(^\")|(\"$)").Replace(outputExtension, "");
107+
outputFloder = new Regex("(^\")|(\"$)").Replace(outputFloder, "");
108+
108109
string arguments = argsTemplet;
109110

110111
//替换 {UserParameters}
@@ -254,6 +255,7 @@ public MainWindow()
254255
IniConfigManager = new IniManager(GetIniConfigFile());
255256
ImputIniConfig(IniConfigManager);
256257
SetLanguage();
258+
LoadResoureDll.RegistDLL(); //导入引用的DLL
257259
}
258260

259261
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
@@ -306,6 +308,8 @@ private void SetProgress(double multiple = -2)
306308
TaskProgressBar.Value = 0;
307309
TaskProgressBar.Foreground = new SolidColorBrush(Colors.DimGray);
308310
TaskProgressBar.Visibility = Visibility.Hidden;
311+
TaskbarManager.Instance.SetProgressValue(0, 100, this);
312+
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress, this);
309313
}
310314
else if (multiple == -1) //错误警告
311315
{
@@ -314,13 +318,17 @@ private void SetProgress(double multiple = -2)
314318
TaskProgressBar.Foreground = new SolidColorBrush(Colors.Red);
315319
TaskProgressBar.Value = 100;
316320
TaskProgressBar.Visibility = Visibility.Visible;
321+
TaskbarManager.Instance.SetProgressValue(100, 100, this);
322+
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error, this);
317323
}
318324
else if (multiple >= 0 && multiple <= 1) //修改
319325
{
320-
double percent = Math.Round(multiple * 100);
326+
int percent = Convert.ToInt32(Math.Round(multiple * 100));
321327
SetTitleSuffix(percent + "%");
322328
TaskProgressBar.Value = percent;
323329
TaskProgressBar.Visibility = Visibility.Visible;
330+
TaskbarManager.Instance.SetProgressValue(percent, 100, this);
331+
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal, this);
324332
}
325333
}
326334

@@ -345,42 +353,43 @@ await Task.Run(() =>
345353
double cpuUseRatio;
346354
var computerInfo = new Microsoft.VisualBasic.Devices.ComputerInfo();
347355
double usedMem;
348-
double memUseRatio;
349356
string memUnit = "KB";
357+
double memUseRatio;
350358
while (true)
351359
{
352360
cpuUseRatio = Math.Round(cpuPerformanceCounter.NextValue());
353361
usedMem = (double)computerInfo.TotalPhysicalMemory - computerInfo.AvailablePhysicalMemory;
354362
memUseRatio = Math.Round((double)usedMem / computerInfo.TotalPhysicalMemory * 100);
355363

356-
if (usedMem > 1073634449817.6) //大于999.9GB
364+
//按需切换占用内存大小的显示单位及精度
365+
if (usedMem >= 1099511627776) //占用内存>=1TB
357366
{
358367
memUnit = "TB";
359-
usedMem = usedMem / 1024 / 1024 / 1024 / 1024;
368+
usedMem = usedMem / 1099511627776; //1024^4(4次方)
360369
usedMem = Math.Round(usedMem, 3);
361370
}
362-
else if (usedMem > 107363444981.76) //大于99.99GB
371+
else if (usedMem >= 107374182400) //>=100GB
363372
{
364373
memUnit = "GB";
365-
usedMem = usedMem / 1024 / 1024 / 1024;
374+
usedMem = usedMem / 1073741824; //^3
366375
usedMem = Math.Round(usedMem, 1);
367376
}
368-
else if (usedMem > 10736344498.176) //大于9.999GB
377+
else if (usedMem >= 10737418240) //>=10GB
369378
{
370379
memUnit = "GB";
371-
usedMem = usedMem / 1024 / 1024 / 1024;
380+
usedMem = usedMem / 1073741824; //^3
372381
usedMem = Math.Round(usedMem, 2);
373382
}
374-
else if (usedMem > 1048471142.4) //大于999.9MB
383+
else if (usedMem >= 1073741824) //>=1GB
375384
{
376385
memUnit = "GB";
377-
usedMem = usedMem / 1024 / 1024 / 1024;
386+
usedMem = usedMem / 1073741824; //^3
378387
usedMem = Math.Round(usedMem, 3);
379388
}
380-
else if (usedMem > 104847114.24) //大于99.99MB
389+
else if (usedMem >= 104857600) //>=100MB
381390
{
382391
memUnit = "MB";
383-
usedMem = usedMem / 1024 / 1024;
392+
usedMem = usedMem / 1048576;//^2
384393
usedMem = Math.Round(usedMem, 1);
385394
}
386395

@@ -510,6 +519,13 @@ private void ApplicationPath_PreviewDrop(object sender, DragEventArgs e)
510519
string[] dropFiles = (string[])e.Data.GetData(DataFormats.FileDrop);
511520
AppPath.Text = dropFiles[0];
512521
}
522+
523+
private void ShowArgsTempletHelp(object sender, RoutedEventArgs e)
524+
{
525+
string title = QueryLangDict("MessageBox_Title_Hint");
526+
string content = QueryLangDict("MessageBox_Content_Help_ArgsTemplet");
527+
MessageBox.Show(content, title);
528+
}
513529

514530
private void SwitchOutputFloder(object sender, RoutedEventArgs e)
515531
{

UniversalGUI/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@
5151
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
5252
// 方法是按如下所示使用“*”: :
5353
// [assembly: AssemblyVersion("1.0.*")]
54-
[assembly: AssemblyVersion("0.8.0.2")]
55-
[assembly: AssemblyFileVersion("0.8.0.2")]
54+
[assembly: AssemblyVersion("0.8.2.9")]
55+
[assembly: AssemblyFileVersion("0.8.2.9")]

UniversalGUI/Resources/Languages/en-US.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<sys:String x:Key="TextBlock_MonitorForRAM_Text">RAM:</sys:String>
4646
<sys:String x:Key="MessageBox_Title_Error">Error</sys:String>
4747
<sys:String x:Key="MessageBox_Title_Hint">Hint</sys:String>
48+
<sys:String x:Key="MessageBox_Content_Help_ArgsTemplet">You can use mark {UserParameters},{InputFile} and {OutputFile}.</sys:String>
4849
<sys:String x:Key="MessageBox_Content_Configfile_FormatMistake">There is a mistake in the configfile's format:</sys:String>
4950
<sys:String x:Key="MessageBox_Content_Configfile_VersionMistake_UseBuildInOne">Existing configfile's version is not supported.So you will use built-in config.</sys:String>
5051
<sys:String x:Key="MessageBox_Content_Configfile_VersionMistake_CreatNewOne">Existing configfile's version is not supported.Want you delete it and creat a new one?</sys:String>

0 commit comments

Comments
 (0)