dndm

dndm Commit Details


Date:2013-02-11 23:31:00 (11 years 10 months ago)
Author:Natalie Adams
Branch:default
Commit:1dae03ea3242
Message:Initial commit

Changes:
AICSharpCode.SharpZipLib.dll
AINIFileParser.dll
AInterop.SHDocVw.dll
AMyDownloader.App/App.config (full)
AMyDownloader.App/App.cs (full)
AMyDownloader.App/CommandLineArguments.cs (full)
AMyDownloader.App/CommandLineParsing/Command.cs (full)
AMyDownloader.App/CommandLineParsing/CommandLineDictionary.cs (full)
AMyDownloader.App/CommandLineParsing/CommandLineParser.cs (full)
AMyDownloader.App/CommandLineParsing/DirectoryInfoConverter.cs (full)
AMyDownloader.App/CommandLineParsing/FileInfoConverter.cs (full)
AMyDownloader.App/CommandLineParsing/NamespaceDoc.cs (full)
AMyDownloader.App/CommandLineParsing/RequiredAttribute.cs (full)
AMyDownloader.App/Controls/Block.cs (full)
AMyDownloader.App/Controls/BlockList.cs (full)
AMyDownloader.App/Controls/BlockedProgressBar.bmp
AMyDownloader.App/Controls/BlockedProgressBar.cs (full)
AMyDownloader.App/Controls/BlockedProgressBar.designer.cs (full)
AMyDownloader.App/Controls/CheckableTreeView.cs (full)
AMyDownloader.App/DONE.txt (full)
AMyDownloader.App/Download.ico
AMyDownloader.App/MyDownloader.App.csproj (full)
AMyDownloader.App/Program.cs (full)
AMyDownloader.App/Properties/AssemblyInfo.cs (full)
AMyDownloader.App/Properties/Resources.Designer.cs (full)
AMyDownloader.App/Properties/Resources.resx (full)
AMyDownloader.App/Settings.Designer.cs (full)
AMyDownloader.App/Settings.settings (full)
AMyDownloader.App/SingleInstancing/ISingleInstanceEnforcer.cs (full)
AMyDownloader.App/SingleInstancing/MessageEventArgs.cs (full)
AMyDownloader.App/SingleInstancing/SingleInstanceException.cs (full)
AMyDownloader.App/SingleInstancing/SingleInstanceProxy.cs (full)
AMyDownloader.App/SingleInstancing/SingleInstanceTracker.cs (full)
AMyDownloader.App/TODO.txt (full)
AMyDownloader.App/UI/About.rtf
AMyDownloader.App/UI/AboutForm.Designer.cs (full)
AMyDownloader.App/UI/AboutForm.cs (full)
AMyDownloader.App/UI/AboutForm.resx (full)
AMyDownloader.App/UI/CreateBatchDownloadForm.Designer.cs (full)
AMyDownloader.App/UI/CreateBatchDownloadForm.cs (full)
AMyDownloader.App/UI/CreateBatchDownloadForm.resx (full)
AMyDownloader.App/UI/DownloadList.Designer.cs (full)
AMyDownloader.App/UI/DownloadList.cs (full)
AMyDownloader.App/UI/DownloadList.resx (full)
AMyDownloader.App/UI/FileTypeImageList.cs (full)
AMyDownloader.App/UI/IconReader.cs (full)
AMyDownloader.App/UI/ImportFromFileForm.Designer.cs (full)
AMyDownloader.App/UI/ImportFromFileForm.cs (full)
AMyDownloader.App/UI/ImportFromFileForm.resx (full)
AMyDownloader.App/UI/ImportFromFilePreviewForm.Designer.cs (full)
AMyDownloader.App/UI/ImportFromFilePreviewForm.cs (full)
AMyDownloader.App/UI/ImportFromFilePreviewForm.resx (full)
AMyDownloader.App/UI/MainForm.Designer.cs (full)
AMyDownloader.App/UI/MainForm.cs (full)
AMyDownloader.App/UI/MainForm.resx (full)
AMyDownloader.App/UI/NewDownloadForm.Designer.cs (full)
AMyDownloader.App/UI/NewDownloadForm.cs (full)
AMyDownloader.App/UI/NewDownloadForm.resx (full)
AMyDownloader.App/UI/OptionsForm.Designer.cs (full)
AMyDownloader.App/UI/OptionsForm.cs (full)
AMyDownloader.App/UI/OptionsForm.resx (full)
AMyDownloader.App/bin/Release/License.txt (full)
AMyDownloader.App/bin/Release/readme.txt (full)
AMyDownloader.Core/CalculatedSegment.cs (full)
AMyDownloader.Core/Common/ArrayExtension.cs (full)
AMyDownloader.Core/Common/BoolFormatter.cs (full)
AMyDownloader.Core/Common/ByteFormatter.cs (full)
AMyDownloader.Core/Common/CookieManager.cs (full)
AMyDownloader.Core/Common/DateTimeExtension.cs (full)
AMyDownloader.Core/Common/PathHelper.cs (full)
AMyDownloader.Core/Common/SQLiteDatabase.cs (full)
AMyDownloader.Core/Common/TimeSpanFormatter.cs (full)
AMyDownloader.Core/Concurrency/ObjectLocker.cs (full)
AMyDownloader.Core/Concurrency/ReaderWriterObjectLocker.cs (full)
AMyDownloader.Core/DownloadManager.cs (full)
AMyDownloader.Core/Downloader.cs (full)
AMyDownloader.Core/DownloaderState.cs (full)
AMyDownloader.Core/EventArgs.cs (full)
AMyDownloader.Core/Extensions/IExtension.cs (full)
AMyDownloader.Core/Extensions/IExtensionParameters.cs (full)
AMyDownloader.Core/Extensions/IInitializable.cs (full)
AMyDownloader.Core/Extensions/IUIExtension.cs (full)
AMyDownloader.Core/IMirrorSelector.cs (full)
AMyDownloader.Core/IProtocolProvider.cs (full)
AMyDownloader.Core/ISegmentCalculator.cs (full)
AMyDownloader.Core/Instrumentation/MyStopwatch.cs (full)
AMyDownloader.Core/MinSizeSegmentCalculator.cs (full)
AMyDownloader.Core/MyDownloader.Core.csproj (full)
AMyDownloader.Core/Properties/AssemblyInfo.cs (full)
AMyDownloader.Core/ProtocolProviderFactory.cs (full)
AMyDownloader.Core/RemoteFileInfo.cs (full)
AMyDownloader.Core/ResourceLocation.cs (full)
AMyDownloader.Core/Segment.cs (full)
AMyDownloader.Core/SegmentState.cs (full)
AMyDownloader.Core/SequentialMirrorSelector.cs (full)
AMyDownloader.Core/Settings.Designer.cs (full)
AMyDownloader.Core/Settings.settings (full)
AMyDownloader.Core/UI/AppManager.cs (full)
AMyDownloader.Core/UI/ApplicationSettings.Designer.cs (full)
AMyDownloader.Core/UI/ApplicationSettings.cs (full)
AMyDownloader.Core/UI/ApplicationSettings.resx (full)
AMyDownloader.Core/UI/ClipboardHelper.cs (full)
AMyDownloader.Core/UI/Connection.Designer.cs (full)
AMyDownloader.Core/UI/Connection.cs (full)
AMyDownloader.Core/UI/Connection.resx (full)
AMyDownloader.Core/UI/CoreExtention.cs (full)
AMyDownloader.Core/UI/CoreUIExtention.cs (full)
AMyDownloader.Core/UI/DownloadFolder.Designer.cs (full)
AMyDownloader.Core/UI/DownloadFolder.cs (full)
AMyDownloader.Core/UI/DownloadFolder.resx (full)
AMyDownloader.Core/UI/IApp.cs (full)
AMyDownloader.Core/UI/Location.Designer.cs (full)
AMyDownloader.Core/UI/Location.cs (full)
AMyDownloader.Core/UI/Location.resx (full)
AMyDownloader.Core/UI/WaitControl.Designer.cs (full)
AMyDownloader.Core/UI/WaitControl.cs (full)
AMyDownloader.Core/UI/WaitControl.resx (full)
AMyDownloader.Core/app.config (full)
AMyDownloader.Core/sqlite3.dll
AMyDownloader.Extension/AntiVirus/AntiVirusExtension.cs (full)
AMyDownloader.Extension/AntiVirus/AntiVirusParametersSettingsProxy.cs (full)
AMyDownloader.Extension/AntiVirus/AntiVirusUIExtension.cs (full)
AMyDownloader.Extension/AntiVirus/IAntiVirusParameters.cs (full)
AMyDownloader.Extension/AntiVirus/Settings.Designer.cs (full)
AMyDownloader.Extension/AntiVirus/Settings.settings (full)
AMyDownloader.Extension/AntiVirus/UI/AVOptions.Designer.cs (full)
AMyDownloader.Extension/AntiVirus/UI/AVOptions.cs (full)
AMyDownloader.Extension/AntiVirus/UI/AVOptions.resx (full)
AMyDownloader.Extension/AutoDownloads/AutoDownloadsExtension.cs (full)
AMyDownloader.Extension/AutoDownloads/AutoDownloadsParametersSettingsProxy.cs (full)
AMyDownloader.Extension/AutoDownloads/AutoDownloadsUIExtension.cs (full)
AMyDownloader.Extension/AutoDownloads/DayHourMatrix.cs (full)
AMyDownloader.Extension/AutoDownloads/IAutoDownloadsParameters.cs (full)
AMyDownloader.Extension/AutoDownloads/Settings.Designer.cs (full)
AMyDownloader.Extension/AutoDownloads/Settings.settings (full)
AMyDownloader.Extension/AutoDownloads/UI/Jobs.Designer.cs (full)
AMyDownloader.Extension/AutoDownloads/UI/Jobs.cs (full)
AMyDownloader.Extension/AutoDownloads/UI/Jobs.resx (full)
AMyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.Designer.cs (full)
AMyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.cs (full)
AMyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.resx (full)
AMyDownloader.Extension/AutoDownloads/UI/TimeGrid.Designer.cs (full)
AMyDownloader.Extension/AutoDownloads/UI/TimeGrid.cs (full)
AMyDownloader.Extension/AutoDownloads/UI/TimeGrid.resx (full)
AMyDownloader.Extension/MyDownloader.Extension.csproj (full)
AMyDownloader.Extension/Notifications/Helpers/BalloonHelper.cs (full)
AMyDownloader.Extension/Notifications/Helpers/SoundHelper.cs (full)
AMyDownloader.Extension/Notifications/INotificationsExtensionParameters.cs (full)
AMyDownloader.Extension/Notifications/NotificationsExtension.cs (full)
AMyDownloader.Extension/Notifications/NotificationsExtensionParametersSettingsProxy.cs (full)
AMyDownloader.Extension/Notifications/NotificationsUIExtension.cs (full)
AMyDownloader.Extension/Notifications/Settings.Designer.cs (full)
AMyDownloader.Extension/Notifications/Settings.settings (full)
AMyDownloader.Extension/Notifications/UI/SoundChooser.Designer.cs (full)
AMyDownloader.Extension/Notifications/UI/SoundChooser.cs (full)
AMyDownloader.Extension/Notifications/UI/SoundChooser.resx (full)
AMyDownloader.Extension/Notifications/UI/SoundsOptions.Designer.cs (full)
AMyDownloader.Extension/Notifications/UI/SoundsOptions.cs (full)
AMyDownloader.Extension/Notifications/UI/SoundsOptions.resx (full)
AMyDownloader.Extension/Notifications/UI/XPBalloonOptions.Designer.cs (full)
AMyDownloader.Extension/Notifications/UI/XPBalloonOptions.cs (full)
AMyDownloader.Extension/Notifications/UI/XPBalloonOptions.resx (full)
AMyDownloader.Extension/PersistedList/PersistedListExtension.cs (full)
AMyDownloader.Extension/PersistedList/SerializableDictionary.cs (full)
AMyDownloader.Extension/Properties/AssemblyInfo.cs (full)
AMyDownloader.Extension/Protocols/BaseProtocolProvider.cs (full)
AMyDownloader.Extension/Protocols/FtpProtocolProvider.cs (full)
AMyDownloader.Extension/Protocols/HttpFtpProtocolExtension.cs (full)
AMyDownloader.Extension/Protocols/HttpFtpProtocolParametersSettingsProxy.cs (full)
AMyDownloader.Extension/Protocols/HttpFtpProtocolUIExtension.cs (full)
AMyDownloader.Extension/Protocols/HttpProtocolProvider.cs (full)
AMyDownloader.Extension/Protocols/IHttpFtpProtocolParameters.cs (full)
AMyDownloader.Extension/Protocols/Settings.Designer.cs (full)
AMyDownloader.Extension/Protocols/Settings.settings (full)
AMyDownloader.Extension/Protocols/UI/Proxy.Designer.cs (full)
AMyDownloader.Extension/Protocols/UI/Proxy.cs (full)
AMyDownloader.Extension/Protocols/UI/Proxy.resx (full)
AMyDownloader.Extension/SpeedLimit/ISpeedLimitParameters.cs (full)
AMyDownloader.Extension/SpeedLimit/LimitedRateStreamProxy.cs (full)
AMyDownloader.Extension/SpeedLimit/ProtocolProviderProxy.cs (full)
AMyDownloader.Extension/SpeedLimit/Settings.Designer.cs (full)
AMyDownloader.Extension/SpeedLimit/Settings.settings (full)
AMyDownloader.Extension/SpeedLimit/SpeedLimitExtension.cs (full)
AMyDownloader.Extension/SpeedLimit/SpeedLimitParametersSettingProxy.cs (full)
AMyDownloader.Extension/SpeedLimit/SpeedLimitUIExtension.cs (full)
AMyDownloader.Extension/SpeedLimit/UI/LimitCfg.Designer.cs (full)
AMyDownloader.Extension/SpeedLimit/UI/LimitCfg.cs (full)
AMyDownloader.Extension/SpeedLimit/UI/LimitCfg.resx (full)
AMyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.Designer.cs (full)
AMyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.cs (full)
AMyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.resx (full)
AMyDownloader.Extension/Video/Impl/BaseVideoDownloader.cs (full)
AMyDownloader.Extension/Video/Impl/BreakVideoDownloader.cs (full)
AMyDownloader.Extension/Video/Impl/GoogleVideoDownloader.cs (full)
AMyDownloader.Extension/Video/Impl/Logos/BreakVideoDownloader.png
AMyDownloader.Extension/Video/Impl/Logos/GoogleVideoDownloader.png
AMyDownloader.Extension/Video/Impl/Logos/MetaCafeVideoDownloader.png
AMyDownloader.Extension/Video/Impl/Logos/PutfileVideoDownloader.PNG
AMyDownloader.Extension/Video/Impl/Logos/YouTubeDownloader.png
AMyDownloader.Extension/Video/Impl/MetaCafeVideoDownloader.cs (full)
AMyDownloader.Extension/Video/Impl/PutfileVideoDownloader.cs (full)
AMyDownloader.Extension/Video/Impl/YouTubeDownloader.cs (full)
AMyDownloader.Extension/Video/TextUtil.cs (full)
AMyDownloader.Extension/Video/UI/NewVideoDownload.Designer.cs (full)
AMyDownloader.Extension/Video/UI/NewVideoDownload.cs (full)
AMyDownloader.Extension/Video/UI/NewVideoDownload.resx (full)
AMyDownloader.Extension/Video/UI/SupportedVideoSitesForm.Designer.cs (full)
AMyDownloader.Extension/Video/UI/SupportedVideoSitesForm.cs (full)
AMyDownloader.Extension/Video/UI/SupportedVideoSitesForm.resx (full)
AMyDownloader.Extension/Video/UI/VideoFormatCtrl.Designer.cs (full)
AMyDownloader.Extension/Video/UI/VideoFormatCtrl.cs (full)
AMyDownloader.Extension/Video/UI/VideoFormatCtrl.resx (full)
AMyDownloader.Extension/Video/VideoConverter.cs (full)
AMyDownloader.Extension/Video/VideoDownloadExtension.cs (full)
AMyDownloader.Extension/Video/VideoDownloadHandler.cs (full)
AMyDownloader.Extension/Video/VideoDownloadUIExtension.cs (full)
AMyDownloader.Extension/WindowsIntegration/ClipboardMonitor/ClipboardMonitor.cs (full)
AMyDownloader.Extension/WindowsIntegration/ClipboardMonitor/IClipboardDataHandler.cs (full)
AMyDownloader.Extension/WindowsIntegration/Settings.Designer.cs (full)
AMyDownloader.Extension/WindowsIntegration/Settings.settings (full)
AMyDownloader.Extension/WindowsIntegration/WindowsIntegrationExtension.cs (full)
AMyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.Designer.cs (full)
AMyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.cs (full)
AMyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.resx (full)
AMyDownloader.Extension/WindowsIntegration/WindowsIntegrationUIExtension.cs (full)
AMyDownloader.Extension/WindowsIntegration/WindowsStartupUtility.cs (full)
AMyDownloader.Extension/Zip/NoCloseSubStream.cs (full)
AMyDownloader.Extension/Zip/PartialInputStream.cs (full)
AMyDownloader.Extension/Zip/StreamHelper.cs (full)
AMyDownloader.Extension/Zip/ZipOutputStream.cs (full)
AMyDownloader.Extension/Zip/ZipProtocolProvider.cs (full)
AMyDownloader.Extension/Zip/ZipRemoteFile.cs (full)
AMyDownloader.Extension/app.config (full)
AMyDownloader.IEPlugin/BandObjectLib/Attributes.cs (full)
AMyDownloader.IEPlugin/BandObjectLib/BandObject.cs (full)
AMyDownloader.IEPlugin/BandObjectLib/ComInterop.cs (full)
AMyDownloader.IEPlugin/IEMD.cs (full)
AMyDownloader.IEPlugin/IEMD.resx (full)
AMyDownloader.IEPlugin/IEManager.cs (full)
AMyDownloader.IEPlugin/IEManager.resx (full)
AMyDownloader.IEPlugin/MyDownloader.IEPlugin.csproj (full)
AMyDownloader.IEPlugin/MyDownloader.IEPlugin.snk
AMyDownloader.IEPlugin/READ-ME.txt (full)
AMyDownloader.IEPlugin/Settings.cs (full)
AMyDownloader.IEPlugin/VideoSitesRepository.cs (full)
AMyDownloader.IEPlugin/VideoSitesURLPatterns.txt (full)
AMyDownloader.IEPlugin/bin/Release/register.bat (full)
AMyDownloader.IEPlugin/bin/Release/register.reg
AMyDownloader.IEPlugin/bin/Release/unregister.bat (full)
AMyDownloader.IEPlugin/bin/Release/unregister.reg
AMyDownloader.IEPlugin/register.bat (full)
AMyDownloader.IEPlugin/register.reg
AMyDownloader.IEPlugin/unregister.bat (full)
AMyDownloader.IEPlugin/unregister.reg
AMyDownloader.Spider/IAsyncRetriver.cs (full)
AMyDownloader.Spider/INamingRule.cs (full)
AMyDownloader.Spider/ISpiderResource.cs (full)
AMyDownloader.Spider/ISpiderResourceFactory.cs (full)
AMyDownloader.Spider/MyDownloader.Spider.csproj (full)
AMyDownloader.Spider/Parsers/Html/HtmlParser.cs (full)
AMyDownloader.Spider/Parsers/Html/UrlType.cs (full)
AMyDownloader.Spider/Properties/AssemblyInfo.cs (full)
AMyDownloader.Spider/Spider.cs (full)
AMyDownloader.Spider/SpiderContext.cs (full)
AMyDownloader.Spider/UI/StartAutoDownloadsForm.Designer.cs (full)
AMyDownloader.Spider/UI/StartAutoDownloadsForm.cs (full)
AMyDownloader.Spider/UI/StartAutoDownloadsForm.resx (full)
AMyDownloader.Spider/UI/WebSpider.Designer.cs (full)
AMyDownloader.Spider/UI/WebSpider.cs (full)
AMyDownloader.Spider/UI/WebSpider.resx (full)
AMyDownloader.Spider/Web/DownloaderAsyncRetrive.cs (full)
AMyDownloader.Spider/Web/Rules/BaseLocationNamingRule.cs (full)
AMyDownloader.Spider/Web/Rules/ExcludeExtensionNamingRule.cs (full)
AMyDownloader.Spider/Web/Rules/ExcludeNameNamingRule.cs (full)
AMyDownloader.Spider/Web/Rules/MaxDepthNamingRule.cs (full)
AMyDownloader.Spider/Web/WebSpiderResource.cs (full)
AMyDownloader.Spider/Web/WebSpiderResourceFactory.cs (full)
AMyDownloader.Tests/Extension/Video/VideoConverterTest.cs (full)
AMyDownloader.Tests/MyDownloader.Tests.csproj (full)
AMyDownloader.Tests/Properties/AssemblyInfo.cs (full)
AMyDownloader.sln (full)
ASystem.Data.SQLite.dll
ATabStrip.dll
Ainstaller.iss (full)
Asqlite3.dll

File differences

MyDownloader.App/App.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="MyDownloader.App.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="MyDownloader.Core.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="MyDownloader.Extension.AntiVirus.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="MyDownloader.Extension.Notifications.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="MyDownloader.Extension.Protocols.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="MyDownloader.Extension.Scheduler.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<userSettings>
<MyDownloader.App.Settings>
<setting name="ViewTransDetails" serializeAs="String">
<value>True</value>
</setting>
<setting name="ViewToolbar" serializeAs="String">
<value>True</value>
</setting>
<setting name="ViewGrid" serializeAs="String">
<value>True</value>
</setting>
</MyDownloader.App.Settings>
<MyDownloader.Core.Settings>
<setting name="MinSegmentSize" serializeAs="String">
<value>200000</value>
</setting>
<setting name="MinSegmentLeftToStartNewSegment" serializeAs="String">
<value>30</value>
</setting>
<setting name="RetryDelay" serializeAs="String">
<value>5</value>
</setting>
<setting name="MaxRetries" serializeAs="String">
<value>10</value>
</setting>
<setting name="MaxSegments" serializeAs="String">
<value>5</value>
</setting>
</MyDownloader.Core.Settings>
<MyDownloader.Extension.AntiVirus.Settings>
<setting name="CheckFileWithAV" serializeAs="String">
<value>False</value>
</setting>
<setting name="AVFileName" serializeAs="String">
<value></value>
</setting>
<setting name="FileTypes" serializeAs="String">
<value>.exe;.com</value>
</setting>
<setting name="AVParameter" serializeAs="String">
<value>-a</value>
</setting>
</MyDownloader.Extension.AntiVirus.Settings>
<MyDownloader.Extension.Scheduler.Settings>
<setting name="MaxJobs" serializeAs="String">
<value>5</value>
</setting>
<setting name="WorkOnlyOnSpecifiedTimes" serializeAs="String">
<value>False</value>
</setting>
<setting name="TimesToWork" serializeAs="String">
<value/>
</setting>
</MyDownloader.Extension.Scheduler.Settings>
<MyDownloader.Extension.Protocols.Settings>
<setting name="UseProxy" serializeAs="String">
<value>False</value>
</setting>
<setting name="ProxyAddress" serializeAs="String">
<value></value>
</setting>
<setting name="ProxyPort" serializeAs="String">
<value>80</value>
</setting>
<setting name="ProxyUserName" serializeAs="String">
<value></value>
</setting>
<setting name="ProxyPassword" serializeAs="String">
<value></value>
</setting>
<setting name="ProxyDomain" serializeAs="String">
<value></value>
</setting>
<setting name="ProxyByPassOnLocal" serializeAs="String">
<value>True</value>
</setting>
</MyDownloader.Extension.Protocols.Settings>
<MyDownloader.Extension.Notifications.Settings>
<setting name="DownloadAddedSound" serializeAs="String">
<value/>
</setting>
<setting name="DownloadRemovedSound" serializeAs="String">
<value/>
</setting>
<setting name="DownloadEndedSound" serializeAs="String">
<value/>
</setting>
<setting name="ShowBallon" serializeAs="String">
<value>True</value>
</setting>
<setting name="BallonTimeout" serializeAs="String">
<value>3000</value>
</setting>
</MyDownloader.Extension.Notifications.Settings>
</userSettings>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
MyDownloader.App/App.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using MyDownloader.App;
using MyDownloader.App.UI;
using MyDownloader.App.SingleInstancing;
using MyDownloader.Core;
using MyDownloader.Core.Extensions;
using MyDownloader.Core.UI;
using MyDownloader.Extension;
using MyDownloader.Extension.AntiVirus;
using MyDownloader.Extension.Protocols;
using MyDownloader.Extension.Notifications;
using MyDownloader.Extension.Video;
using MyDownloader.Extension.AutoDownloads;
using MyDownloader.Extension.SpeedLimit;
using MyDownloader.Extension.PersistedList;
using MyDownloader.Extension.WindowsIntegration;
using Microsoft.Test.CommandLineParsing;
using System.IO;
namespace MyDownloader.App
{
[Serializable]
public class App : IApp
{
#region Singleton
private static App instance = new App();
public static App Instance
{
get
{
return instance;
}
}
private App()
{
AppManager.Instance.Initialize(this);
extensions = new List<IExtension>();
extensions.Add(new CoreExtention());
extensions.Add(new HttpFtpProtocolExtension());
extensions.Add(new VideoDownloadExtension());
extensions.Add(new SpeedLimitExtension());
extensions.Add(new PersistedListExtension());
extensions.Add(new AntiVirusExtension());
extensions.Add(new NotificationsExtension());
extensions.Add(new AutoDownloadsExtension());
extensions.Add(new WindowsIntegrationExtension());
}
#endregion
#region Fields
private List<IExtension> extensions;
private SingleInstanceTracker tracker = null;
private bool disposed = false;
#endregion
#region Properties
public Form MainForm
{
get
{
return (MainForm)tracker.Enforcer;
}
}
public NotifyIcon NotifyIcon
{
get
{
return ((UI.MainForm)MainForm).notifyIcon;
}
}
public List<IExtension> Extensions
{
get
{
return extensions;
}
}
#endregion
#region Methods
public IExtension GetExtensionByType(Type type)
{
for (int i = 0; i < this.extensions.Count; i++)
{
if (this.extensions[i].GetType() == type)
{
return this.extensions[i];
}
}
return null;
}
private ISingleInstanceEnforcer GetSingleInstanceEnforcer()
{
return new MainForm();
}
public void InitExtensions()
{
for (int i = 0; i < Extensions.Count; i++)
{
if (Extensions[i] is IInitializable)
{
((IInitializable)Extensions[i]).Init();
}
}
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
for (int i = 0; i < Extensions.Count; i++)
{
if (Extensions[i] is IDisposable)
{
try
{
((IDisposable)Extensions[i]).Dispose();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
}
}
}
public void Start(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
// Attempt to create a tracker
tracker = new SingleInstanceTracker("SingleInstanceSample", new SingleInstanceEnforcerRetriever(GetSingleInstanceEnforcer));
// If this is the first instance of the application, run the main form
if (tracker.IsFirstInstance)
{
try
{
NewDownloadForm df = null;
MainForm form = (MainForm)tracker.Enforcer;
if (args.Length > 0)
{
//form.downloadList1.AddDownloadURLs(ResourceLocation.FromURLArray(args), 1, null, 0);
CommandLineArguments argstruct = new CommandLineArguments();
argstruct.ParseArguments(args);
if (argstruct.StartMinimized == true)
form.WindowState = FormWindowState.Minimized;
//DownloadManager.Instance.Add(ResourceLocation.FromURL(argstruct.File), null, Path.Combine(argstruct.path, Path.GetFileName(argstruct.File)), argstruct.Segments, true);
// form.downloadList1.AddDownloadURLs(ResourceLocation.FromURL(argstruct.File), argstruct.Segments, argstruct.path, 0);
if (argstruct.File != null)
{
df = new NewDownloadForm(argstruct.File, Path.GetFileName(argstruct.File), argstruct.path, argstruct.Segments, argstruct.username, argstruct.password);
df.Show();
df.Focus();
df.BringToFront();
}
}
form.Load += delegate(object sender, EventArgs e)
{
InitExtensions();
if (form.WindowState == FormWindowState.Minimized)
{
form.HideForm();
}
/*if (args.Length > 0)
{
form.OnMessageReceived(new MessageEventArgs(args));
}*/
};
form.FormClosing += delegate(object sender, FormClosingEventArgs e)
{
Dispose();
};
Application.Run(form);
}
finally
{
Dispose();
}
}
else
{
// This is not the first instance of the application, so do nothing but send a message to the first instance
if (args.Length > 0)
{
tracker.SendMessageToFirstInstance(args);
}
}
}
catch (SingleInstancingException ex)
{
MessageBox.Show("Could not create a SingleInstanceTracker object:\n" + ex.Message + "\nApplication will now terminate.\n" + ex.InnerException.ToString());
return;
}
finally
{
if (tracker != null)
tracker.Dispose();
}
}
#endregion
}
}
MyDownloader.App/CommandLineArguments.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Test.CommandLineParsing;
using System.ComponentModel;
using System.IO;
namespace MyDownloader.App
{
class CommandLineArguments
{
public CommandLineArguments()
{
this.path = Path.Combine(System.Environment.GetEnvironmentVariable("USERPROFILE"), "Downloads");
Segments = 1;
username = "";
password = "";
}
[Description("Starts the application minimized to the tray.")]
public bool? StartMinimized { get; set; }
// Backwards compatibility
public bool? @as { get { return this.StartMinimized; } set { this.StartMinimized = value; } }
public string File { get; set; }
public int Segments { get; set; }
public string path { get; set; }
public string username { get; set; }
public string password { get; set; }
}
}
MyDownloader.App/CommandLineParsing/Command.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Provides a base class for the functionality that all commands must implement.
/// </summary>
///
/// <example>
/// The following example shows parsing of a command-line such as "Test.exe RUN /verbose /runId=10"
/// into a strongly-typed Command, that can then be excuted.
/// <code>
/// using System;
/// using System.Linq;
/// using Microsoft.Test.CommandLineParsing;
///
/// public class RunCommand : Command
/// {
/// public bool? Verbose { get; set; }
/// public int? RunId { get; set; }
///
/// public override void Execute()
/// {
/// Console.WriteLine("RunCommand: Verbose={0} RunId={1}", Verbose, RunId);
/// }
/// }
///
/// public class Program
/// {
/// public static void Main(string[] args)
/// {
/// if (String.Compare(args[0], "run", StringComparison.InvariantCultureIgnoreCase) == 0)
/// {
/// Command c = new RunCommand();
/// c.ParseArguments(args.Skip(1)); // or CommandLineParser.ParseArguments(c, args.Skip(1))
/// c.Execute();
/// }
/// }
/// }
/// </code>
/// </example>
public abstract class Command
{
/// <summary>
/// The name of the command. The base implementation is to strip off the last
/// instance of "Command" from the end of the type name. So "DiscoverCommand"
/// would become "Discover". If the type name does not have the string "Command" in it,
/// then the name of the command is the same as the type name. This behavior can be
/// overridden, but most derived classes are going to be of the form [Command Name] + Command.
/// </summary>
public virtual string Name
{
get
{
string typeName = this.GetType().Name;
if (typeName.Contains("Command"))
{
return typeName.Remove(typeName.LastIndexOf("Command", StringComparison.Ordinal));
}
else
{
return typeName;
}
}
}
/// <summary>
/// Executes the command.
/// </summary>
public abstract void Execute();
}
}
MyDownloader.App/CommandLineParsing/CommandLineDictionary.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.Serialization;
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Represents a dictionary that is aware of command line input patterns. All lookups for keys ignore case.
/// </summary>
///
/// <example>
/// The example below demonstrates parsing a command line such as "Test.exe /verbose /runId=10"
/// <code>
/// CommandLineDictionary d = CommandLineDictionary.FromArguments(args);
///
/// bool verbose = d.ContainsKey("verbose");
/// int runId = Int32.Parse(d["runId"]);
/// </code>
/// </example>
///
/// <example>
/// You can also explicitly provide key and value identifiers for the cases
/// that use other characters (rather than '/' and '=') as key/value identifiers.
/// The example below demonstrates parsing a command line such as "Test.exe -verbose -runId:10"
/// <code>
/// CommandLineDictionary d = CommandLineDictionary.FromArguments(args, '-', ':');
///
/// bool verbose = d.ContainsKey("verbose");
/// int runId = Int32.Parse(d["runId"]);
/// </code>
/// </example>
[Serializable]
public class CommandLineDictionary : Dictionary<string, string>
{
#region Constructors
/// <summary>
/// Create an empty CommandLineDictionary using the default key/value
/// separators of '/' and '='.
/// </summary>
public CommandLineDictionary()
: base(StringComparer.OrdinalIgnoreCase)
{
KeyCharacter = '/';
ValueCharacter = '=';
}
/// <summary>
/// Creates a dictionary using a serialization info and context. This
/// is used for Xml deserialization and isn't normally called from user code.
/// </summary>
/// <param name="info">Data needed to deserialize the dictionary.</param>
/// <param name="context">Describes source and destination of the stream.</param>
protected CommandLineDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endregion
#region Public Members
/// <summary>
/// Initializes a new instance of the CommandLineDictionary class, populating a
/// dictionary with key/value pairs from a command line that supports syntax
/// where options are provided in the form "/key=value".
/// </summary>
/// <param name="arguments">Key/value pairs.</param>
/// <returns></returns>
public static CommandLineDictionary FromArguments(IEnumerable<string> arguments)
{
return FromArguments(arguments, '/', '=');
}
/// <summary>
/// Creates a dictionary that is populated with key/value pairs from a command line
/// that supports syntax where options are provided in the form "/key=value".
/// This method supports the ability to specify delimiter characters for options in
/// the command line.
/// </summary>
/// <param name="arguments">Key/value pairs.</param>
/// <param name="keyCharacter">A character that precedes a key.</param>
/// <param name="valueCharacter">A character that separates a key from a value.</param>
/// <returns></returns>
public static CommandLineDictionary FromArguments(IEnumerable<string> arguments, char keyCharacter, char valueCharacter)
{
CommandLineDictionary cld = new CommandLineDictionary();
cld.KeyCharacter = keyCharacter;
cld.ValueCharacter = valueCharacter;
foreach (string argument in arguments)
{
cld.AddArgument(argument);
}
return cld;
}
#endregion
#region Override Members
/// <summary>
/// Converts dictionary contents to a command line string of key/value pairs.
/// </summary>
/// <returns>Command line string.</returns>
public override string ToString()
{
string commandline = String.Empty;
foreach (KeyValuePair<String, String> pair in this)
{
if (!string.IsNullOrEmpty(pair.Value))
{
commandline += String.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3} ", KeyCharacter, pair.Key, ValueCharacter, pair.Value);
}
else // There is no value, so we just serialize the key
{
commandline += String.Format(CultureInfo.InvariantCulture, "{0}{1} ", KeyCharacter, pair.Key);
}
}
return commandline.TrimEnd();
}
#endregion
#region Protected Members
/// <summary>
/// Populates a SerializationInfo with data needed to serialize the dictionary.
/// This is used by Xml serialization and isn't normally called from user code.
/// </summary>
/// <param name="info">SerializationInfo object to populate.</param>
/// <param name="context">StreamingContext to populate data from.</param>
[SuppressMessage("Microsoft.Security", "CA2123")]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
#endregion
#region Private Members
/// <summary>
/// Character to treat as the key character in the value line.
/// If the arguments should be of the form /Foo=Bar, then the
/// key character is /. (Which is the default)
/// </summary>
private char KeyCharacter { get; set; }
/// <summary>
/// Character to treat as the value character in the value line.
/// If the arguments should be of the form /Foo=Bar, then the
/// value character is =. (Which is the default)
/// </summary>
private char ValueCharacter { get; set; }
/// <summary>
/// Adds the specified argument to the dictionary
/// </summary>
/// <param name="argument">Key/Value pair argument.</param>
private void AddArgument(string argument)
{
if (argument == null)
{
throw new ArgumentNullException("argument");
}
string key;
string value;
if (argument.StartsWith(KeyCharacter.ToString(), StringComparison.OrdinalIgnoreCase))
{
string[] splitArg = argument.Substring(1).Split(ValueCharacter);
//Key is extracted from first element
key = splitArg[0];
//Reconstruct the value. We could also do this using substrings.
if (splitArg.Length > 1)
{
value = string.Join("=", splitArg, 1, splitArg.Length - 1);
}
else
{
value = string.Empty;
}
}
else
{
throw new ArgumentException("Unsupported value line argument format.", argument);
}
Add(key, value);
}
#endregion
}
}
MyDownloader.App/CommandLineParsing/CommandLineParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Provides utilities for parsing command-line values.
/// </summary>
///
/// <example>
/// The following example shows parsing of a command-line such as "Test.exe /verbose /runId=10"
/// into a strongly-typed structure.
/// <code>
/// using System;
/// using System.Linq;
/// using Microsoft.Test.CommandLineParsing;
///
/// public class CommandLineArguments
/// {
/// public bool? Verbose { get; set; }
/// public int? RunId { get; set; }
/// }
///
/// public class Program
/// {
/// public static void Main(string[] args)
/// {
/// CommandLineArguments a = new CommandLineArguments();
/// a.ParseArguments(args); // or CommandLineParser.ParseArguments(a, args);
///
/// Console.WriteLine("Verbose: {0}, RunId: {1}", a.Verbose, a.RunId);
/// }
/// }
/// </code>
/// </example>
///
/// <example>
/// The following example shows parsing of a command-line such as "Test.exe RUN /verbose /runId=10"
/// into a strongly-typed Command, that can then be excuted.
/// <code>
/// using System;
/// using System.Linq;
/// using Microsoft.Test.CommandLineParsing;
///
/// public class RunCommand : Command
/// {
/// public bool? Verbose { get; set; }
/// public int? RunId { get; set; }
///
/// public override void Execute()
/// {
/// Console.WriteLine("RunCommand: Verbose={0} RunId={1}", Verbose, RunId);
/// }
/// }
///
/// public class Program
/// {
/// public static void Main(string[] args)
/// {
/// if (String.Compare(args[0], "run", StringComparison.InvariantCultureIgnoreCase) == 0)
/// {
/// Command c = new RunCommand();
/// c.ParseArguments(args.Skip(1)); // or CommandLineParser.ParseArguments(c, args.Skip(1))
/// c.Execute();
/// }
/// }
/// }
/// </code>
/// </example>
public static class CommandLineParser
{
#region Constructors
/// <summary>
/// Static constructor.
/// </summary>
static CommandLineParser()
{
// The parser will want to convert from value line string arguments into various
// data types on a value. Any type that doesn't have a default TypeConverter that
// can convert from string to it's type needs to have a custom TypeConverter written
// for it, and have it added here.
TypeDescriptor.AddAttributes(typeof(DirectoryInfo), new TypeConverterAttribute(typeof(DirectoryInfoConverter)));
TypeDescriptor.AddAttributes(typeof(FileInfo), new TypeConverterAttribute(typeof(FileInfoConverter)));
}
#endregion
#region Public Members
/// <summary>
/// Sets properties on an object from a series of key/value string
/// arguments that are in the form "/PropertyName=Value", where the
/// value is converted from a string into the property type.
/// </summary>
/// <param name="valueToPopulate">The object to set properties on.</param>
/// <param name="args">The key/value arguments describing the property names and values to set.</param>
/// <returns>
/// Indicates whether the properties were successfully set. Reasons for failure reasons include
/// a property name that does not exist or a value that cannot be converted from a string.
/// </returns>
/// <exception cref="System.ArgumentException">Thrown when one of the key/value strings cannot be parsed into a property.</exception>
public static void ParseArguments(this object valueToPopulate, IEnumerable<string> args)
{
CommandLineDictionary commandLineDictionary = CommandLineDictionary.FromArguments(args);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(valueToPopulate);
// Ensure required properties are specified.
foreach (PropertyDescriptor property in properties)
{
// See whether any of the attributes on the property is a RequiredAttribute.
if (property.Attributes.Cast<Attribute>().Any(attribute => attribute is RequiredAttribute))
{
// If so, and the command line dictionary doesn't contain a key matching
// the property's name, it means that a required property isn't specified.
if (!commandLineDictionary.ContainsKey(property.Name))
{
throw new ArgumentException("A value for the " + property.Name + " property is required.");
}
}
}
foreach (KeyValuePair<string, string> keyValuePair in commandLineDictionary)
{
// Find a property whose name matches the kvp's key, ignoring case.
// We can't just use the indexer because that is case-sensitive.
PropertyDescriptor property = MatchProperty(keyValuePair.Key, properties,valueToPopulate.GetType());
// If the value is null/empty and the property is a bool, we
// treat it as a flag, which means its presence means true.
if (String.IsNullOrEmpty(keyValuePair.Value) &&
(property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?)))
{
property.SetValue(valueToPopulate, true);
continue;
}
object valueToSet;
// We support a limited set of collection types. Setting a List<T>
// is one of the most flexible types as it supports three different
// interfaces, but the catch is that we don't support the concrete
// Collection<T> type. We can expand it to support Collection<T>
// in the future, but the code will get a bit uglier.
switch (property.PropertyType.Name)
{
case "IEnumerable`1":
case "ICollection`1":
case "IList`1":
case "List`1":
MethodInfo methodInfo = typeof(CommandLineParser).GetMethod("FromCommaSeparatedList", BindingFlags.Static | BindingFlags.NonPublic);
Type[] genericArguments = property.PropertyType.GetGenericArguments();
MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);
valueToSet = genericMethodInfo.Invoke(null, new object[] { keyValuePair.Value });
break;
default:
TypeConverter typeConverter = TypeDescriptor.GetConverter(property.PropertyType);
if (typeConverter == null || !typeConverter.CanConvertFrom(typeof(string)))
{
throw new ArgumentException("Unable to convert from a string to a property of type " + property.PropertyType + ".");
}
valueToSet = typeConverter.ConvertFromInvariantString(keyValuePair.Value);
break;
}
property.SetValue(valueToPopulate, valueToSet);
}
return;
}
/// <summary>
/// Match the property to the specified keyName
///
/// If match cannot be found, throw an argument exception
/// </summary>
private static PropertyDescriptor MatchProperty(string keyName, PropertyDescriptorCollection properties, Type targetType)
{
foreach(PropertyDescriptor prop in properties)
{
if(prop.Name.Equals(keyName, StringComparison.OrdinalIgnoreCase))
{
return prop;
}
}
throw new ArgumentException("A matching public property of name " + keyName + " on type " + targetType + " could not be found.");
}
/// <summary>
/// Prints names and descriptions for properties on the specified component.
/// </summary>
/// <param name="component">The component to print usage for.</param>
public static void PrintUsage(object component)
{
IEnumerable<PropertyDescriptor> properties = TypeDescriptor.GetProperties(component).Cast<PropertyDescriptor>();
IEnumerable<string> propertyNames = properties.Select(property => property.Name);
IEnumerable<string> propertyDescriptions = properties.Select(property => property.Description);
IEnumerable<string> lines = FormatNamesAndDescriptions(propertyNames, propertyDescriptions, Console.WindowWidth);
Console.WriteLine("Possible arguments:");
foreach (string line in lines)
{
Console.WriteLine(line);
}
}
/// <summary>
/// Prints a general summary of each command.
/// </summary>
/// <param name="commands">A collection of possible commands.</param>
public static void PrintCommands(IEnumerable<Command> commands)
{
// Print out general descriptions for every command.
IEnumerable<string> commandNames = commands.Select(command => command.Name);
IEnumerable<string> commandDescriptions = commands.Select(command => command.GetAttribute<DescriptionAttribute>().Description);
IEnumerable<string> lines = FormatNamesAndDescriptions(commandNames, commandDescriptions, Console.WindowWidth);
Console.WriteLine("Possible commands:");
foreach (string line in lines)
{
Console.WriteLine(line);
}
}
/// <summary>
/// Creates a string that represents key/value arguments for the properties of the
/// specified object. For example, an object with a name (string) of "example" and a
/// priority value (integer) of 1 translates to '/name=example /priority=1'. This
/// can be used to send data structures through the command line.
/// </summary>
/// <param name="valueToConvert">Value to create key/value arguments from.</param>
/// <returns>Space-delimited key/value arguments.</returns>
public static string ToString(object valueToConvert)
{
IEnumerable<PropertyDescriptor> properties = TypeDescriptor.GetProperties(valueToConvert).Cast<PropertyDescriptor>();
IEnumerable<PropertyDescriptor> propertiesOnParent = TypeDescriptor.GetProperties(valueToConvert.GetType().BaseType).Cast<PropertyDescriptor>();
properties = properties.Except(propertiesOnParent);
CommandLineDictionary commandLineDictionary = new CommandLineDictionary();
foreach (PropertyDescriptor property in properties)
{
commandLineDictionary[property.Name] = property.GetValue(valueToConvert).ToString();
}
return commandLineDictionary.ToString();
}
#endregion
#region Private Members
/// <summary>
/// Given collections of names and descriptions, returns a set of lines
/// where the description text is wrapped and left aligned. eg:
/// First Name this is a string that wraps around
/// and is left aligned.
/// Second Name this is another string.
/// </summary>
/// <param name="names">Collection of name strings.</param>
/// <param name="descriptions">Collection of description strings.</param>
/// <param name="maxLineLength">Maximum length of formatted lines</param>
/// <returns>Formatted lines of text.</returns>
private static IEnumerable<string> FormatNamesAndDescriptions(IEnumerable<string> names, IEnumerable<string> descriptions, int maxLineLength)
{
if (names.Count() != descriptions.Count())
{
throw new ArgumentException("Collection sizes are not equal", "names");
}
int namesMaxLength = names.Max(commandName => commandName.Length);
List<string> lines = new List<string>();
for (int i = 0; i < names.Count(); i++)
{
string line = names.ElementAt(i);
line = line.PadRight(namesMaxLength + 2);
foreach (string wrappedLine in WordWrap(descriptions.ElementAt(i), maxLineLength - namesMaxLength - 3))
{
line += wrappedLine;
lines.Add(line);
line = new string(' ', namesMaxLength + 2);
}
}
return lines;
}
/// <summary>
/// Convert a comma separated list to a List of T. There must be a
/// TypeConverter for the collection type that can convert from a string.
/// "1,2,3" => List(int) containing 1, 2, and 3.
/// Commas in the textual representation itself should be escaped with
/// a blackslash, as should backslash itself.
/// </summary>
/// <typeparam name="T">Type of objects in the collection.</typeparam>
/// <param name="commaSeparatedList">Comma separated list representation.</param>
/// <returns>Collection of objects.</returns>
private static List<T> FromCommaSeparatedList<T>(this string commaSeparatedList)
{
List<T> collection = new List<T>();
TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter.CanConvertFrom(typeof(string)))
{
StringBuilder builder = new StringBuilder();
bool isEscaped = false;
foreach (char character in commaSeparatedList)
{
// If we are in escaped mode, add the character and exit escape mode
if (isEscaped)
{
builder.Append(character);
isEscaped = false;
}
// If we see the backslash and are not in escaped mode, go into escaped mode
else if (character == '\\' && !isEscaped)
{
isEscaped = true;
}
// A comma outside of escaped mode is an item separator, convert
// built string to T and add to collection, then zero out the builder
else if (character == ',' && !isEscaped)
{
collection.Add((T)typeConverter.ConvertFromInvariantString(builder.ToString()));
builder.Length = 0;
}
// Otherwise simply add the character
else
{
builder.Append(character);
}
}
// If builder.Length is non-zero, of course we want to add it.
// If, however, it is zero, it can mean one of two things:
// - There are no items at all, i.e. the commaSeparatedList string
// is null/empty, and we should return an empty collection.
// - The builder just got flushed by a comma, and there is one last
// item in the collection to add that should be typeconverted
// from an empty string.
// collection.Count is always 0 for the former and greater than 0
// for the later, so we will also add if Count > 0.
if (builder.Length > 0 || collection.Count > 0)
{
collection.Add((T)typeConverter.ConvertFromInvariantString(builder.ToString()));
}
}
return collection;
}
/// <summary>
/// Gets an attribute on the specified object instance.
/// </summary>
/// <typeparam name="T">Type of attribute to get.</typeparam>
/// <param name="value">Object instance to look for attribute on.</param>
/// <returns>First instance of the specified attribute.</returns>
private static T GetAttribute<T>(this object value) where T : Attribute
{
IEnumerable<Attribute> attributes = TypeDescriptor.GetAttributes(value).Cast<Attribute>();
return (T)attributes.First(attribute => attribute is T);
}
/// <summary>
/// Word wrap text for a specified maximum line length.
/// </summary>
/// <param name="text">Text to word wrap.</param>
/// <param name="maxLineLength">Maximum length of a line.</param>
/// <returns>Collection of lines for the word wrapped text.</returns>
private static IEnumerable<string> WordWrap(string text, int maxLineLength)
{
List<string> lines = new List<string>();
string currentLine = String.Empty;
foreach (string word in text.Split(' '))
{
// Whenever adding the word would push us over the maximum
// width, add the current line to the lines collection and
// begin a new line. The new line starts with space padding
// it to be left aligned with the previous line of text from
// this column.
if (currentLine.Length + word.Length > maxLineLength)
{
lines.Add(currentLine);
currentLine = String.Empty;
}
currentLine += word;
// Add spaces between words except for when we are at exactly the
// maximum width.
if (currentLine.Length != maxLineLength)
{
currentLine += " ";
}
}
// Add the remainder of the current line except for when it is
// empty, which is true in the case when we had just started a
// new line.
if (currentLine.Trim() != String.Empty)
{
lines.Add(currentLine);
}
return lines;
}
#endregion
}
}
MyDownloader.App/CommandLineParsing/DirectoryInfoConverter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
using System.ComponentModel;
using System.IO;
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Converter that can convert from a string to a DirectoryInfo.
/// </summary>
public class DirectoryInfoConverter : TypeConverter
{
/// <summary>
/// Converts from a string to a DirectoryInfo.
/// </summary>
/// <param name="context">Context.</param>
/// <param name="culture">Culture.</param>
/// <param name="value">Value to convert.</param>
/// <returns>DirectoryInfo, or null if value was null or non-string.</returns>
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string && value != null)
{
return new DirectoryInfo((string)value);
}
else
{
return null;
}
}
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
/// <param name="sourceType">A Type that represents the type you want to convert from.</param>
/// <returns>True if this converter can perform the conversion; otherwise, False.</returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return (sourceType == typeof(string));
}
}
}
MyDownloader.App/CommandLineParsing/FileInfoConverter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
using System.ComponentModel;
using System.IO;
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Converter that can convert from a string to a FileInfo.
/// </summary>
public class FileInfoConverter : TypeConverter
{
/// <summary>
/// Converts from a string to a FileInfo.
/// </summary>
/// <param name="context">Context.</param>
/// <param name="culture">Culture.</param>
/// <param name="value">Value to convert.</param>
/// <returns>FileInfo, or null if value was null or non-string.</returns>
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string && value != null)
{
return new FileInfo((string)value);
}
else
{
return null;
}
}
/// <summary>
/// Returns whether this converter can convert an object of the given type to a FileInfo.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
/// <param name="sourceType">A Type that represents the type you want to convert from.</param>
/// <returns>True if this converter can perform the conversion; otherwise, False.</returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return (sourceType == typeof(string));
}
/// <summary>
/// Converts from a FileInfo to a string.
/// </summary>
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value is FileInfo && destinationType == typeof(string))
{
return ((FileInfo)value).FullName;
}
else
{
return null;
}
}
/// <summary>
/// Returns whether this converter can convert a FileInfo object to the specified type.
/// </summary>
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return (destinationType == typeof(string));
}
}
}
MyDownloader.App/CommandLineParsing/NamespaceDoc.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Contains a full-featured API for command-line parsing. The API is exposed
/// in several decoupled layers – from a string-based command-line dictionary,
/// to a strongly-typed command-line parser.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812")]
[System.Runtime.CompilerServices.CompilerGenerated()]
class NamespaceDoc
{
// Empty class used only for generation of namespace comments.
}
}
MyDownloader.App/CommandLineParsing/RequiredAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
namespace Microsoft.Test.CommandLineParsing
{
/// <summary>
/// Defines whether a property value is required to be specified.
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class RequiredAttribute : Attribute
{
/// <summary />
public RequiredAttribute()
{
}
}
}
MyDownloader.App/Controls/Block.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.App.Controls
{
[Serializable()]
public class Block
{
private float _blockSize = 0;
private float _percentProgress = 0;
public Block(float BlockSize, float PercentProgress)
{
this.BlockSize = BlockSize;
this.PercentProgress = PercentProgress;
}
public float BlockSize
{
get { return _blockSize; }
set { _blockSize = value; }
}
public float PercentProgress
{
get { return _percentProgress; }
set { _percentProgress = value; }
}
}
}
MyDownloader.App/Controls/BlockList.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.App.Controls
{
[Serializable()]
public class BlockList
{
private int _length = 0;
private List<Block> _blockList;
public BlockList()
{
_blockList = new List<Block>();
}
public enum UpdateMode
{
All,
FilledSegments,
FullListSegment,
BlockList
}
/// <summary>
/// Update mode of segments
/// </summary>
public UpdateMode Update = UpdateMode.All;
/// <summary>
/// Change quantity of segments
/// </summary>
public int Length
{
get { return _length; }
set
{
if (_length != value && value > 0)
{
bool[] bools = FullListSegment;
bool[] bools2 = new bool[value];
for (int i = 0; i < bools.Length; i++)
bools2[i] = bools[i];
FullListSegment = bools2;
}
}
}
/// <summary>
/// Get or set filled segments
/// </summary>
public int[] FilledSegments
{
get
{
bool[] bools = FullListSegment;
List<int> filled = new List<int>(); ;
for (int i = 0; i < bools.Length; i++)
if (bools[i]) filled.Add(i);
return filled.ToArray();
}
set
{
if (Update != UpdateMode.All && Update != UpdateMode.FilledSegments)
throw new InvalidOperationException();
if (value != null)
if (value.Length > 0)
{
bool[] bools = FullListSegment;
for (int i = 0; i < value.Length; i++)
bools.SetValue(true, value[i]);
FullListSegment = bools;
}
}
}
/// <summary>
/// Get or sets the full list of segments
/// </summary>
public bool[] FullListSegment
{
get
{
int size_anterior = 0;
bool[] bools = new bool[_length];
if (bools.Length > 0)
{
foreach (Block block in _blockList)
{
for (int i = 0; i < Convert.ToInt32(block.BlockSize * block.PercentProgress / 100); i++)
bools.SetValue(true, i + size_anterior);
size_anterior += Convert.ToInt32(block.BlockSize);
}
}
return bools;
}
set
{
if (Update != UpdateMode.All && Update != UpdateMode.FullListSegment)
throw new InvalidOperationException();
bool b_old = false;
int qtd = 0;
int filled = 0;
float percent = 0;
if (value != null)
{
if (value.Length > 0)
{
_blockList.Clear();
foreach (bool b in value)
{
if (b == b_old)
qtd++;
else
{
if (b_old)
filled = qtd;
else if (filled + qtd > 0)
{
percent = (float)filled / (float)(filled + qtd) * (float)100;
_blockList.Add(new Block(filled + qtd, percent));
}
qtd = 1;
b_old = b;
}
}
if (filled + qtd > 0)
{
percent = (float)filled / (float)(filled + qtd) * (float)100;
_blockList.Add(new Block(filled + qtd, percent));
}
_length = value.Length;
}
}
else
{
_length = 0;
}
}
}
/// <summary>
/// Get or set the block list of segments
/// </summary>
public List<Block> List
{
get
{
return _blockList;
}
set
{
if (Update != UpdateMode.All && Update != UpdateMode.BlockList)
throw new InvalidOperationException();
float size = 0;
_blockList = value;
if (_blockList != null)
foreach (Block block in _blockList)
size += block.BlockSize;
_length = Convert.ToInt32(size);
}
}
}
}
MyDownloader.App/Controls/BlockedProgressBar.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.App.Controls
{
[ToolboxBitmap(typeof(BlockedProgressBar), "BlockedProgressBar.bmp")] //without namespace
public partial class BlockedProgressBar : Control
{
BlockList _blockList;
/// <summary>
/// MyProgressBar Constructor
/// </summary>
public BlockedProgressBar()
{
InitializeComponent();
_blockList = new BlockList();
_direction = DirectionMode.Horizontal;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true);
}
/// <summary>
/// Update mode of segments
/// </summary>
[Description("The mode of update of progress bar")]
[Category("MyProgressBar")]
[RefreshProperties(RefreshProperties.All)]
public BlockList.UpdateMode UpdateMode
{
get { return _blockList.Update; }
set { _blockList.Update = value; }
}
/// <summary>
/// Change quantity of segments
/// </summary>
[Description("The length of segments of progress bar")]
[Category("MyProgressBar")]
[RefreshProperties(RefreshProperties.All)]
public int Length
{
get { return _blockList.Length; }
set { _blockList.Length = value; this.Refresh(); }
}
/// <summary>
/// Get or set filled segments
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int[] FilledSegments
{
get { return _blockList.FilledSegments; }
set { _blockList.FilledSegments = value; this.Refresh(); }
}
/// <summary>
/// Get or sets the full list of segments
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool[] FullListSegment
{
get { return _blockList.FullListSegment; }
set { _blockList.FullListSegment = value; this.Refresh(); }
}
/// <summary>
/// Get or set the block list of segments
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<Block> BlockList
{
get { return _blockList.List; }
set { _blockList.List = value; this.Refresh(); }
}
/// <summary>
/// DirectionMode of bar
/// </summary>
public enum DirectionMode : int
{
Horizontal = 0,
Vertical = 1
}
private DirectionMode _direction = DirectionMode.Horizontal;
/// <summary>
/// Horizontal or Vertical
/// </summary>
[Description("The filling direction of progress bar")]
[Category("MyProgressBar")]
[RefreshProperties(RefreshProperties.All)]
public DirectionMode Direction
{
get { return _direction; }
set { _direction = value; this.Refresh(); }
}
/// <summary>
/// OnPaint event
/// </summary>
/// <param name="pe"></param>
protected override void OnPaint(PaintEventArgs pe)
{
Color Color1 = ControlPaint.Dark(this.ForeColor);
Color Color2 = ControlPaint.Light(this.ForeColor);
if (_direction == DirectionMode.Horizontal)
{
int top = ClientRectangle.Top + ClientRectangle.Height / 2 - 1;
int height = ClientRectangle.Height - top;
DrawRectangleH(pe, top, height, Color2, Color1);
top = ClientRectangle.Top;
height = ClientRectangle.Height / 2;
DrawRectangleH(pe, top, height, Color1, Color2);
}
else
{
int left = ClientRectangle.Left;
int width = ClientRectangle.Width / 2;
DrawRectangleV(pe, left, width, Color1, Color2);
left = ClientRectangle.Left + ClientRectangle.Width / 2;
width = ClientRectangle.Width / 2;
DrawRectangleV(pe, left, width, Color2, Color1);
}
pe.Graphics.DrawRectangle(new Pen(Color.Black), ClientRectangle);
base.OnPaint(pe);
}
private void DrawRectangleH(PaintEventArgs pe, int top, int height, Color fromColor, Color toColor)
{
Rectangle rect = new Rectangle(ClientRectangle.Left, top, ClientRectangle.Width, height);
LinearGradientBrush brush = new LinearGradientBrush(rect, fromColor, toColor, LinearGradientMode.Vertical);
if (_blockList.Length > 0)
{
Rectangle[] rects = GetRectanglesH(top, height);
if (rects.Length > 0) pe.Graphics.FillRectangles(brush, rects); //SystemBrushes.Control
}
}
private void DrawRectangleV(PaintEventArgs pe, int left, int width, Color fromColor, Color toColor)
{
Rectangle rect = new Rectangle(left, ClientRectangle.Top, width, ClientRectangle.Height);
LinearGradientBrush brush = new LinearGradientBrush(rect, fromColor, toColor, LinearGradientMode.Horizontal);
if (_blockList.Length > 0)
{
Rectangle[] rects = GetRectanglesV(left, width);
if (rects.Length > 0) pe.Graphics.FillRectangles(brush, rects); //SystemBrushes.Control
}
}
private Rectangle[] GetRectanglesH(int top, int height)
{
List<Rectangle> rects = new List<Rectangle>();
float xf = 0, wf = 0, pf = 1;
int x = 0, y = top, w = 0, h = height;
pf = (float)this.Width / (float)_blockList.Length;
//h = this.Height;
foreach (Block block in _blockList.List)
{
if (block.PercentProgress > 0)
{
x = Convert.ToInt32(xf);
wf = (pf * (block.BlockSize * block.PercentProgress / 100)) + xf - x;
w = Convert.ToInt32(wf);
rects.Add(new Rectangle(x, y, w, h));
}
xf += pf * block.BlockSize;
}
return rects.ToArray();
}
private Rectangle[] GetRectanglesV(int left, int width)
{
List<Rectangle> rects = new List<Rectangle>();
float yf = 0, hf = 0, pf = 1;
int x = left, y = 0, w = width, h = 0;
pf = (float)this.Height / (float)_blockList.Length;
//w = this.Width;
foreach (Block block in _blockList.List)
{
if (block.PercentProgress > 0)
{
y = Convert.ToInt32(yf);
hf = (pf * (block.BlockSize * block.PercentProgress / 100)) + yf - y;
h = Convert.ToInt32(hf);
rects.Add(new Rectangle(x, y, w, h));
}
yf += pf * block.BlockSize;
}
return rects.ToArray();
}
}
}
MyDownloader.App/Controls/BlockedProgressBar.designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System.Collections;
namespace MyDownloader.App.Controls
{
partial class BlockedProgressBar
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}
MyDownloader.App/Controls/CheckableTreeView.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.App.Controls
{
public class CheckableTreeView: TreeView
{
private static bool IsSomeChildNodeChecked(TreeNode node)
{
for (int i = 0; i < node.Nodes.Count; i++)
{
if (node.Nodes[i].Checked)
{
return true;
}
}
return false;
}
private static void CheckAllChildren(TreeNode node, bool check)
{
for (int i = 0; i < node.Nodes.Count; i++)
{
if (node.Nodes[i].Checked != check)
{
node.Nodes[i].Checked = check;
}
CheckAllChildren(node.Nodes[i], check);
}
}
protected override void OnAfterCheck(TreeViewEventArgs e)
{
base.OnAfterCheck(e);
if (!(e.Action == TreeViewAction.ByKeyboard || e.Action == TreeViewAction.ByMouse))
{
return;
}
try
{
this.BeginUpdate();
// the node if checked...
if (e.Node.Checked)
{
// check all child nodes...
CheckAllChildren(e.Node, true);
// check all parents...
TreeNode parent = e.Node.Parent;
while (parent != null)
{
if (!parent.Checked) parent.Checked = true;
parent = parent.Parent;
}
}
else
{
// check all child nodes...
CheckAllChildren(e.Node, false);
// uncheck the parent node if all child nodes are unchecked...
TreeNode parent = e.Node.Parent;
while (parent != null)
{
if (!IsSomeChildNodeChecked(parent)) parent.Checked = false;
parent = parent.Parent;
}
}
}
finally
{
this.EndUpdate();
}
}
}
}
MyDownloader.App/DONE.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
* limite da rate
* melhorar calculo de rate
* popup notify icon
* (OK) janela de download de video
* (OK) funcionar
* autenticacao na URL ftp
* rever tratamento de erros, pois nem todas as excecoes estao sendo capturas
* http://keepvid.com/
* Support for GVideo
* Support for YouTube
* Support for Putfile
* Support for Metacafe
* Support for Break - esse site tb prove o formato WMV
* Melhorar na parte inferior colocar uma tabControl: Segments | Log
* jobs/scheduler:
* numero maximo de jobs
* se mandou startar, vai embora
* Testar HTTPs Downloader
* download d arquivos q o servidor nao diz o tamanho
* Tela de download batch suportar autentication
* urls alternativas
* cada URL pode ser de um tipo diferente
* validar se o arquivo no mirror tem o mesmo tamanho
* Qnd retoma um download pausado nao ta fazendo retry
* melhorar integracao com parte do marco (chamar mtas imagems)
* melhorar o refresh de UI
* se o arquivo no servidor mudou?
* ter diretorio comum para salvar
* mudar tela de new donwload
* mudar jeito que processa parametros de entrada
* performance para salvar a lista de downloads (xml serializer)
* melhorar uso de CPU qnd a lista fica grande
* tela de batch download
* exibir erro Downloader.LastError na UI
* executar arquivo do concluir
* se tenta retomar arquivo que nao suporta ranges
* se falhar ao obter o file info deixar como erro e tentar + tarde
* calcular tempo que download consuminiu no total (added date)
* about box
* mostrar plug'in
* link para site
* se um segmento falhar tentar + tarde (configurado)
* ordenacao da lista na UI
* subir balao no relogio do windows qnd download terminar
* sons para notificar eventos
* se fechou o programa qnd esta em needtoPrepare ou preparing da erro na volta
pois nesse caso ainda nao gerou os segmentos
* evitar que seja aberta 1 conexao pra pegar o info e depois seja despresada
* download de YouTUbe
* se um segmento terminar, quebrar o que esta rodando em 2
* salvar estados dos downloads para reiniciar a aplicacao
* configuracao visual do proxy
* integracao com anti-virus
* formatar os bytes em casas decimais para exibir no grid
* download via FTP
* download via HTTP
* download segmentado
* pause e restart
* tornar o download http e ftp uma extensions
MyDownloader.App/MyDownloader.App.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{18AE3994-8F48-49B1-AC63-342F70ED1135}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyDownloader.App</RootNamespace>
<AssemblyName>MyDownloader.App</AssemblyName>
<StartupObject>
</StartupObject>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<ApplicationIcon>Download.ico</ApplicationIcon>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.85.4.369, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="TabStrip, Version=2.0.2523.29272, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\TabStrip.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App.cs" />
<Compile Include="CommandLineArguments.cs" />
<Compile Include="CommandLineParsing\Command.cs" />
<Compile Include="CommandLineParsing\CommandLineDictionary.cs" />
<Compile Include="CommandLineParsing\CommandLineParser.cs" />
<Compile Include="CommandLineParsing\DirectoryInfoConverter.cs" />
<Compile Include="CommandLineParsing\FileInfoConverter.cs" />
<Compile Include="CommandLineParsing\NamespaceDoc.cs" />
<Compile Include="CommandLineParsing\RequiredAttribute.cs" />
<Compile Include="Controls\Block.cs" />
<Compile Include="Controls\BlockList.cs" />
<Compile Include="Controls\BlockedProgressBar.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Controls\BlockedProgressBar.designer.cs">
<DependentUpon>BlockedProgressBar.cs</DependentUpon>
</Compile>
<Compile Include="Controls\CheckableTreeView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="SingleInstancing\ISingleInstanceEnforcer.cs" />
<Compile Include="SingleInstancing\MessageEventArgs.cs" />
<Compile Include="SingleInstancing\SingleInstanceException.cs" />
<Compile Include="SingleInstancing\SingleInstanceProxy.cs" />
<Compile Include="SingleInstancing\SingleInstanceTracker.cs" />
<Compile Include="UI\AboutForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\AboutForm.Designer.cs">
<DependentUpon>AboutForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\CreateBatchDownloadForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\CreateBatchDownloadForm.Designer.cs">
<DependentUpon>CreateBatchDownloadForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\DownloadList.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\DownloadList.Designer.cs">
<DependentUpon>DownloadList.cs</DependentUpon>
</Compile>
<Compile Include="UI\FileTypeImageList.cs" />
<Compile Include="UI\IconReader.cs" />
<Compile Include="UI\ImportFromFileForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\ImportFromFileForm.Designer.cs">
<DependentUpon>ImportFromFileForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\ImportFromFilePreviewForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\ImportFromFilePreviewForm.Designer.cs">
<DependentUpon>ImportFromFilePreviewForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\NewDownloadForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\NewDownloadForm.Designer.cs">
<DependentUpon>NewDownloadForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\OptionsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\OptionsForm.Designer.cs">
<DependentUpon>OptionsForm.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Controls\BlockedProgressBar.bmp" />
<Content Include="DONE.txt" />
<Content Include="Download.ico" />
<Content Include="TODO.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyDownloader.Core\MyDownloader.Core.csproj">
<Project>{E763345E-6696-4C53-8764-47E4ABD67DEF}</Project>
<Name>MyDownloader.Core</Name>
</ProjectReference>
<ProjectReference Include="..\MyDownloader.Extension\MyDownloader.Extension.csproj">
<Project>{FEA18B6C-491F-401A-A06B-AE47888FF288}</Project>
<Name>MyDownloader.Extension</Name>
</ProjectReference>
<ProjectReference Include="..\MyDownloader.Spider\MyDownloader.Spider.csproj">
<Project>{69C99442-953E-4559-96D3-C82CC57A3C87}</Project>
<Name>MyDownloader.Spider</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="UI\AboutForm.resx">
<SubType>Designer</SubType>
<DependentUpon>AboutForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\MainForm.resx">
<SubType>Designer</SubType>
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\OptionsForm.resx">
<SubType>Designer</SubType>
<DependentUpon>OptionsForm.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<EmbeddedResource Include="Properties\Resources.resx">
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="UI\About.rtf" />
<EmbeddedResource Include="UI\CreateBatchDownloadForm.resx">
<SubType>Designer</SubType>
<DependentUpon>CreateBatchDownloadForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\DownloadList.resx">
<SubType>Designer</SubType>
<DependentUpon>DownloadList.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\ImportFromFileForm.resx">
<SubType>Designer</SubType>
<DependentUpon>ImportFromFileForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\ImportFromFilePreviewForm.resx">
<SubType>Designer</SubType>
<DependentUpon>ImportFromFilePreviewForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\NewDownloadForm.resx">
<DependentUpon>NewDownloadForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
MyDownloader.App/Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using MyDownloader.Core;
using System.Diagnostics;
using System.Windows.Forms;
using MyDownloader.App.UI;
using MyDownloader.Extension.Protocols;
using MyDownloader.Extension.Video;
using MyDownloader.Extension.Video.Impl;
namespace MyDownloader.App
{
class Program
{
[STAThread]
static void Main(string[] args)
{
App.Instance.Start(args);
}
}
}
MyDownloader.App/Properties/AssemblyInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("MyDownloader.App")]
[assembly: AssemblyDescription(
@"
.Net Download Manager
Nathan Adams -
My Downloader
Glacial ListView - Copyright Glacial Components Software 2004 - http://www.glacialcomponents.com/"
)]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct(@".Net Download Manager")]
[assembly: AssemblyCopyright("")]
[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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e962837f-7d13-4b2b-9f04-e9c2f871f155")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]
MyDownloader.App/Properties/Resources.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.App.Properties {
using System;
/// <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 (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MyDownloader.App.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;
}
}
}
}
MyDownloader.App/Properties/Resources.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.App/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.App {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool ViewTransDetails {
get {
return ((bool)(this["ViewTransDetails"]));
}
set {
this["ViewTransDetails"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool ViewToolbar {
get {
return ((bool)(this["ViewToolbar"]));
}
set {
this["ViewToolbar"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool ViewGrid {
get {
return ((bool)(this["ViewGrid"]));
}
set {
this["ViewGrid"] = value;
}
}
}
}
MyDownloader.App/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.App" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="ViewTransDetails" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="ViewToolbar" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="ViewGrid" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.App/SingleInstancing/ISingleInstanceEnforcer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
namespace MyDownloader.App.SingleInstancing
{
/// <summary>
/// Provides methods which a single instance application can use to in order to be respond to any new instance of it.
/// </summary>
public interface ISingleInstanceEnforcer
{
/// <summary>
/// Handles messages received from a new instance of the application.
/// </summary>
/// <param name="e">The EventArgs object holding information about the event.</param>
void OnMessageReceived(MessageEventArgs e);
/// <summary>
/// Handles a creation of a new instance of the application.
/// </summary>
/// <param name="e">The EventArgs object holding information about the event.</param>
void OnNewInstanceCreated(EventArgs e);
}
}
MyDownloader.App/SingleInstancing/MessageEventArgs.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
namespace MyDownloader.App.SingleInstancing
{
/// <summary>
/// Provides data for the SingleInstancing.ISingleInstanceEnforcer.OnMessageReceived method.
/// </summary>
[Serializable()]
public class MessageEventArgs : EventArgs
{
#region Member Variables
private object message;
#endregion
#region Construction / Destruction
/// <summary>
/// Instantiates a new MessageEventArgs object.
/// </summary>
/// <param name="message">The message to pass to the first running instance of the application.</param>
/// <exception cref="System.ArgumentNullException">message is null.</exception>
public MessageEventArgs(object message)
{
if (message == null)
throw new ArgumentNullException("message", "message cannot be null.");
this.message = message;
}
#endregion
#region Properties
/// <summary>
/// Gets the message sent to the first instance of the application.
/// </summary>
public object Message
{
get
{
return message;
}
}
#endregion
}
}
MyDownloader.App/SingleInstancing/SingleInstanceException.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Runtime.Serialization;
namespace MyDownloader.App.SingleInstancing
{
/// <summary>
/// Represents errors occured while trying to enforce single application instancing.
/// </summary>
[Serializable()]
public class SingleInstancingException : Exception
{
#region Construction / Destruction
/// <summary>
/// Instantiates a new SingleInstancingException object.
/// </summary>
public SingleInstancingException() { }
/// <summary>
/// Instantiates a new SingleInstancingException object.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public SingleInstancingException(string message)
: base(message) { }
/// <summary>
/// Instantiates a new SingleInstancingException object.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="inner">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
public SingleInstancingException(string message, Exception inner)
: base(message, inner) { }
/// <summary>
/// Instantiates a new SingleInstancingException object with serialized data.
/// </summary>
/// <param name="info">The System.Runtime.Serialization.SerializationInfo that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The System.Runtime.Serialization.StreamingContext that contains contextual information about the source or destination.</param>
protected SingleInstancingException(SerializationInfo info, StreamingContext context)
: base(info, context) { }
#endregion
}
}
MyDownloader.App/SingleInstancing/SingleInstanceProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
namespace MyDownloader.App.SingleInstancing
{
/// <summary>
/// Provides a proxy to communicate with the first instance of the application.
/// </summary>
internal class SingleInstanceProxy : MarshalByRefObject
{
#region Member Variables
private ISingleInstanceEnforcer enforcer;
#endregion
#region Construction / Destruction
/// <summary>
/// Instantiates a new SingleInstanceProxy object.
/// </summary>
/// <param name="enforcer">The enforcer (first instance of the application) which will receive messages from the new instances of the application.</param>
/// <exception cref="System.ArgumentNullException">enforcer is null.</exception>
public SingleInstanceProxy(ISingleInstanceEnforcer enforcer)
{
if (enforcer == null)
throw new ArgumentNullException("enforcer", "enforcer cannot be null.");
this.enforcer = enforcer;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the enforcer (first instance of the application) which will receive messages from the new instances of the application.
/// </summary>
public ISingleInstanceEnforcer Enforcer
{
get
{
return enforcer;
}
}
#endregion
///
/// Override and return NULL to prevent windows from doing
/// garbage collection on the proxy object.
///
public override object InitializeLifetimeService()
{
return null;
}
}
}
MyDownloader.App/SingleInstancing/SingleInstanceTracker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
using System;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
namespace MyDownloader.App.SingleInstancing
{
/// <summary>
/// Represents the method which would be used to retrieve an ISingleInstanceEnforcer object when instantiating a SingleInstanceTracker object.
/// If the method returns null, the SingleInstanceTracker's constructor will throw an exception.
/// </summary>
/// <returns>An ISingleInstanceEnforcer object which would receive messages.</returns>
public delegate ISingleInstanceEnforcer SingleInstanceEnforcerRetriever();
/// <summary>
/// Represents an object used to check for a previous instance of an application, and sending messages to it.
/// </summary>
public class SingleInstanceTracker : IDisposable
{
#region Member Variables
private bool disposed;
private Mutex singleInstanceMutex;
private bool isFirstInstance;
private IChannel ipcChannel;
private SingleInstanceProxy proxy;
#endregion
#region Construction / Destruction
/// <summary>
/// Instantiates a new SingleInstanceTracker object.
/// When using this constructor it is assumed that there is no need for sending messages to the first application instance.
/// To enable the tracker's ability to send messages to the first instance, use the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) constructor overload instead.
/// </summary>
/// <param name="name">The unique name used to identify the application.</param>
/// <exception cref="System.ArgumentNullException">name is null or empty.</exception>
/// <exception cref="SingleInstancing.SingleInstancingException">A general error occured while trying to instantiate the SingleInstanceInteractor. See InnerException for more details.</exception>
public SingleInstanceTracker(string name)
: this(name, null) { }
/// <summary>
/// Instantiates a new SingleInstanceTracker object.
/// When using this constructor overload and enforcerRetriever is null, the SingleInstanceTracker object can only be used to determine whether the application is already running.
/// </summary>
/// <param name="name">The unique name used to identify the application.</param>
/// <param name="enforcerRetriever">The method which would be used to retrieve an ISingleInstanceEnforcer object when instantiating the new object.</param>
/// <exception cref="System.ArgumentNullException">name is null or empty.</exception>
/// <exception cref="SingleInstancing.SingleInstancingException">A general error occured while trying to instantiate the SingleInstanceInteractor. See InnerException for more details.</exception>
public SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name", "name cannot be null or empty.");
try
{
singleInstanceMutex = new Mutex(true, name, out isFirstInstance);
// Do not attempt to construct the IPC channel if there is no need for messages
if (enforcerRetriever != null)
{
string proxyObjectName = "SingleInstanceProxy";
string proxyUri = "ipc://" + name + "/" + proxyObjectName;
// If no previous instance was found, create a server channel which will provide the proxy to the first created instance
if (isFirstInstance)
{
// Create an IPC server channel to listen for SingleInstanceProxy object requests
ipcChannel = new IpcServerChannel(name);
// Register the channel and get it ready for use
ChannelServices.RegisterChannel(ipcChannel, false);
// Register the service which gets the SingleInstanceProxy object, so it can be accessible by IPC client channels
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SingleInstanceProxy), proxyObjectName, WellKnownObjectMode.Singleton);
// Attempt to retrieve the enforcer from the delegated method
ISingleInstanceEnforcer enforcer = enforcerRetriever();
// Validate that an enforcer object was returned
if (enforcer == null)
throw new InvalidOperationException("The method delegated by the enforcerRetriever argument returned null. The method must return an ISingleInstanceEnforcer object.");
// Create the first proxy object
proxy = new SingleInstanceProxy(enforcer);
// Publish the first proxy object so IPC clients requesting a proxy would receive a reference to it
RemotingServices.Marshal(proxy, proxyObjectName);
}
else
{
// Create an IPC client channel to request the existing SingleInstanceProxy object.
ipcChannel = new IpcClientChannel();
// Register the channel and get it ready for use
ChannelServices.RegisterChannel(ipcChannel, false);
// Retreive a reference to the proxy object which will be later used to send messages
proxy = (SingleInstanceProxy)Activator.GetObject(typeof(SingleInstanceProxy), proxyUri);
// Notify the first instance of the application that a new instance was created
// proxy.Enforcer.OnNewInstanceCreated(new EventArgs());
}
}
}
catch (Exception ex)
{
throw new SingleInstancingException("Failed to instantiate a new SingleInstanceTracker object. See InnerException for more details.", ex);
}
}
/// <summary>
/// Releases all unmanaged resources used by the object.
/// </summary>
~SingleInstanceTracker()
{
Dispose(false);
}
#region IDisposable Members
/// <summary>
/// Releases all unmanaged resources used by the object, and potentially releases managed resources.
/// </summary>
/// <param name="disposing">true to dispose of managed resources; otherwise false.</param>
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (singleInstanceMutex != null)
{
singleInstanceMutex.Close();
singleInstanceMutex = null;
}
if (ipcChannel != null)
{
ChannelServices.UnregisterChannel(ipcChannel);
ipcChannel = null;
}
}
disposed = true;
}
}
/// <summary>
/// Releases all resources used by the object.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#endregion
#region Member Functions
/// <summary>
/// Sends a message to the first instance of the application.
/// </summary>
/// <param name="message">The message to send to the first instance of the application. The message must be serializable.</param>
/// <exception cref="System.InvalidOperationException">The object was constructed with the SingleInstanceTracker(string name) constructor overload, or with the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) cosntructor overload, with enforcerRetriever set to null.</exception>
/// <exception cref="SingleInstancing.SingleInstancingException">The SingleInstanceInteractor has failed to send the message to the first application instance. The first instance might have terminated.</exception>
public void SendMessageToFirstInstance(object message)
{
if (disposed)
throw new ObjectDisposedException("The SingleInstanceTracker object has already been disposed.");
if (ipcChannel == null)
throw new InvalidOperationException("The object was constructed with the SingleInstanceTracker(string name) constructor overload, or with the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) constructor overload, with enforcerRetriever set to null, thus you cannot send messages to the first instance.");
try
{
proxy.Enforcer.OnMessageReceived(new MessageEventArgs(message));
}
catch (Exception ex)
{
throw new SingleInstancingException("Failed to send message to the first instance of the application. The first instance might have terminated.", ex);
}
}
#endregion
#region Properties
/// <summary>
/// Gets a value indicating whether this instance of the application is the first instance.
/// </summary>
public bool IsFirstInstance
{
get
{
if (disposed)
throw new ObjectDisposedException("The SingleInstanceTracker object has already been disposed.");
return isFirstInstance;
}
}
/// <summary>
/// Gets the single instance enforcer (the first instance of the application) which would receive messages.
/// </summary>
public ISingleInstanceEnforcer Enforcer
{
get
{
if (disposed)
throw new ObjectDisposedException("The SingleInstanceTracker object has already been disposed.");
return proxy.Enforcer;
}
}
#endregion
}
}
MyDownloader.App/TODO.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed(*).wmv
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed10.wmv
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed09.wmv
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed08.wmv
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed07.wmv
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed06.wmv
http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed05.wmv
* http://downloads.uol.com.br/windows/web/save2pc.jhtm
* http://baixaki.ig.com.br/
* http://www.shareit.com/
www.superdownlods.com ( e o blog)
* ok - Conta no paypal
* Site
* Instalador para versao final
* Nome "unico"
* Creditos:
BandObjectLib
TabStrip
--------------------------- VERSION 2
* (OK) (Video Download) Convert video to AVI,MPEG,MP3 using ffmpeg.exe
* (OK) Vai salver direto no formato, qual extensao usar na hr de salvar?
* (OK) Salvar o formato do video no downlods.xml
* (OK) Colocar o nome do video na tela de download video, pegar o nome do arquivo pelo titutlo no site
* (OK) Ja traz URL no campo qnd abre uma janela de new download e ja tem no clipboard
* (OK) import from text file
* (OK) New column on download list "Resume": Yes or No
* (OK) Confirmar para deletar downloads
* (OK) Fix view toolbar, nao esta ajudastando o tamanho!
* (OK) Criar controle folder browser
* (OK) Nas edicoes de rate, qnd aplica as cotas, as vezes da erro
* (OK) move up / move down in download queue - http://www.codeproject.com/KB/cpp/listview.aspx?print=true
* (OK) Tabs na janela principal http://www.codeproject.com/cs/miscctrl/TabStrip.asp
* (OK) Renomear o scheduler para Auto-Downloads
* (OK) Opcao para ativar modo scheduler no star-up, Is it possible to start downloading, by starting the Downloader
* (OK) Fix de performance na download lista
* (OK) Qnd add pl spider adiciona varios lisks, fica lerdo
* (OK) Remover dependencia com GlacialList.dll
* (OK) batch windows (import file and bacths from url)
* (OK) Option to start the scheduler
* (OK) Set simutaneos downloads limit
* (OK) Pause, esta demorando mto
* (OK) deve abortar as threads?
* (OK) Pause all junto com o speed limit, da dead lock
* (OK) Speed limit deixa o pause all lento
* (OK) Lock da download list deve ser de 1 - writer e N readers
* (OK) Testar autenticacao http
* (OK) Authentication in http
* (OK) let the software start as a service, so it would start automaically in the background when windows login
* (OK) Rever o parser de html do gringo
* (OK) Acho que pode colocar na tela de "Import From File"
* (OK) Algo como "Import from HTML" e ai tb exibe um campo base URL
* (OK) Melhorar calculo de rate
* (OK) qnd baixando arquivo local e poe limite, demora mto pra cair
* (OK) em muitos downloads ao mesmo tempo, o rate fica mto auto
* (Speed Limit)
* (OK) Testar se com varios download a performance nao cai (cpu)
* Option to disable the speed limit while screen saver is running or computer is idle
* (OK) Improve
* (OK) Integrar com scheduler
* (OK) Especificar horarios que nao deve trabalhar
* (OK) Especificar horarios com limites
* (OK) Testar
* (OK) Todas as janelas
* (OK) Rever tab order
* (OK) Rever accep button e cancel button
* HTML Spider
* (OK) Desabilitar os botoes de Download/Abort
* (OK) Colocar animacao tipo do google reader
* (OK) IFRAME, FRAMES
* (OK) Abort
* (OK) Permitir imagens fora de location?
* (OK) Filtros
* (OK) Ignore Nome
* (OK) Ignore Extension
* (OK) Download deaph
* (OK) Remove from list when completed
* (OK) Bug nas reg. expressions
<p><a href=""><img src="/Content/images/home/adcast.jpg" width="540" height="158" alt="Castle Stronghold" /></a></p>
<span id="newsnavleft"><a href="">&lt;</a></span>
<span id="newsnavright"><a href="">&gt;</a></span>
<p>If you have any question, do not hesitate to <a href="">contact us</a>. We would be pleased to talk to you.</p>
</div>
* (OK) Melhorar gerenciamento de conexao
* (OK) Um download da erro e ai fica parado por mto tempo e os outros ficam esperando
* (OK) Clipboard monitor
* (OK) Integrate with IE
* (OK) Qnd for site de video, mostrar animacao - http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=469442&SiteID=1
* (OK) Interceptar clicks de links and ALT apertado
* (OK) Chamar o processo
* (OK) Botao de "Lauch MD"
* (OK) Botao do video
* (OK) Validar entrada de dados nos forms
* Procurar TODO
* OK - Allow user to explore ZIP file before download
* OK - Colocar controle de espera qnd esta listando conteudo do zip
* Testes:
* ok - Esquema dos horarios do download scheduler
* ok - Se o rate fica controlado no horario configurado e depois volta
* Testar mais sites no Web Spider
* URL superiror tem IFRAME http://www2.uol.com.br/chantili/ensaios/renata_soares2/g0_0.htm
http://www2.uol.com.br/chantili/ensaios/index.html?pamela_vogue
* ok - Tirar URL padrao dos controles de location
* ok - Tirar URL padrao no Web Spider
* Testar opcao de subir junto com o Windows
* ok - importar URLs
* ok - Testar video (todos os sites)
* ok - Testar video conversao
* ok- Testar + download de ZIP
* ok - Teste arquivo sem size
* ok - Clipboard monitor
--------------------------- VERSION 3
* Grabber++
* how about support for categories, downloading, downloaded, trash, and custom folders/categories.
* new function: check update of the downloaded file, if newer version(last modified date) exists, download the new one, ask for replace the old one.
if add a new download file that already downloaded, allow to apply new download settings(new file path/name etc).
1. add new download item, the download folder textbox will be better to be combobox remembering latest folders (could be configured at options, default is 10) ;-)
2. allow to autorun at win startup;
3. set referer of http download to avoid some anti-pirate link websites;
4. larger default buffer, how about 4M, you know, nowadays, wide bandwidth [laugh]
* double click download item to open file/directory
* support auto redirect, it seems that it does not support auto url redirection [doh]
* Integrate with IE
* Para links simples funciona, mas para rapidshare/webmails nao
* Simplificar nome dos elementos XML no save
* DropZone
* Aceita drag de HTML (abrir janela pedindo URL base)
* Aceita drag de link
* Melhorar o algortimo de selecao do mirror
* tempo do ping
* Localizacao
* download rate do download anterior
* Download batch = FDM
* XY graph to display the transfer rate
* AutoShut down after download end
* Shutdownl
* Hibernate
* Restart
* Close MD
* Add Site login user name & password; coz I use RAPIDSHARE a lot and I have a user name and password for it,
but it is not supported by your program
* Integrate with FF
* Option to "Run when terminate"
* Fazer parecido com o FDM, abri uma janela com um timer para cancelar a execucao
* incluir um botao para excluir todos aqueles "tentando sem conseguir" no myFreeDownLoaderByGui
* Create download category and allow user to label the downloads
* Search for TODO in code
* Authentication in https
* FTP should have a separated proxy setting
* add / remove segments in download while downloading
* (Video Download) Media monitor to intercept traffic from IE / FF.
* Show a progress bar like emule in download list -> ***||**||||**|||
* MetaLink http://en.wikipedia.org/wiki/Metalink
* Download from MMS
* reteste em caso de falhas no segmento
* qnd o segmento termina nao esta vendo isso direito (o download do NFS tinha termando mais ainda continuava tentando baixar)
* Lock da segment list deve ser de 1 - writer e N readers
* Evento que usa o DownloaderEventArgs, pode ficar + simples, as vezes se adiciona uma lsita mto grande
* No Speed Limit, como chama toda hr o TotalSpeed faz mto lock na download list se juntar com o WebSpider ficara mto ruim
* Pause/Pause All - Fazer assincrono para tela nao travar
* Se Download == Pausing, deixar o sleep = 0 no SpeedLimit
MyDownloader.App/UI/AboutForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
namespace MyDownloader.App.UI
{
partial class AboutForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.okButton = new System.Windows.Forms.Button();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.lvwPlugs = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.tabPage3 = new System.Windows.Forms.TabPage();
this.richTextBox2 = new System.Windows.Forms.RichTextBox();
this.tableLayoutPanel.SuspendLayout();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage3.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel
//
this.tableLayoutPanel.ColumnCount = 1;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel.Controls.Add(this.okButton, 0, 1);
this.tableLayoutPanel.Controls.Add(this.tabControl1, 0, 0);
this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 2;
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel.Size = new System.Drawing.Size(343, 349);
this.tableLayoutPanel.TabIndex = 0;
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Location = new System.Drawing.Point(265, 323);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 1;
this.okButton.Text = "&OK";
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(3, 3);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(337, 314);
this.tabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.richTextBox1);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(329, 288);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "About";
this.tabPage1.UseVisualStyleBackColor = true;
//
// richTextBox1
//
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.richTextBox1.Location = new System.Drawing.Point(3, 3);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(323, 282);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = "";
this.richTextBox1.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.richTextBox1_LinkClicked);
this.richTextBox1.TextChanged += new System.EventHandler(this.richTextBox1_TextChanged);
//
// tabPage2
//
this.tabPage2.Controls.Add(this.lvwPlugs);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(329, 288);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Plug\'ins";
this.tabPage2.UseVisualStyleBackColor = true;
//
// lvwPlugs
//
this.lvwPlugs.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
this.lvwPlugs.Dock = System.Windows.Forms.DockStyle.Fill;
this.lvwPlugs.FullRowSelect = true;
this.lvwPlugs.GridLines = true;
this.lvwPlugs.Location = new System.Drawing.Point(3, 3);
this.lvwPlugs.Name = "lvwPlugs";
this.lvwPlugs.Size = new System.Drawing.Size(323, 282);
this.lvwPlugs.TabIndex = 0;
this.lvwPlugs.UseCompatibleStateImageBehavior = false;
this.lvwPlugs.View = System.Windows.Forms.View.Details;
//
// columnHeader1
//
this.columnHeader1.Text = "Plug\'n";
this.columnHeader1.Width = 213;
//
// columnHeader2
//
this.columnHeader2.Text = "Version";
this.columnHeader2.Width = 92;
//
// tabPage3
//
this.tabPage3.Controls.Add(this.richTextBox2);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
this.tabPage3.Size = new System.Drawing.Size(329, 288);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Licenses";
this.tabPage3.UseVisualStyleBackColor = true;
//
// richTextBox2
//
this.richTextBox2.Location = new System.Drawing.Point(3, 3);
this.richTextBox2.Name = "richTextBox2";
this.richTextBox2.Size = new System.Drawing.Size(323, 282);
this.richTextBox2.TabIndex = 0;
this.richTextBox2.Text = resources.GetString("richTextBox2.Text");
//
// AboutForm
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.okButton;
this.ClientSize = new System.Drawing.Size(361, 367);
this.Controls.Add(this.tableLayoutPanel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AboutForm";
this.Padding = new System.Windows.Forms.Padding(9);
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "About";
this.tableLayoutPanel.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.ListView lvwPlugs;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.RichTextBox richTextBox2;
}
}
MyDownloader.App/UI/AboutForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using MyDownloader.Core.UI;
using MyDownloader.Core.Extensions;
using System.Resources;
using System.IO;
using System.Globalization;
using System.Diagnostics;
namespace MyDownloader.App.UI
{
partial class AboutForm : Form
{
public AboutForm()
{
InitializeComponent();
// Initialize the AboutBox to display the product information from the assembly information.
// Change assembly information settings for your application through either:
// - Project->Properties->Application->Assembly Information
// - AssemblyInfo.cs
this.Text = String.Format("About {0}", AssemblyTitle);
for (int i = 0; i < AppManager.Instance.Application.Extensions.Count; i++)
{
IExtension ext = AppManager.Instance.Application.Extensions[i];
ListViewItem item = new ListViewItem(ext.Name);
item.SubItems.Add(AssemblyVersion(ext.GetType().Assembly));
lvwPlugs.Items.Add(item);
}
using (Stream s = this.GetType().Assembly.GetManifestResourceStream("MyDownloader.App.UI.About.rtf"))
{
richTextBox1.LoadFile(s, RichTextBoxStreamType.RichText);
}
}
#region Assembly Attribute Accessors
public string AssemblyTitle
{
get
{
// Get all Title attributes on this assembly
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
// If there is at least one Title attribute
if (attributes.Length > 0)
{
// Select the first one
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
// If it is not an empty string, return it
if (titleAttribute.Title != "")
return titleAttribute.Title;
}
// If there was no Title attribute, or if the Title attribute was the empty string, return the .exe name
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
}
}
public string AssemblyVersion(Assembly a)
{
return a.GetName().Version.ToString();
}
//public string AssemblyDescription
//{
// get
// {
// // Get all Description attributes on this assembly
// object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
// // If there aren't any Description attributes, return an empty string
// if (attributes.Length == 0)
// return "";
// // If there is a Description attribute, return its value
// return ((AssemblyDescriptionAttribute)attributes[0]).Description;
// }
//}
//public string AssemblyProduct
//{
// get
// {
// // Get all Product attributes on this assembly
// object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
// // If there aren't any Product attributes, return an empty string
// if (attributes.Length == 0)
// return "";
// // If there is a Product attribute, return its value
// return ((AssemblyProductAttribute)attributes[0]).Product;
// }
//}
//public string AssemblyCopyright
//{
// get
// {
// // Get all Copyright attributes on this assembly
// object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
// // If there aren't any Copyright attributes, return an empty string
// if (attributes.Length == 0)
// return "";
// // If there is a Copyright attribute, return its value
// return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
// }
//}
//public string AssemblyCompany
//{
// get
// {
// // Get all Company attributes on this assembly
// object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
// // If there aren't any Company attributes, return an empty string
// if (attributes.Length == 0)
// return "";
// // If there is a Company attribute, return its value
// return ((AssemblyCompanyAttribute)attributes[0]).Company;
// }
//}
#endregion
private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
Process.Start(e.LinkText);
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
MyDownloader.App/UI/AboutForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<data name="richTextBox2.Text" xml:space="preserve">
<value>.Net Download Manager is Licensed under the Apache Version 2.0.
DNDM also uses the following projects from other developers:
* A command line parser licensed under the MS-PL.
* A ini parser licensed under MIT
Apache License 2.0
Copyright [2012]
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.
Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</value>
</data>
</root>
MyDownloader.App/UI/CreateBatchDownloadForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
using MyDownloader.Core.UI;
namespace MyDownloader.App.UI
{
partial class CreateBatchDownloadForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.numSegments = new System.Windows.Forms.NumericUpDown();
this.label2 = new System.Windows.Forms.Label();
this.rdoNumbers = new System.Windows.Forms.RadioButton();
this.rdoLetters = new System.Windows.Forms.RadioButton();
this.label3 = new System.Windows.Forms.Label();
this.txtTo = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.txtFrom = new System.Windows.Forms.TextBox();
this.label6 = new System.Windows.Forms.Label();
this.lvwListPreview = new System.Windows.Forms.ListBox();
this.button2 = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.numWildcard = new System.Windows.Forms.NumericUpDown();
this.label8 = new System.Windows.Forms.Label();
this.numFrom = new System.Windows.Forms.NumericUpDown();
this.numTo = new System.Windows.Forms.NumericUpDown();
this.folderBrowser1 = new MyDownloader.Core.UI.DownloadFolder();
this.location1 = new MyDownloader.App.UI.Location();
this.scheduledDownloadEnabler1 = new MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler();
((System.ComponentModel.ISupportInitialize)(this.numSegments)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numWildcard)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numFrom)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numTo)).BeginInit();
this.SuspendLayout();
//
// numSegments
//
this.numSegments.Location = new System.Drawing.Point(401, 110);
this.numSegments.Name = "numSegments";
this.numSegments.Size = new System.Drawing.Size(75, 20);
this.numSegments.TabIndex = 13;
this.numSegments.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(398, 94);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(54, 13);
this.label2.TabIndex = 12;
this.label2.Text = "Segments";
//
// rdoNumbers
//
this.rdoNumbers.AutoSize = true;
this.rdoNumbers.Checked = true;
this.rdoNumbers.Location = new System.Drawing.Point(7, 95);
this.rdoNumbers.Name = "rdoNumbers";
this.rdoNumbers.Size = new System.Drawing.Size(45, 17);
this.rdoNumbers.TabIndex = 1;
this.rdoNumbers.TabStop = true;
this.rdoNumbers.Text = "from";
this.rdoNumbers.UseVisualStyleBackColor = true;
this.rdoNumbers.CheckedChanged += new System.EventHandler(this.rdoNumbers_CheckedChanged);
//
// rdoLetters
//
this.rdoLetters.AutoSize = true;
this.rdoLetters.Location = new System.Drawing.Point(7, 124);
this.rdoLetters.Name = "rdoLetters";
this.rdoLetters.Size = new System.Drawing.Size(45, 17);
this.rdoLetters.TabIndex = 7;
this.rdoLetters.TabStop = true;
this.rdoLetters.Text = "from";
this.rdoLetters.UseVisualStyleBackColor = true;
this.rdoLetters.CheckedChanged += new System.EventHandler(this.rdoNumbers_CheckedChanged);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(117, 99);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(16, 13);
this.label3.TabIndex = 3;
this.label3.Text = "to";
//
// txtTo
//
this.txtTo.Location = new System.Drawing.Point(139, 123);
this.txtTo.MaxLength = 1;
this.txtTo.Name = "txtTo";
this.txtTo.Size = new System.Drawing.Size(52, 20);
this.txtTo.TabIndex = 10;
this.txtTo.TextChanged += new System.EventHandler(this.numFrom_ValueChanged);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(117, 127);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(16, 13);
this.label4.TabIndex = 9;
this.label4.Text = "to";
//
// txtFrom
//
this.txtFrom.Location = new System.Drawing.Point(59, 123);
this.txtFrom.MaxLength = 1;
this.txtFrom.Name = "txtFrom";
this.txtFrom.Size = new System.Drawing.Size(52, 20);
this.txtFrom.TabIndex = 8;
this.txtFrom.TextChanged += new System.EventHandler(this.numFrom_ValueChanged);
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(4, 194);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(113, 13);
this.label6.TabIndex = 15;
this.label6.Text = "Download list preview:";
//
// lvwListPreview
//
this.lvwListPreview.FormattingEnabled = true;
this.lvwListPreview.Location = new System.Drawing.Point(8, 208);
this.lvwListPreview.Name = "lvwListPreview";
this.lvwListPreview.Size = new System.Drawing.Size(468, 95);
this.lvwListPreview.TabIndex = 16;
//
// button2
//
this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button2.Location = new System.Drawing.Point(400, 472);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 19;
this.button2.Text = "Cancel";
this.button2.UseVisualStyleBackColor = true;
//
// button1
//
this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
this.button1.Location = new System.Drawing.Point(319, 472);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 18;
this.button1.Text = "OK";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(197, 98);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(97, 13);
this.label7.TabIndex = 5;
this.label7.Text = "Length of wildcard:";
//
// numWildcard
//
this.numWildcard.Location = new System.Drawing.Point(300, 94);
this.numWildcard.Name = "numWildcard";
this.numWildcard.Size = new System.Drawing.Size(75, 20);
this.numWildcard.TabIndex = 6;
this.numWildcard.Value = new decimal(new int[] {
2,
0,
0,
0});
this.numWildcard.ValueChanged += new System.EventHandler(this.numFrom_ValueChanged);
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(197, 127);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(80, 13);
this.label8.TabIndex = 11;
this.label8.Text = "(case sensitive)";
//
// numFrom
//
this.numFrom.Location = new System.Drawing.Point(59, 94);
this.numFrom.Name = "numFrom";
this.numFrom.Size = new System.Drawing.Size(52, 20);
this.numFrom.TabIndex = 2;
this.numFrom.ValueChanged += new System.EventHandler(this.numFrom_ValueChanged);
//
// numTo
//
this.numTo.Location = new System.Drawing.Point(139, 94);
this.numTo.Maximum = new decimal(new int[] {
100000,
0,
0,
0});
this.numTo.Name = "numTo";
this.numTo.Size = new System.Drawing.Size(52, 20);
this.numTo.TabIndex = 4;
this.numTo.ValueChanged += new System.EventHandler(this.numFrom_ValueChanged);
//
// folderBrowser1
//
this.folderBrowser1.LabelText = "Save to:";
this.folderBrowser1.Location = new System.Drawing.Point(7, 149);
this.folderBrowser1.Name = "folderBrowser1";
this.folderBrowser1.Size = new System.Drawing.Size(468, 42);
this.folderBrowser1.TabIndex = 14;
//
// location1
//
this.location1.Location = new System.Drawing.Point(7, 0);
this.location1.Name = "location1";
this.location1.Size = new System.Drawing.Size(468, 87);
this.location1.TabIndex = 0;
this.location1.UrlLabelTitle = "URL (e.g http://download.microsoft.com/file(*).zip)";
//
// scheduledDownloadEnabler1
//
this.scheduledDownloadEnabler1.Location = new System.Drawing.Point(8, 304);
this.scheduledDownloadEnabler1.Name = "scheduledDownloadEnabler1";
this.scheduledDownloadEnabler1.Size = new System.Drawing.Size(468, 164);
this.scheduledDownloadEnabler1.TabIndex = 17;
//
// CreateBatchDownloadForm
//
this.AcceptButton = this.button1;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.button2;
this.ClientSize = new System.Drawing.Size(482, 499);
this.Controls.Add(this.scheduledDownloadEnabler1);
this.Controls.Add(this.folderBrowser1);
this.Controls.Add(this.location1);
this.Controls.Add(this.numTo);
this.Controls.Add(this.numFrom);
this.Controls.Add(this.label8);
this.Controls.Add(this.numWildcard);
this.Controls.Add(this.label7);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.lvwListPreview);
this.Controls.Add(this.label6);
this.Controls.Add(this.txtTo);
this.Controls.Add(this.label4);
this.Controls.Add(this.txtFrom);
this.Controls.Add(this.label3);
this.Controls.Add(this.rdoLetters);
this.Controls.Add(this.rdoNumbers);
this.Controls.Add(this.numSegments);
this.Controls.Add(this.label2);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "CreateBatchDownloadForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Create batch download";
this.Load += new System.EventHandler(this.CreateBatchDownloadForm_Load);
((System.ComponentModel.ISupportInitialize)(this.numSegments)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numWildcard)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numFrom)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numTo)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.NumericUpDown numSegments;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.RadioButton rdoNumbers;
private System.Windows.Forms.RadioButton rdoLetters;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtTo;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtFrom;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.ListBox lvwListPreview;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.NumericUpDown numWildcard;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.NumericUpDown numFrom;
private System.Windows.Forms.NumericUpDown numTo;
private Location location1;
private DownloadFolder folderBrowser1;
private MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler scheduledDownloadEnabler1;
}
}
MyDownloader.App/UI/CreateBatchDownloadForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using MyDownloader.Core;
using MyDownloader.Core.Common;
using MyDownloader.Core.UI;
namespace MyDownloader.App.UI
{
public partial class CreateBatchDownloadForm : Form
{
public CreateBatchDownloadForm()
{
InitializeComponent();
location1.UrlChanged += new EventHandler(numFrom_ValueChanged);
}
private static ResourceLocation GetNumberURL(ResourceLocation locationBase, int i, int wildcard)
{
ResourceLocation r = locationBase.Clone();
r.URL = locationBase.URL.Replace("(*)", i.ToString().PadLeft(wildcard, '0'));
return r;
}
private ResourceLocation GetCharURL(ResourceLocation locationBase, string c)
{
ResourceLocation r = locationBase.Clone();
r.URL = locationBase.URL.Replace("(*)", c);
return r;
}
public string DownloadPath
{
get
{
return folderBrowser1.Folder;
}
}
public int Segments
{
get
{
return (int)numSegments.Value;
}
}
public ResourceLocation[] URLs
{
get
{
ResourceLocation[] result = new ResourceLocation[0];
//TODO: multiple location handle here
ResourceLocation locationBase = location1.ResourceLocation[0];
if (rdoNumbers.Checked)
{
int from = (int)numFrom.Value;
int to = (int)numTo.Value;
int wildcard = (int)numWildcard.Value;
if (from <= to)
{
result = new ResourceLocation[to - from + 1];
for (int i = from, j = 0; i <= to; i++, j++)
{
result[j] = GetNumberURL(locationBase, i, wildcard);
}
}
else
{
result = new ResourceLocation[2];
result[0] = GetNumberURL(locationBase, from, wildcard);
result[1] = GetNumberURL(locationBase, to, wildcard);
}
}
else
{
string strFrom = txtFrom.Text;
string strTo = txtTo.Text;
if (String.IsNullOrEmpty(strTo) && !String.IsNullOrEmpty(strFrom))
{
result = new ResourceLocation[1];
result[0] = GetCharURL(locationBase, strFrom);
}
else if (!String.IsNullOrEmpty(strTo) && String.IsNullOrEmpty(strFrom))
{
result = new ResourceLocation[1];
result[0] = GetCharURL(locationBase, strTo);
}
else if (!String.IsNullOrEmpty(strTo) && !String.IsNullOrEmpty(strFrom))
{
char from = strFrom[0];
char to = strTo[0];
if (from <= to)
{
result = new ResourceLocation[((int)(to - from)) + 1];
int j = 0;
for (char i = from; i <= to; i++)
{
result[j++] = GetCharURL(locationBase, i.ToString());
}
}
else
{
result = new ResourceLocation[2];
result[0] = GetCharURL(locationBase, strFrom);
result[1] = GetCharURL(locationBase, strTo);
}
}
}
return result;
}
}
private void PreviewURLs()
{
lvwListPreview.BeginUpdate();
lvwListPreview.DataSource = URLs;
lvwListPreview.EndUpdate();
}
private void numFrom_ValueChanged(object sender, EventArgs e)
{
PreviewURLs();
}
private void rdoNumbers_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
PreviewURLs();
}
private void UpdateUI()
{
numFrom.Enabled = rdoNumbers.Checked;
numTo.Enabled = rdoNumbers.Checked;
numWildcard.Enabled = rdoNumbers.Checked;
txtFrom.Enabled = rdoLetters.Checked;
txtTo.Enabled = rdoLetters.Checked;
}
private void CreateBatchDownloadForm_Load(object sender, EventArgs e)
{
UpdateUI();
}
public void ApplySettings()
{
scheduledDownloadEnabler1.ApplySettings();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
//TODO: multiple location handle here
ResourceLocation rl = this.location1.ResourceLocation[0];
rl.BindProtocolProviderType();
if (rl.ProtocolProviderType == null)
{
MessageBox.Show("Invalid URL format, please check the location field.",
AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
DialogResult = DialogResult.None;
return;
}
}
catch
{
DialogResult = DialogResult.None;
MessageBox.Show("Unknow error, please check your input data.",
AppManager.Instance.Application.MainForm.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}
MyDownloader.App/UI/CreateBatchDownloadForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.App/UI/DownloadList.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
namespace MyDownloader.App.UI
{
partial class DownloadList
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
this.lvwDownloads = new System.Windows.Forms.ListView();
this.columnFile = new System.Windows.Forms.ColumnHeader();
this.columnSize = new System.Windows.Forms.ColumnHeader();
this.columnCompleted = new System.Windows.Forms.ColumnHeader();
this.columnProgress = new System.Windows.Forms.ColumnHeader();
this.columnLeft = new System.Windows.Forms.ColumnHeader();
this.columnRate = new System.Windows.Forms.ColumnHeader();
this.columnAdded = new System.Windows.Forms.ColumnHeader();
this.columnState = new System.Windows.Forms.ColumnHeader();
this.columnResume = new System.Windows.Forms.ColumnHeader();
this.columnURL = new System.Windows.Forms.ColumnHeader();
this.popUpContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.newDownloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.startToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pauseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
this.openFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyURLToClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showInExplorerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.tabSegmentsLogs = new System.Windows.Forms.TabControl();
this.tabSegments = new System.Windows.Forms.TabPage();
this.blockedProgressBar1 = new MyDownloader.App.Controls.BlockedProgressBar();
this.lvwSegments = new System.Windows.Forms.ListView();
this.columnCurrentTry = new System.Windows.Forms.ColumnHeader();
this.columnSegProgress = new System.Windows.Forms.ColumnHeader();
this.columnSegCompleted = new System.Windows.Forms.ColumnHeader();
this.columnSegSize = new System.Windows.Forms.ColumnHeader();
this.columnStartPosition = new System.Windows.Forms.ColumnHeader();
this.columnEndPosition = new System.Windows.Forms.ColumnHeader();
this.columnSegRate = new System.Windows.Forms.ColumnHeader();
this.columnSegLeft = new System.Windows.Forms.ColumnHeader();
this.columnSegState = new System.Windows.Forms.ColumnHeader();
this.columnCurrURL = new System.Windows.Forms.ColumnHeader();
this.tabLog = new System.Windows.Forms.TabPage();
this.richLog = new System.Windows.Forms.RichTextBox();
this.logContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.clearLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer2.Panel1.SuspendLayout();
this.splitContainer2.Panel2.SuspendLayout();
this.splitContainer2.SuspendLayout();
this.popUpContextMenu.SuspendLayout();
this.tabSegmentsLogs.SuspendLayout();
this.tabSegments.SuspendLayout();
this.tabLog.SuspendLayout();
this.logContextMenu.SuspendLayout();
this.SuspendLayout();
//
// splitContainer2
//
this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer2.Location = new System.Drawing.Point(0, 0);
this.splitContainer2.Name = "splitContainer2";
this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer2.Panel1
//
this.splitContainer2.Panel1.Controls.Add(this.lvwDownloads);
//
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.tabSegmentsLogs);
this.splitContainer2.Size = new System.Drawing.Size(722, 436);
this.splitContainer2.SplitterDistance = 211;
this.splitContainer2.TabIndex = 15;
//
// lvwDownloads
//
this.lvwDownloads.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnFile,
this.columnSize,
this.columnCompleted,
this.columnProgress,
this.columnLeft,
this.columnRate,
this.columnAdded,
this.columnState,
this.columnResume,
this.columnURL});
this.lvwDownloads.ContextMenuStrip = this.popUpContextMenu;
this.lvwDownloads.Dock = System.Windows.Forms.DockStyle.Fill;
this.lvwDownloads.FullRowSelect = true;
this.lvwDownloads.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvwDownloads.HideSelection = false;
this.lvwDownloads.Location = new System.Drawing.Point(0, 0);
this.lvwDownloads.Name = "lvwDownloads";
this.lvwDownloads.ShowGroups = false;
this.lvwDownloads.ShowItemToolTips = true;
this.lvwDownloads.Size = new System.Drawing.Size(722, 211);
this.lvwDownloads.TabIndex = 0;
this.lvwDownloads.UseCompatibleStateImageBehavior = false;
this.lvwDownloads.View = System.Windows.Forms.View.Details;
this.lvwDownloads.DoubleClick += new System.EventHandler(this.lvwDownloads_DoubleClick);
this.lvwDownloads.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvwDownloads_ItemSelectionChanged);
//
// columnFile
//
this.columnFile.Text = "File";
this.columnFile.Width = 98;
//
// columnSize
//
this.columnSize.Text = "Size";
this.columnSize.Width = 80;
//
// columnCompleted
//
this.columnCompleted.Text = "Completed";
this.columnCompleted.Width = 81;
//
// columnProgress
//
this.columnProgress.Text = "Progress";
this.columnProgress.Width = 63;
//
// columnLeft
//
this.columnLeft.Text = "Left";
this.columnLeft.Width = 70;
//
// columnRate
//
this.columnRate.Text = "Rate";
this.columnRate.Width = 72;
//
// columnAdded
//
this.columnAdded.Text = "Added";
this.columnAdded.Width = 77;
//
// columnState
//
this.columnState.Text = "State";
this.columnState.Width = 97;
//
// columnResume
//
this.columnResume.Text = "Resume";
//
// columnURL
//
this.columnURL.Text = "URL";
this.columnURL.Width = 171;
//
// popUpContextMenu
//
this.popUpContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.newDownloadToolStripMenuItem,
this.toolStripSeparator5,
this.startToolStripMenuItem,
this.pauseToolStripMenuItem,
this.toolStripSeparator6,
this.removeToolStripMenuItem,
this.toolStripSeparator7,
this.openFileToolStripMenuItem,
this.copyURLToClipboardToolStripMenuItem,
this.showInExplorerToolStripMenuItem});
this.popUpContextMenu.Name = "contextMenuStrip1";
this.popUpContextMenu.Size = new System.Drawing.Size(196, 176);
this.popUpContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.popUpContextMenu_Opening);
//
// newDownloadToolStripMenuItem
//
this.newDownloadToolStripMenuItem.Name = "newDownloadToolStripMenuItem";
this.newDownloadToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.newDownloadToolStripMenuItem.Text = "New Download...";
this.newDownloadToolStripMenuItem.Click += new System.EventHandler(this.newDownloadToolStripMenuItem_Click);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(192, 6);
//
// startToolStripMenuItem
//
this.startToolStripMenuItem.Name = "startToolStripMenuItem";
this.startToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.startToolStripMenuItem.Text = "Start";
this.startToolStripMenuItem.Click += new System.EventHandler(this.startToolStripMenuItem_Click);
//
// pauseToolStripMenuItem
//
this.pauseToolStripMenuItem.Name = "pauseToolStripMenuItem";
this.pauseToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.pauseToolStripMenuItem.Text = "Pause";
this.pauseToolStripMenuItem.Click += new System.EventHandler(this.pauseToolStripMenuItem_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(192, 6);
//
// removeToolStripMenuItem
//
this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
this.removeToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.removeToolStripMenuItem.Text = "Remove";
this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
//
// toolStripSeparator7
//
this.toolStripSeparator7.Name = "toolStripSeparator7";
this.toolStripSeparator7.Size = new System.Drawing.Size(192, 6);
//
// openFileToolStripMenuItem
//
this.openFileToolStripMenuItem.Name = "openFileToolStripMenuItem";
this.openFileToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.openFileToolStripMenuItem.Text = "Open File";
this.openFileToolStripMenuItem.Click += new System.EventHandler(this.openFileToolStripMenuItem_Click);
//
// copyURLToClipboardToolStripMenuItem
//
this.copyURLToClipboardToolStripMenuItem.Name = "copyURLToClipboardToolStripMenuItem";
this.copyURLToClipboardToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.copyURLToClipboardToolStripMenuItem.Text = "Copy URL to Clipboard";
this.copyURLToClipboardToolStripMenuItem.Click += new System.EventHandler(this.copyURLToClipboardToolStripMenuItem_Click);
//
// showInExplorerToolStripMenuItem
//
this.showInExplorerToolStripMenuItem.Name = "showInExplorerToolStripMenuItem";
this.showInExplorerToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.showInExplorerToolStripMenuItem.Text = "Show in Explorer";
this.showInExplorerToolStripMenuItem.Click += new System.EventHandler(this.showInExplorerToolStripMenuItem_Click);
//
// tabSegmentsLogs
//
this.tabSegmentsLogs.Controls.Add(this.tabSegments);
this.tabSegmentsLogs.Controls.Add(this.tabLog);
this.tabSegmentsLogs.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabSegmentsLogs.Location = new System.Drawing.Point(0, 0);
this.tabSegmentsLogs.Name = "tabSegmentsLogs";
this.tabSegmentsLogs.SelectedIndex = 0;
this.tabSegmentsLogs.Size = new System.Drawing.Size(722, 221);
this.tabSegmentsLogs.TabIndex = 0;
//
// tabSegments
//
this.tabSegments.Controls.Add(this.blockedProgressBar1);
this.tabSegments.Controls.Add(this.lvwSegments);
this.tabSegments.Location = new System.Drawing.Point(4, 22);
this.tabSegments.Name = "tabSegments";
this.tabSegments.Padding = new System.Windows.Forms.Padding(3);
this.tabSegments.Size = new System.Drawing.Size(714, 195);
this.tabSegments.TabIndex = 0;
this.tabSegments.Text = "Segments";
this.tabSegments.UseVisualStyleBackColor = true;
//
// blockedProgressBar1
//
this.blockedProgressBar1.BackColor = System.Drawing.SystemColors.Window;
this.blockedProgressBar1.Direction = MyDownloader.App.Controls.BlockedProgressBar.DirectionMode.Horizontal;
this.blockedProgressBar1.Dock = System.Windows.Forms.DockStyle.Top;
this.blockedProgressBar1.ForeColor = System.Drawing.SystemColors.GradientActiveCaption;
this.blockedProgressBar1.Length = 0;
this.blockedProgressBar1.Location = new System.Drawing.Point(3, 3);
this.blockedProgressBar1.Name = "blockedProgressBar1";
this.blockedProgressBar1.Size = new System.Drawing.Size(708, 23);
this.blockedProgressBar1.TabIndex = 0;
this.blockedProgressBar1.Text = "blockedProgressBar1";
this.blockedProgressBar1.UpdateMode = MyDownloader.App.Controls.BlockList.UpdateMode.All;
//
// lvwSegments
//
this.lvwSegments.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lvwSegments.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnCurrentTry,
this.columnSegProgress,
this.columnSegCompleted,
this.columnSegSize,
this.columnStartPosition,
this.columnEndPosition,
this.columnSegRate,
this.columnSegLeft,
this.columnSegState,
this.columnCurrURL});
this.lvwSegments.FullRowSelect = true;
this.lvwSegments.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvwSegments.HideSelection = false;
this.lvwSegments.Location = new System.Drawing.Point(3, 30);
this.lvwSegments.Name = "lvwSegments";
this.lvwSegments.ShowGroups = false;
this.lvwSegments.ShowItemToolTips = true;
this.lvwSegments.Size = new System.Drawing.Size(708, 162);
this.lvwSegments.TabIndex = 1;
this.lvwSegments.UseCompatibleStateImageBehavior = false;
this.lvwSegments.View = System.Windows.Forms.View.Details;
//
// columnCurrentTry
//
this.columnCurrentTry.Text = "Current Try";
this.columnCurrentTry.Width = 66;
//
// columnSegProgress
//
this.columnSegProgress.Text = "Progress";
this.columnSegProgress.Width = 80;
//
// columnSegCompleted
//
this.columnSegCompleted.Text = "Completed";
this.columnSegCompleted.Width = 81;
//
// columnSegSize
//
this.columnSegSize.Text = "Size";
this.columnSegSize.Width = 77;
//
// columnStartPosition
//
this.columnStartPosition.Text = "Start Position";
this.columnStartPosition.Width = 97;
//
// columnEndPosition
//
this.columnEndPosition.Text = "End Position";
this.columnEndPosition.Width = 100;
//
// columnSegRate
//
this.columnSegRate.Text = "Rate";
this.columnSegRate.Width = 55;
//
// columnSegLeft
//
this.columnSegLeft.Text = "Left";
this.columnSegLeft.Width = 80;
//
// columnSegState
//
this.columnSegState.Text = "State";
this.columnSegState.Width = 133;
//
// columnCurrURL
//
this.columnCurrURL.Text = "Current URL";
this.columnCurrURL.Width = 100;
//
// tabLog
//
this.tabLog.Controls.Add(this.richLog);
this.tabLog.Location = new System.Drawing.Point(4, 22);
this.tabLog.Name = "tabLog";
this.tabLog.Padding = new System.Windows.Forms.Padding(3);
this.tabLog.Size = new System.Drawing.Size(714, 195);
this.tabLog.TabIndex = 1;
this.tabLog.Text = "Log";
this.tabLog.UseVisualStyleBackColor = true;
//
// richLog
//
this.richLog.BackColor = System.Drawing.SystemColors.Window;
this.richLog.ContextMenuStrip = this.logContextMenu;
this.richLog.Dock = System.Windows.Forms.DockStyle.Fill;
this.richLog.Location = new System.Drawing.Point(3, 3);
this.richLog.Name = "richLog";
this.richLog.ReadOnly = true;
this.richLog.Size = new System.Drawing.Size(708, 189);
this.richLog.TabIndex = 0;
this.richLog.Text = "";
this.richLog.WordWrap = false;
//
// logContextMenu
//
this.logContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.clearLogToolStripMenuItem});
this.logContextMenu.Name = "logContextMenu";
this.logContextMenu.Size = new System.Drawing.Size(125, 26);
//
// clearLogToolStripMenuItem
//
this.clearLogToolStripMenuItem.Name = "clearLogToolStripMenuItem";
this.clearLogToolStripMenuItem.Size = new System.Drawing.Size(124, 22);
this.clearLogToolStripMenuItem.Text = "Clear Log";
this.clearLogToolStripMenuItem.Click += new System.EventHandler(this.clearLogToolStripMenuItem_Click);
//
// DownloadList
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.splitContainer2);
this.Name = "DownloadList";
this.Size = new System.Drawing.Size(722, 436);
this.Load += new System.EventHandler(this.DownloadList_Load);
this.splitContainer2.Panel1.ResumeLayout(false);
this.splitContainer2.Panel2.ResumeLayout(false);
this.splitContainer2.ResumeLayout(false);
this.popUpContextMenu.ResumeLayout(false);
this.tabSegmentsLogs.ResumeLayout(false);
this.tabSegments.ResumeLayout(false);
this.tabLog.ResumeLayout(false);
this.logContextMenu.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.SplitContainer splitContainer2;
private System.Windows.Forms.ListView lvwDownloads;
private System.Windows.Forms.ColumnHeader columnFile;
private System.Windows.Forms.ColumnHeader columnSize;
private System.Windows.Forms.ColumnHeader columnCompleted;
private System.Windows.Forms.ColumnHeader columnProgress;
private System.Windows.Forms.ColumnHeader columnLeft;
private System.Windows.Forms.ColumnHeader columnRate;
private System.Windows.Forms.ColumnHeader columnAdded;
private System.Windows.Forms.ColumnHeader columnState;
private System.Windows.Forms.ColumnHeader columnURL;
private System.Windows.Forms.TabControl tabSegmentsLogs;
private System.Windows.Forms.TabPage tabSegments;
private System.Windows.Forms.ListView lvwSegments;
private System.Windows.Forms.ColumnHeader columnCurrentTry;
private System.Windows.Forms.ColumnHeader columnSegProgress;
private System.Windows.Forms.ColumnHeader columnSegCompleted;
private System.Windows.Forms.ColumnHeader columnSegSize;
private System.Windows.Forms.ColumnHeader columnStartPosition;
private System.Windows.Forms.ColumnHeader columnEndPosition;
private System.Windows.Forms.ColumnHeader columnSegRate;
private System.Windows.Forms.ColumnHeader columnSegLeft;
private System.Windows.Forms.ColumnHeader columnSegState;
private System.Windows.Forms.ColumnHeader columnCurrURL;
private System.Windows.Forms.TabPage tabLog;
private System.Windows.Forms.RichTextBox richLog;
private System.Windows.Forms.ContextMenuStrip logContextMenu;
private System.Windows.Forms.ToolStripMenuItem clearLogToolStripMenuItem;
private System.Windows.Forms.ContextMenuStrip popUpContextMenu;
private System.Windows.Forms.ToolStripMenuItem newDownloadToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripMenuItem startToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem pauseToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
private System.Windows.Forms.ToolStripMenuItem openFileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyURLToClipboardToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem showInExplorerToolStripMenuItem;
private System.Windows.Forms.ColumnHeader columnResume;
private MyDownloader.App.Controls.BlockedProgressBar blockedProgressBar1;
}
}
MyDownloader.App/UI/DownloadList.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core;
using System.Collections;
using System.Diagnostics;
using System.IO;
using MyDownloader.Core.Common;
using MyDownloader.Extension.Video;
using System.Web;
using MyDownloader.Extension.AutoDownloads;
using MyDownloader.App.Controls;
using MyDownloader.Core.UI;
using MyDownloader.Extension.WindowsIntegration.ClipboardMonitor;
namespace MyDownloader.App.UI
{
public partial class DownloadList : UserControl, IClipboardDataHandler
{
delegate void ActionDownloader(Downloader d, ListViewItem item);
Hashtable mapItemToDownload = new Hashtable();
Hashtable mapDownloadToItem = new Hashtable();
ListViewItem lastSelection = null;
AutoDownloadsExtension scheduler;
ClipboardMonitor clipMonitor;
public DownloadList()
{
InitializeComponent();
lvwDownloads.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(lvwDownloads, true, null);
lvwSegments.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(lvwSegments, true, null);
DownloadManager.Instance.DownloadAdded += new EventHandler<DownloaderEventArgs>(Instance_DownloadAdded);
DownloadManager.Instance.DownloadRemoved += new EventHandler<DownloaderEventArgs>(Instance_DownloadRemoved);
DownloadManager.Instance.DownloadEnded += new EventHandler<DownloaderEventArgs>(Instance_DownloadEnded);
for (int i = 0; i < DownloadManager.Instance.Downloads.Count; i++)
{
AddDownload(DownloadManager.Instance.Downloads[i]);
}
lvwDownloads.SmallImageList = FileTypeImageList.GetSharedInstance();
}
private void DownloadList_Load(object sender, EventArgs e)
{
DownloadManager.Instance.BeginAddBatchDownloads += new EventHandler(Instance_BeginAddBatchDownloads);
DownloadManager.Instance.EndAddBatchDownloads += new EventHandler(Instance_EndAddBatchDownloads);
DownloadManager.Instance.DownloadRemoved+=new EventHandler<DownloaderEventArgs>(Instance_DownloadRemoved);
scheduler = (AutoDownloadsExtension)App.Instance.GetExtensionByType(typeof(AutoDownloadsExtension));
clipMonitor = new ClipboardMonitor(this, this.Handle);
this.Disposed += delegate(object snd, EventArgs ea)
{
clipMonitor.Dispose();
};
}
void Instance_EndAddBatchDownloads(object sender, EventArgs e)
{
this.BeginInvoke((MethodInvoker)lvwDownloads.EndUpdate);
}
void Instance_BeginAddBatchDownloads(object sender, EventArgs e)
{
this.BeginInvoke((MethodInvoker)lvwDownloads.BeginUpdate);
}
public void ImportFromTextFile()
{
using (ImportFromFileForm importFile = new ImportFromFileForm())
{
if (importFile.ShowDialog() == DialogResult.OK)
{
AddDownloadURLs(
importFile.URLs,
1,
importFile.DownloadPath,
0);
importFile.ApplySettings();
}
}
}
public void NewBatchDownload()
{
using (CreateBatchDownloadForm batchDownload = new CreateBatchDownloadForm())
{
if (batchDownload.ShowDialog() == DialogResult.OK)
{
AddDownloadURLs(
batchDownload.URLs,
batchDownload.Segments,
batchDownload.DownloadPath,
0);
batchDownload.ApplySettings();
}
}
}
string lastClipboardURL;
#region IClipboardDataHandler Members
protected override void WndProc(ref Message m)
{
if (clipMonitor == null || !clipMonitor.FilterMessage(ref m))
{
base.WndProc(ref m);
}
}
public void HandleClipboardData(IDataObject data)
{
NewDownloadFromClipboardData();
}
#endregion
public void NewDownloadFromData(string url)
{
VideoDownloadExtension ext = (VideoDownloadExtension)App.Instance.GetExtensionByType(typeof(VideoDownloadExtension));
if (ext.GetHandlerByURL(url) != null)
{
((VideoDownloadUIExtension)ext.UIExtension).ShowNewVideoDialog(url, false);
}
else
{
NewFileDownload(url, false);
}
}
public void NewDownloadFromClipboardData()
{
string url = ClipboardHelper.GetURLOnClipboard();
if (string.IsNullOrEmpty(url) || lastClipboardURL == url)
{
return;
}
lastClipboardURL = url;
VideoDownloadExtension ext = (VideoDownloadExtension)App.Instance.GetExtensionByType(typeof(VideoDownloadExtension));
if (ext.GetHandlerByURL(url) != null)
{
((VideoDownloadUIExtension)ext.UIExtension).ShowNewVideoDialog(null, false);
}
else
{
NewFileDownload(null, false);
}
}
public void NewVideoDownload()
{
VideoDownloadExtension ext = (VideoDownloadExtension)App.Instance.GetExtensionByType(typeof(VideoDownloadExtension));
((VideoDownloadUIExtension)ext.UIExtension).ShowNewVideoDialog(null, true);
}
public void NewFileDownload(string url, bool modal)
{
if (modal)
{
using (NewDownloadForm newDownload = new NewDownloadForm())
{
if (!String.IsNullOrEmpty(url))
{
ResourceLocation[] rl = new ResourceLocation[1];
rl[0]= ResourceLocation.FromURL(url);
newDownload.DownloadLocation =rl;
}
newDownload.ShowDialog();
}
}
else
{
NewDownloadForm newDownload = new NewDownloadForm();
if (!String.IsNullOrEmpty(url))
{
ResourceLocation[] rl = new ResourceLocation[1];
rl[0] = ResourceLocation.FromURL(url);
newDownload.DownloadLocation = rl;
}
newDownload.ShowInTaskbar = true;
newDownload.MinimizeBox = true;
newDownload.Show();
newDownload.Focus();
newDownload.TopMost = true;
}
}
public void StartScheduler(bool enabled)
{
scheduler.Active = enabled;
}
public bool SchedulerStarted()
{
return scheduler.Active;
}
public void StartSelections()
{
DownloadsAction(
delegate(Downloader d, ListViewItem item)
{
d.ScheduleState=DownloaderScheduleState.Waiting;
DownloadManager.Instance.StartNextDownload();
//d.Start();
}
);
}
public void Pause()
{
DownloadsAction(
delegate(Downloader d, ListViewItem item)
{
d.Pause();
}
);
}
public void PauseAll()
{
DownloadManager.Instance.PauseAll();
UpdateList();
}
public void RemoveSelections()
{
if (MessageBox.Show("Are you sure that you want to remove selected downloads?",
this.ParentForm.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
lvwDownloads.ItemSelectionChanged -= new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged);
DownloadManager.Instance.DownloadRemoved -= new EventHandler<DownloaderEventArgs>(Instance_DownloadRemoved);
DownloadsAction(
delegate(Downloader d, ListViewItem item)
{
lvwDownloads.Items.RemoveAt(item.Index);
DownloadManager.Instance.RemoveDownload(d);
System.IO.FileInfo fi = new FileInfo(d.LocalFile);
if (fi.Exists)
try
{
fi.Delete();
}
catch
{
MessageBox.Show("Unable to delete: " + fi.FullName);
}
}
);
}
finally
{
lvwDownloads.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged);
lvwDownloads_ItemSelectionChanged(null, null);
DownloadManager.Instance.DownloadRemoved += new EventHandler<DownloaderEventArgs>(Instance_DownloadRemoved);
}
}
}
public void SelectAll()
{
using (DownloadManager.Instance.LockDownloadList(false))
{
lvwDownloads.BeginUpdate();
try
{
lvwDownloads.ItemSelectionChanged -= new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged);
for (int i = 0; i < lvwDownloads.Items.Count; i++)
{
lvwDownloads.Items[i].Selected = true;
}
}
finally
{
lvwDownloads.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged);
lvwDownloads_ItemSelectionChanged(null, null);
lvwDownloads.EndUpdate();
}
}
}
public void RemoveCompleted()
{
lvwDownloads.BeginUpdate();
try
{
DownloadManager.Instance.ClearEnded();
UpdateList();
}
finally
{
lvwDownloads.EndUpdate();
}
}
public void AddDownloadURLs(
ResourceLocation arg,
int segments,
string path,
int nrOfSubfolders)
{
if (arg == null) return;
if (path == null)
{
path = PathHelper.GetWithBackslash(Core.Settings.Default.DownloadFolder);
}
else
{
path = PathHelper.GetWithBackslash(path);
}
try
{
DownloadManager.Instance.OnBeginAddBatchDownloads();
//foreach (ResourceLocation rl in args)
//{
Uri uri = new Uri(arg.URL);
string fileName = uri.Segments[uri.Segments.Length - 1];
fileName = HttpUtility.UrlDecode(fileName).Replace("/", "\\");
DownloadManager.Instance.Add(
arg,
null,
path + fileName,
segments,
false);
//}
}
finally
{
DownloadManager.Instance.OnEndAddBatchDownloads();
}
}
public void AddDownloadURLs(
ResourceLocation[] args,
int segments,
string path,
int nrOfSubfolders)
{
if (args == null) return;
if (path == null)
{
path = PathHelper.GetWithBackslash(Core.Settings.Default.DownloadFolder);
}
else
{
path = PathHelper.GetWithBackslash(path);
}
try
{
DownloadManager.Instance.OnBeginAddBatchDownloads();
foreach (ResourceLocation rl in args)
{
Uri uri = new Uri(rl.URL);
string fileName = uri.Segments[uri.Segments.Length - 1];
fileName = HttpUtility.UrlDecode(fileName).Replace("/", "\\");
DownloadManager.Instance.Add(
rl,
null,
path + fileName,
segments,
false);
}
}
finally
{
DownloadManager.Instance.OnEndAddBatchDownloads();
}
}
private void lvwDownloads_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
UpdateSegments();
UpdateUI();
}
public void LoadSettingsView()
{
lvwDownloads.GridLines = Settings.Default.ViewGrid;
lvwSegments.GridLines = Settings.Default.ViewGrid;
splitContainer2.Panel2Collapsed = !Settings.Default.ViewTransDetails;
}
public void UpdateUI()
{
bool isSelected = lvwDownloads.SelectedItems.Count > 0;
removeToolStripMenuItem.Enabled = isSelected;
startToolStripMenuItem.Enabled = isSelected;
pauseToolStripMenuItem.Enabled = isSelected;
isSelected = lvwDownloads.SelectedItems.Count == 1;
copyURLToClipboardToolStripMenuItem.Enabled = isSelected;
showInExplorerToolStripMenuItem.Enabled = isSelected;
openFileToolStripMenuItem.Enabled = isSelected && SelectedDownloaders[0].State == DownloaderState.Ended;
OnSelectionChange();
}
public event EventHandler SelectionChange;
protected virtual void OnSelectionChange()
{
if (SelectionChange != null)
{
SelectionChange(this, EventArgs.Empty);
}
}
private void copyURLToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
{
Clipboard.SetText(SelectedDownloaders[0].ResourceLocation.URL);
}
private void showInExplorerToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start("explorer.exe", String.Format("/select,{0}", SelectedDownloaders[0].LocalFile));
}
private void openFileToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
Process.Start(SelectedDownloaders[0].LocalFile);
}
catch (Exception)
{
}
}
public int SelectedCount
{
get
{
return lvwDownloads.SelectedItems.Count;
}
}
public Downloader[] SelectedDownloaders
{
get
{
if (lvwDownloads.SelectedItems.Count > 0)
{
Downloader[] downloaders = new Downloader[lvwDownloads.SelectedItems.Count];
for (int i = 0; i < downloaders.Length; i++)
{
downloaders[i] = mapItemToDownload[lvwDownloads.SelectedItems[i]] as Downloader;
}
return downloaders;
}
return null;
}
}
void Instance_DownloadRemoved(object sender, DownloaderEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate()
{
ListViewItem item = mapDownloadToItem[e.Downloader] as ListViewItem;
if (item != null)
{
if (item.Selected)
{
lastSelection = null;
lvwSegments.Items.Clear();
//lvwDownloads.SelectedItems.Clear();
}
mapDownloadToItem[e.Downloader] = null;
mapItemToDownload[item] = null;
item.Remove();
}
}
);
}
void Instance_DownloadAdded(object sender, DownloaderEventArgs e)
{
if (IsHandleCreated)
{
this.BeginInvoke((MethodInvoker)delegate() { AddDownload(e.Downloader); });
}
else
{
AddDownload(e.Downloader);
}
}
private void AddDownload(Downloader d)
{
d.RestartingSegment += new EventHandler<SegmentEventArgs>(download_RestartingSegment);
d.SegmentStoped += new EventHandler<SegmentEventArgs>(download_SegmentEnded);
d.SegmentFailed += new EventHandler<SegmentEventArgs>(download_SegmentFailed);
d.SegmentStarted += new EventHandler<SegmentEventArgs>(download_SegmentStarted);
d.InfoReceived += new EventHandler(download_InfoReceived);
d.SegmentStarting += new EventHandler<SegmentEventArgs>(Downloader_SegmentStarting);
string ext = Path.GetExtension(d.LocalFile);
ListViewItem item = new ListViewItem();
item.ImageIndex = FileTypeImageList.GetImageIndexByExtention(ext);
item.Text = Path.GetFileName(d.LocalFile);
// size
item.SubItems.Add(ByteFormatter.ToString(d.FileSize));
// completed
item.SubItems.Add(ByteFormatter.ToString(d.Transfered));
// progress
item.SubItems.Add(String.Format("{0:0.##}%", d.Progress));
// left
item.SubItems.Add(TimeSpanFormatter.ToString(d.Left));
// rate
item.SubItems.Add("0");
// added
item.SubItems.Add(d.CreatedDateTime.ToShortDateString() + " " + d.CreatedDateTime.ToShortTimeString());
// state
item.SubItems.Add(d.State.ToString());
// resume
item.SubItems.Add(GetResumeStr(d));
// url
item.SubItems.Add(d.ResourceLocation.URL);
mapDownloadToItem[d] = item;
mapItemToDownload[item] = d;
lvwDownloads.Items.Add(item);
}
private static string GetResumeStr(Downloader d)
{
return (d.RemoteFileInfo != null && d.RemoteFileInfo.AcceptRanges ? "Yes" : "No");
}
public void UpdateList()
{
lvwDownloads.BeginUpdate();
for (int i = 0; i < lvwDownloads.Items.Count; i++)
{
ListViewItem item = lvwDownloads.Items[i];
if (item == null) return;
Downloader d = mapItemToDownload[item] as Downloader;
if (d == null) return;
DownloaderState state;
if (item.Tag == null) state = DownloaderState.Working;
else state = (DownloaderState)item.Tag;
if (state != d.State ||
state == DownloaderState.Working ||
state == DownloaderState.WaitingForReconnect)
{
item.SubItems[0].Text = d.FileName;
item.SubItems[1].Text = ByteFormatter.ToString(d.FileSize);
item.SubItems[2].Text = ByteFormatter.ToString(d.Transfered);
item.SubItems[3].Text = String.Format("{0:0.##}%", d.Progress);
item.SubItems[4].Text = TimeSpanFormatter.ToString(d.Left);
item.SubItems[5].Text = String.Format("{0:0.##}", d.Rate / 1024.0);
if (d.LastError != null)
{
item.SubItems[7].Text = d.ScheduleState.ToString() + ", " + d.LastError.Message;
}
else
{
if (String.IsNullOrEmpty(d.StatusMessage))
{
item.SubItems[7].Text = d.ScheduleState.ToString();
}
else
{
item.SubItems[7].Text = d.ScheduleState.ToString() + ", " + d.StatusMessage;
}
}
item.SubItems[8].Text = GetResumeStr(d);
item.SubItems[9].Text = d.ResourceLocation.URL;
item.Tag = d.State;
}
}
UpdateSegments();
lvwDownloads.EndUpdate();
}
private void UpdateSegments()
{
try
{
lvwSegments.BeginUpdate();
if (lvwDownloads.SelectedItems.Count == 1)
{
ListViewItem newSelection = lvwDownloads.SelectedItems[0];
Downloader d = mapItemToDownload[newSelection] as Downloader;
if (lastSelection == newSelection)
{
if (d.Segments.Count == lvwSegments.Items.Count)
{
UpdateSegmentsWithoutInsert(d);
}
else
{
UpdateSegmentsInserting(d, newSelection);
}
}
else
{
UpdateSegmentsInserting(d, newSelection);
}
}
else
{
lastSelection = null;
blockedProgressBar1.BlockList.Clear();
blockedProgressBar1.Refresh();
lvwSegments.Items.Clear();
}
}
finally
{
lvwSegments.EndUpdate();
}
}
private void DownloadsAction(ActionDownloader action)
{
if (lvwDownloads.SelectedItems.Count > 0)
{
try
{
lvwDownloads.BeginUpdate();
lvwDownloads.ItemSelectionChanged -= new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged);
for (int i = lvwDownloads.SelectedItems.Count - 1; i >= 0; i--)
{
ListViewItem item = lvwDownloads.SelectedItems[i];
action((Downloader)mapItemToDownload[item], item);
}
lvwDownloads.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged);
lvwDownloads_ItemSelectionChanged(null, null);
}
finally
{
lvwDownloads.EndUpdate();
UpdateSegments();
}
}
}
private void UpdateSegmentsWithoutInsert(Downloader d)
{
for (int i = 0; i < d.Segments.Count; i++)
{
lvwSegments.Items[i].SubItems[0].Text = d.Segments[i].CurrentTry.ToString();
lvwSegments.Items[i].SubItems[1].Text = String.Format("{0:0.##}%", d.Segments[i].Progress);
lvwSegments.Items[i].SubItems[2].Text = ByteFormatter.ToString(d.Segments[i].Transfered);
lvwSegments.Items[i].SubItems[3].Text = ByteFormatter.ToString(d.Segments[i].TotalToTransfer);
lvwSegments.Items[i].SubItems[4].Text = ByteFormatter.ToString(d.Segments[i].InitialStartPosition);
lvwSegments.Items[i].SubItems[5].Text = ByteFormatter.ToString(d.Segments[i].EndPosition);
lvwSegments.Items[i].SubItems[6].Text = String.Format("{0:0.##}", d.Segments[i].Rate / 1024.0);
lvwSegments.Items[i].SubItems[7].Text = TimeSpanFormatter.ToString(d.Segments[i].Left);
if (d.Segments[i].LastError != null)
{
lvwSegments.Items[i].SubItems[8].Text = d.Segments[i].State.ToString() + ", " + d.Segments[i].LastError.Message;
}
else
{
lvwSegments.Items[i].SubItems[8].Text = d.Segments[i].State.ToString();
}
lvwSegments.Items[i].SubItems[9].Text = d.Segments[i].CurrentURL;
this.blockedProgressBar1.BlockList[i].BlockSize = d.Segments[i].TotalToTransfer;
this.blockedProgressBar1.BlockList[i].PercentProgress = (float)d.Segments[i].Progress;
}
this.blockedProgressBar1.Refresh();
}
private void UpdateSegmentsInserting(Downloader d, ListViewItem newSelection)
{
lastSelection = newSelection;
lvwSegments.Items.Clear();
List<Block> blocks = new List<Block>();
for (int i = 0; i < d.Segments.Count; i++)
{
ListViewItem item = new ListViewItem();
item.Text = d.Segments[i].CurrentTry.ToString();
item.SubItems.Add(String.Format("{0:0.##}%", d.Segments[i].Progress));
item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].Transfered));
item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].TotalToTransfer));
item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].InitialStartPosition));
item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].EndPosition));
item.SubItems.Add(String.Format("{0:0.##}", d.Segments[i].Rate / 1024.0));
item.SubItems.Add(TimeSpanFormatter.ToString(d.Segments[i].Left));
item.SubItems.Add(d.Segments[i].State.ToString());
item.SubItems.Add(d.Segments[i].CurrentURL);
lvwSegments.Items.Add(item);
blocks.Add(new Block(d.Segments[i].TotalToTransfer, (float)d.Segments[i].Progress));
}
this.blockedProgressBar1.BlockList = blocks;
}
void download_InfoReceived(object sender, EventArgs e)
{
Downloader d = (Downloader)sender;
Log(
d,
String.Format(
"Connected to: {2}. File size = {0}, Resume = {1}",
ByteFormatter.ToString(d.FileSize),
d.RemoteFileInfo.AcceptRanges,
d.ResourceLocation.URL),
LogMode.Information);
}
void Downloader_SegmentStarting(object sender, SegmentEventArgs e)
{
Log(
e.Downloader,
String.Format(
"Starting segment for {3}, start position = {0}, end position {1}, segment size = {2}",
ByteFormatter.ToString(e.Segment.InitialStartPosition),
ByteFormatter.ToString(e.Segment.EndPosition),
ByteFormatter.ToString(e.Segment.TotalToTransfer),
e.Downloader.ResourceLocation.URL),
LogMode.Information);
}
void download_SegmentStarted(object sender, SegmentEventArgs e)
{
Log(
e.Downloader,
String.Format(
"Started segment for {3}, start position = {0}, end position {1}, segment size = {2}",
ByteFormatter.ToString(e.Segment.InitialStartPosition),
ByteFormatter.ToString(e.Segment.EndPosition),
ByteFormatter.ToString(e.Segment.TotalToTransfer),
e.Downloader.ResourceLocation.URL),
LogMode.Information);
}
void download_SegmentFailed(object sender, SegmentEventArgs e)
{
Log(
e.Downloader,
String.Format(
"Download segment ({0}) failed for {2}, reason = {1}",
e.Segment.Index,
e.Segment.LastError.Message,
e.Downloader.ResourceLocation.URL),
LogMode.Error);
}
void download_SegmentEnded(object sender, SegmentEventArgs e)
{
Log(
e.Downloader,
String.Format(
"Download segment ({0}) ended for {1}",
e.Segment.Index,
e.Downloader.ResourceLocation.URL),
LogMode.Information);
}
void download_RestartingSegment(object sender, SegmentEventArgs e)
{
Log(
e.Downloader,
String.Format(
"Download segment ({0}) is restarting for {1}",
e.Segment.Index,
e.Downloader.ResourceLocation.URL),
LogMode.Information);
}
void Instance_DownloadEnded(object sender, DownloaderEventArgs e)
{
Log(
e.Downloader,
String.Format(
"Download ended {0}",
e.Downloader.ResourceLocation.URL),
LogMode.Information);
}
enum LogMode
{
Error,
Information
}
void Log(Downloader downloader, string msg, LogMode m)
{
try
{
this.BeginInvoke(
(MethodInvoker)
delegate()
{
int len = richLog.Text.Length;
if (len > 0)
{
richLog.SelectionStart = len;
}
if (m == LogMode.Error)
{
richLog.SelectionColor = Color.Red;
}
else
{
richLog.SelectionColor = Color.Blue;
}
richLog.AppendText(DateTime.Now + " - " + msg + Environment.NewLine);
}
);
}
catch { }
}
private void clearLogToolStripMenuItem_Click(object sender, EventArgs e)
{
richLog.Clear();
}
private void newDownloadToolStripMenuItem_Click(object sender, EventArgs e)
{
NewFileDownload(null, true);
}
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
StartSelections();
}
private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
{
Pause();
}
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
RemoveSelections();
}
private void SwapElements(int idx)
{
ListViewItem it1 = lvwDownloads.Items[idx];
ListViewItem it2 = lvwDownloads.Items[idx - 1];
lvwDownloads.Items.RemoveAt(idx);
lvwDownloads.Items.RemoveAt(idx - 1);
lvwDownloads.Items.Insert(idx - 1, it1);
lvwDownloads.Items.Insert(idx, it2);
DownloadManager.Instance.SwapDownloads(idx, true);
}
public void MoveSelectionsDown()
{
int selCount = lvwDownloads.SelectedItems.Count;
if (selCount > 0)
{
try
{
lvwDownloads.BeginUpdate();
ListViewItem lvi = null;
using (DownloadManager.Instance.LockDownloadList(true))
{
for (int i = selCount - 1; i >= 0; i--)
{
lvi = lvwDownloads.SelectedItems[i];
if (lvi.Index < lvwDownloads.Items.Count - 1
&& !lvwDownloads.Items[lvi.Index + 1].Selected)
{
SwapElements(lvi.Index + 1);
}
}
}
lvwDownloads.SelectedItems[selCount - 1].EnsureVisible();
}
finally
{
lvwDownloads.EndUpdate();
}
}
}
public void MoveSelectionsUp()
{
int selCount = lvwDownloads.SelectedItems.Count;
if (selCount > 0)
{
try
{
lvwDownloads.BeginUpdate();
ListViewItem lvi = null;
using (DownloadManager.Instance.LockDownloadList(true))
{
for (int i = 0; i < selCount; i++)
{
lvi = lvwDownloads.SelectedItems[i];
if (lvi.Index > 0
&& !lvwDownloads.Items[lvi.Index - 1].Selected)
{
SwapElements(lvi.Index);
}
}
}
lvwDownloads.SelectedItems[0].EnsureVisible();
}
finally
{
lvwDownloads.EndUpdate();
}
}
}
public bool ClipboardMonitorEnabled
{
set
{
if (clipMonitor != null)
{
clipMonitor.Enabled = value;
}
}
get
{
if (clipMonitor != null)
{
return clipMonitor.Enabled;
}
return false;
}
}
private void popUpContextMenu_Opening(object sender, CancelEventArgs e)
{
UpdateUI();
}
private void lvwDownloads_DoubleClick(object sender, EventArgs e)
{
UpdateUI();
openFileToolStripMenuItem_Click(sender, e);
}
}
}
MyDownloader.App/UI/DownloadList.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="popUpContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>528, 54</value>
</metadata>
<metadata name="logContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>396, 54</value>
</metadata>
</root>
MyDownloader.App/UI/FileTypeImageList.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace MyDownloader.App.UI
{
public class FileTypeImageList
{
private const string OpenFolderKey = "OpenFolderKey";
private const string CloseFolderKey = "OpenFolderKey";
private static ImageList instance;
public static ImageList GetSharedInstance()
{
if (instance == null)
{
instance = new ImageList();
instance.TransparentColor = Color.Black;
instance.TransparentColor = Color.Transparent;
instance.ColorDepth = ColorDepth.Depth32Bit;
instance.ImageSize = new Size(16, 16);
}
return instance;
}
public static int GetImageIndexByExtention(string ext)
{
GetSharedInstance();
ext = ext.ToLower();
if (!instance.Images.ContainsKey(ext))
{
//Icon iconForFile = IconExtractor.Extract(ext);
Icon iconForFile = IconReader.GetFileIconByExt(ext, IconReader.EnumIconSize.Small, false);
instance.Images.Add(ext, iconForFile);
}
return instance.Images.IndexOfKey(ext);
}
public static int GetImageIndexFromFolder(bool open)
{
string key;
GetSharedInstance();
if (open)
{
key = OpenFolderKey;
}
else
{
key = CloseFolderKey;
}
if (!instance.Images.ContainsKey(key))
{
Icon iconForFile = IconReader.GetFolderIcon(
IconReader.EnumIconSize.Small,
(open ? IconReader.EnumFolderType.Open : IconReader.EnumFolderType.Closed));
instance.Images.Add(key, iconForFile);
}
return instance.Images.IndexOfKey(key);
}
}
}
MyDownloader.App/UI/IconReader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.App.UI
{
public class IconReader
{
///
/// used to get/return information about a file
/// in SHGetFileInfo call
///
[System.FlagsAttribute()]
private enum EnumFileInfoFlags : uint
{
/// get large icon
LARGEICON = 0x000000000,
/// get small icon
SMALLICON = 0x000000001,
/// get open icon
OPENICON = 0x000000002,
/// get shell size icon
SHELLICONSIZE = 0x000000004,
/// pszPath is a pidl
PIDL = 0x000000008,
/// use passed dwFileAttribute
USEFILEATTRIBUTES = 0x000000010,
/// apply the appropriate overlays
ADDOVERLAYS = 0x000000020,
/// get the index of the overlay
OVERLAYINDEX = 0x000000040,
/// get icon
ICON = 0x000000100,
/// get display name
DISPLAYNAME = 0x000000200,
/// get type name
TYPENAME = 0x000000400,
/// get attributes
ATTRIBUTES = 0x000000800,
/// get icon location
ICONLOCATION = 0x000001000,
/// return exe type
EXETYPE = 0x000002000,
/// get system icon index
SYSICONINDEX = 0x000004000,
/// put a link overlay on icon
LINKOVERLAY = 0x000008000,
/// show icon in selected state
SELECTED = 0x000010000,
/// get only specified attributes
ATTR_SPECIFIED = 0x000020000
}
///
/// maxumum length of path
///
private const int conMAX_PATH = 260;
///
/// looking for folder
///
private const uint conFILE_ATTRIBUTE_DIRECTORY = 0x00000010;
///
/// looking for file
///
private const uint conFILE_ATTRIBUTE_NORMAL = 0x00000080;
///
/// size of the icon
///
public enum EnumIconSize
{
/// 32x32
Large = 0,
/// 16x16
Small = 1
}
///
/// state of the folder
///
public enum EnumFolderType
{
/// open folder
Open = 0,
/// closed folder
Closed = 1
}
///
/// hold file/icon information
/// see platformSDK SHFILEINFO
///
///
/// be sure to call DestroyIcon [hIcon] when done
///
[System.Runtime.InteropServices.StructLayout(
System.Runtime.InteropServices.LayoutKind.Sequential)]
private struct ShellFileInfo
{
public const int conNameSize = 80;
public System.IntPtr hIcon; // note to call DestroyIcon
public int iIndex;
public uint dwAttributes;
[System.Runtime.InteropServices.MarshalAs(
System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = conMAX_PATH)]
public string szDisplayName;
[System.Runtime.InteropServices.MarshalAs(
System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = conNameSize)]
public string szTypeName;
};
///
/// used to free a windows icon handle
///
/// "hIcon">icon handle.
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern int DestroyIcon(System.IntPtr hIcon);
///
/// gets file information
/// see platformSDK
///
[System.Runtime.InteropServices.DllImport("Shell32.dll")]
private static extern System.IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref ShellFileInfo psfi,
uint cbFileInfo,
uint uFlags
);
public static System.Drawing.Icon GetFileIcon(string filePath,
EnumIconSize size, bool addLinkOverlay)
{
EnumFileInfoFlags flags =
EnumFileInfoFlags.ICON | EnumFileInfoFlags.USEFILEATTRIBUTES;
// add link overlay if requested
if (addLinkOverlay)
{
flags |= EnumFileInfoFlags.LINKOVERLAY;
}
// set size
if (size == EnumIconSize.Small)
{
flags |= EnumFileInfoFlags.SMALLICON;
}
else
{
flags |= EnumFileInfoFlags.LARGEICON;
}
ShellFileInfo shellFileInfo = new ShellFileInfo();
SHGetFileInfo(
filePath,
conFILE_ATTRIBUTE_NORMAL,
ref shellFileInfo,
(uint)System.Runtime.InteropServices.Marshal.SizeOf(shellFileInfo),
(uint)flags);
// deep copy
System.Drawing.Icon icon =
(System.Drawing.Icon)System.Drawing.Icon.FromHandle(shellFileInfo.hIcon).Clone();
// release handle
DestroyIcon(shellFileInfo.hIcon);
return icon;
}
///
/// lookup and return an icon from windows shell
///
/// "name">path to the file
/// "size">large or small
/// "linkOverlay">true to include the overlay link iconlet
/// requested icon
public static System.Drawing.Icon GetFileIconByExt(
string fileExt,
EnumIconSize size,
bool addLinkOverlay)
{
string tempFile = Path.GetTempPath() + Guid.NewGuid().ToString("N") + fileExt;
try
{
File.WriteAllBytes(tempFile, new byte[1] { 0 });
return GetFileIcon(tempFile, size, addLinkOverlay);
}
finally
{
try
{
File.Delete(tempFile);
}
catch (Exception)
{
}
}
}
///
/// lookup and return an icon from windows shell
///
/// "size">large or small
/// "folderType">open or closed
/// requested icon
public static System.Drawing.Icon GetFolderIcon(
EnumIconSize size,
EnumFolderType folderType)
{
return GetFolderIcon(null, size, folderType);
}
///
/// lookup and return an icon from windows shell
///
/// "folderPath">path to folder
/// "size">large or small
/// "folderType">open or closed
/// requested icon
public static System.Drawing.Icon GetFolderIcon(
string folderPath,
EnumIconSize size,
EnumFolderType folderType)
{
EnumFileInfoFlags flags =
EnumFileInfoFlags.ICON | EnumFileInfoFlags.USEFILEATTRIBUTES;
if (folderType == EnumFolderType.Open)
{
flags |= EnumFileInfoFlags.OPENICON;
}
if (EnumIconSize.Small == size)
{
flags |= EnumFileInfoFlags.SMALLICON;
}
else
{
flags |= EnumFileInfoFlags.LARGEICON;
}
ShellFileInfo shellFileInfo = new ShellFileInfo();
SHGetFileInfo(
folderPath,
conFILE_ATTRIBUTE_DIRECTORY,
ref shellFileInfo,
(uint)System.Runtime.InteropServices.Marshal.SizeOf(shellFileInfo),
(uint)flags);
// deep copy
System.Drawing.Icon icon =
(System.Drawing.Icon)System.Drawing.Icon.FromHandle(shellFileInfo.hIcon).Clone();
// release handle
DestroyIcon(shellFileInfo.hIcon);
return icon;
}
}
}
MyDownloader.App/UI/ImportFromFileForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
namespace MyDownloader.App.UI
{
partial class ImportFromFileForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnSelFile = new System.Windows.Forms.Button();
this.txtFileName = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.rdoTextFile = new System.Windows.Forms.RadioButton();
this.rdoHTML = new System.Windows.Forms.RadioButton();
this.btnPreview = new System.Windows.Forms.Button();
this.location1 = new MyDownloader.App.UI.Location();
this.downloadFolder1 = new MyDownloader.Core.UI.DownloadFolder();
this.scheduledDownloadEnabler1 = new MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnSelFile
//
this.btnSelFile.Location = new System.Drawing.Point(429, 65);
this.btnSelFile.Name = "btnSelFile";
this.btnSelFile.Size = new System.Drawing.Size(26, 23);
this.btnSelFile.TabIndex = 4;
this.btnSelFile.Text = "...";
this.btnSelFile.UseVisualStyleBackColor = true;
this.btnSelFile.Click += new System.EventHandler(this.btnSelFile_Click);
//
// txtFileName
//
this.txtFileName.Location = new System.Drawing.Point(5, 68);
this.txtFileName.Name = "txtFileName";
this.txtFileName.Size = new System.Drawing.Size(422, 20);
this.txtFileName.TabIndex = 3;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(5, 51);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(69, 13);
this.label1.TabIndex = 2;
this.label1.Text = "File to import:";
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(383, 408);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 9;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// btnOK
//
this.btnOK.AllowDrop = true;
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(302, 408);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 8;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
this.openFileDialog1.Filter = "HTML Files (*.html;*.htm)|*.html;*.htm|Text Files (*.txt)|*.txt|All File (*.*)|*." +
"*";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.rdoTextFile);
this.groupBox1.Controls.Add(this.rdoHTML);
this.groupBox1.Location = new System.Drawing.Point(8, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(449, 45);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Import from";
//
// rdoTextFile
//
this.rdoTextFile.AutoSize = true;
this.rdoTextFile.Checked = true;
this.rdoTextFile.Location = new System.Drawing.Point(6, 19);
this.rdoTextFile.Name = "rdoTextFile";
this.rdoTextFile.Size = new System.Drawing.Size(65, 17);
this.rdoTextFile.TabIndex = 0;
this.rdoTextFile.TabStop = true;
this.rdoTextFile.Text = "Text File";
this.rdoTextFile.UseVisualStyleBackColor = true;
this.rdoTextFile.CheckedChanged += new System.EventHandler(this.rdoDownloadMode_Changed);
//
// rdoHTML
//
this.rdoHTML.AutoSize = true;
this.rdoHTML.Location = new System.Drawing.Point(172, 19);
this.rdoHTML.Name = "rdoHTML";
this.rdoHTML.Size = new System.Drawing.Size(74, 17);
this.rdoHTML.TabIndex = 1;
this.rdoHTML.Text = "HTML File";
this.rdoHTML.UseVisualStyleBackColor = true;
this.rdoHTML.CheckedChanged += new System.EventHandler(this.rdoDownloadMode_Changed);
//
// btnPreview
//
this.btnPreview.Location = new System.Drawing.Point(8, 408);
this.btnPreview.Name = "btnPreview";
this.btnPreview.Size = new System.Drawing.Size(110, 23);
this.btnPreview.TabIndex = 7;
this.btnPreview.Text = "Preview URLs";
this.btnPreview.UseVisualStyleBackColor = true;
this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click);
//
// location1
//
this.location1.Enabled = false;
this.location1.Location = new System.Drawing.Point(5, 142);
this.location1.Name = "location1";
this.location1.Size = new System.Drawing.Size(449, 89);
this.location1.TabIndex = 1;
this.location1.UrlLabelTitle = "Base URL:";
//
// downloadFolder1
//
this.downloadFolder1.LabelText = "Save to:";
this.downloadFolder1.Location = new System.Drawing.Point(5, 94);
this.downloadFolder1.Name = "downloadFolder1";
this.downloadFolder1.Size = new System.Drawing.Size(450, 42);
this.downloadFolder1.TabIndex = 5;
//
// scheduledDownloadEnabler1
//
this.scheduledDownloadEnabler1.Location = new System.Drawing.Point(5, 237);
this.scheduledDownloadEnabler1.Name = "scheduledDownloadEnabler1";
this.scheduledDownloadEnabler1.Size = new System.Drawing.Size(450, 164);
this.scheduledDownloadEnabler1.TabIndex = 6;
//
// ImportFromFileForm
//
this.AcceptButton = this.btnOK;
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(463, 437);
this.Controls.Add(this.location1);
this.Controls.Add(this.btnPreview);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.scheduledDownloadEnabler1);
this.Controls.Add(this.downloadFolder1);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.Controls.Add(this.btnSelFile);
this.Controls.Add(this.txtFileName);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ImportFromFileForm";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Import from file";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnSelFile;
private System.Windows.Forms.TextBox txtFileName;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private MyDownloader.Core.UI.DownloadFolder downloadFolder1;
private MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler scheduledDownloadEnabler1;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Button btnPreview;
private System.Windows.Forms.RadioButton rdoTextFile;
private System.Windows.Forms.RadioButton rdoHTML;
private Location location1;
}
}
MyDownloader.App/UI/ImportFromFileForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core;
using System.IO;
using System.Text.RegularExpressions;
using MyDownloader.Spider.Parsers.Html;
using MyDownloader.Core.UI;
namespace MyDownloader.App.UI
{
public partial class ImportFromFileForm : Form
{
public ImportFromFileForm()
{
InitializeComponent();
}
public string DownloadPath
{
get
{
return downloadFolder1.Folder;
}
}
public ResourceLocation[] URLs
{
get
{
List<ResourceLocation> urls = new List<ResourceLocation>();
if (rdoTextFile.Checked)
{
FillListFromTextFile(urls);
}
else
{
FillListFromHtmlFile(urls);
}
return urls.ToArray();
}
}
private void FillListFromHtmlFile(List<ResourceLocation> urls)
{
using (Stream htmlStream = File.OpenRead(txtFileName.Text))
{
using (HtmlParser parser = new HtmlParser(htmlStream))
{
//TODO:fix for multiple file download???
IEnumerator<Uri> enumUri = parser.GetHrefs(this.location1.ResourceLocation[0].URL).GetEnumerator();
while (enumUri.MoveNext())
{
ResourceLocation newRl = location1.ResourceLocation[0];
newRl.URL = enumUri.Current.OriginalString;
urls.Add(newRl);
}
}
}
}
private void FillListFromTextFile(List<ResourceLocation> urls)
{
string[] lines = File.ReadAllLines(txtFileName.Text);
for (int i = 0; i < lines.Length; i++)
{
string url = lines[i].Trim();
if (!String.IsNullOrEmpty(url) && ResourceLocation.IsURL(url))
{
urls.Add(ResourceLocation.FromURL(url));
}
}
}
private void btnSelFile_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
txtFileName.Text = openFileDialog1.FileName;
}
}
public void ApplySettings()
{
scheduledDownloadEnabler1.ApplySettings();
}
/*private void CreateBatchDownloadForm_DragEnter(object sender, DragEventArgs e)
{
if (!string.IsNullOrEmpty(downloadFolder1.Folder))
{
if ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
{
object data = ((IDataObject)e.Data).GetData("HTML Format", true);
if (data != null)
{
e.Effect = DragDropEffects.Copy;
}
}
}
}
private string GetBaseFolder(string url)
{
Uri uri = new Uri(url);
return string.Format("{0}://{1}{2}", uri.Scheme, uri.Host, string.Join("", uri.Segments, 0, uri.Segments.Length - 1));
}
private void CreateBatchDownloadForm_DragDrop(object sender, DragEventArgs e)
{
//numFrom.Value = 0;
//numTo.Value = 0;
//location1.Clear();
string html = GetDroppedHtmlSnippet(e);
string url = GetDroppedHtmlUrl(e);
string baseuri = GetBaseFolder(url);
List<string> links = RetrieveLinks(html, url);
dragdropURLs = ResourceLocation.FromURLArray(links.ToArray());
//PreviewURLs();
}
private string GetDroppedHtmlSnippet(DragEventArgs e)
{
string text = ((DataObject)e.Data).GetData(DataFormats.Html) as string;
if (string.IsNullOrEmpty(text))
{
text = ((DataObject)e.Data).GetData(DataFormats.Text) as string;
}
else
{
byte[] buffer = Encoding.Default.GetBytes(text);
text = Encoding.UTF8.GetString(buffer);
}
if (!string.IsNullOrEmpty(text))
{
int startPos = text.IndexOf("<!--StartFragment-->");
int endPos = text.IndexOf("<!--EndFragment-->");
if (startPos != -1)
{
startPos += 20;
}
if (startPos != -1 && endPos != -1)
{
text = text.Substring(startPos, endPos - startPos);
}
if (string.IsNullOrEmpty(text))
{
text = ((DataObject)e.Data).GetData(DataFormats.Rtf) as string;
if (string.IsNullOrEmpty(text))
{
text = ((DataObject)e.Data).GetData(DataFormats.Text) as string;
}
}
}
return text;
}
private string GetDroppedHtmlUrl(DragEventArgs e)
{
string text = ((DataObject)e.Data).GetData(DataFormats.Html) as string;
if (!string.IsNullOrEmpty(text))
{
int startPos = text.IndexOf("SourceURL:");
int endPos = text.IndexOf("\r\n", startPos);
if (startPos != -1)
{
startPos += 10;
}
if (startPos != -1 && endPos != -1)
{
text = text.Substring(startPos, endPos - startPos);
}
if (string.IsNullOrEmpty(text))
{
text = ((DataObject)e.Data).GetData(DataFormats.Rtf) as string;
if (string.IsNullOrEmpty(text))
{
text = ((DataObject)e.Data).GetData(DataFormats.Text) as string;
}
}
}
return text;
}
private List<string> RetrieveLinks(string html, string baseUrl)
{
List<string> tbl = new List<string>();
if (html == null || html.Length == 0)
return tbl;
for (Match m = RegExFindHref.Match(html); m.Success; m = m.NextMatch())
{
string href = m.Groups[1].ToString();// filter non-real relation urls:
if (href.StartsWith("mailto:") || href.StartsWith("javascript:") ||
href.EndsWith(".gif") || href.EndsWith(".jpg") || href.EndsWith(".png"))
{
continue;
}
href = ConvertToAbsoluteUrl(href, baseUrl);
if (href == null || href.Length == 0)
continue;
string linkText = m.Groups[2].ToString();
if (!tbl.Contains(href))
tbl.Add(href);
}
return tbl;
}
private string ConvertToAbsoluteUrl(string url, string baseUrl)
{
// we try to prevent the exception caused in the case the url is relative
// (no scheme info) just for speed
if (url.IndexOf(Uri.SchemeDelimiter) < 0 && baseUrl != null)
{
try
{
Uri baseUri = new Uri(baseUrl);
return (new Uri(baseUri, url).ToString());
}
catch
{
return null;
}
}
try
{
Uri uri = new Uri(url);
return uri.ToString();
}
catch (Exception)
{
if (baseUrl != null)
{
try
{
Uri baseUri = new Uri(baseUrl);
return (new Uri(baseUri, url).ToString());
}
catch (Exception)
{
return null;
}
}
else
{
return null;
}
}
}*/
private void rdoDownloadMode_Changed(object sender, EventArgs e)
{
location1.Enabled = rdoHTML.Checked;
}
private bool IsValid()
{
if (!File.Exists(txtFileName.Text))
{
MessageBox.Show("Invalid file name.",
AppManager.Instance.Application.MainForm.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return false;
}
return true;
}
private void btnPreview_Click(object sender, EventArgs e)
{
if (IsValid())
{
using (ImportFromFilePreviewForm preview = new ImportFromFilePreviewForm(this.URLs))
{
preview.ShowDialog();
}
}
}
private void btnOK_Click(object sender, EventArgs e)
{
if (! IsValid())
{
DialogResult = DialogResult.None;
return;
}
}
}
}
MyDownloader.App/UI/ImportFromFileForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>15, 25</value>
</metadata>
</root>
MyDownloader.App/UI/ImportFromFilePreviewForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
namespace MyDownloader.App.UI
{
partial class ImportFromFilePreviewForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.lslUrls = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// button1
//
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button1.Location = new System.Drawing.Point(473, 270);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Close";
this.button1.UseVisualStyleBackColor = true;
//
// lslUrls
//
this.lslUrls.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lslUrls.FormattingEnabled = true;
this.lslUrls.Location = new System.Drawing.Point(8, 12);
this.lslUrls.Name = "lslUrls";
this.lslUrls.Size = new System.Drawing.Size(540, 251);
this.lslUrls.TabIndex = 0;
//
// ImportFromFilePreviewForm
//
this.AcceptButton = this.button1;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.button1;
this.ClientSize = new System.Drawing.Size(555, 298);
this.Controls.Add(this.lslUrls);
this.Controls.Add(this.button1);
this.MinimizeBox = false;
this.Name = "ImportFromFilePreviewForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Import From File - Preview";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ListBox lslUrls;
}
}
MyDownloader.App/UI/ImportFromFilePreviewForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core;
namespace MyDownloader.App.UI
{
public partial class ImportFromFilePreviewForm : Form
{
public ImportFromFilePreviewForm(ResourceLocation[] locations)
{
InitializeComponent();
lslUrls.DataSource = locations;
}
}
}
MyDownloader.App/UI/ImportFromFilePreviewForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.App/UI/MainForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
using MyDownloader.Spider.UI;
namespace MyDownloader.App.UI
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.tmrRefresh = new System.Windows.Forms.Timer(this.components);
this.toolStripMain = new System.Windows.Forms.ToolStrip();
this.tsbMenu = new System.Windows.Forms.ToolStripButton();
this.toolNewDownload = new System.Windows.Forms.ToolStripButton();
this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.toolStart = new System.Windows.Forms.ToolStripButton();
this.toolStripScheduler = new System.Windows.Forms.ToolStripButton();
this.toolPause = new System.Windows.Forms.ToolStripButton();
this.toolPauseAll = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolRemove = new System.Windows.Forms.ToolStripButton();
this.toolRemoveCompleted = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.toolMoveSelectionsUp = new System.Windows.Forms.ToolStripButton();
this.toolMoveSelectionsDown = new System.Windows.Forms.ToolStripButton();
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.notifyIconContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.showHideToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.clipboardMonitoringToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator14 = new System.Windows.Forms.ToolStripSeparator();
this.newDownloadToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.newBatchDownloadToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
this.pauseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
this.optionsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.menuBarStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.newDownloadToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.newVideoDownloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.newBatchDownloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
this.importFromTextFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeCompletedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyURLToClipboardToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem();
this.segmentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolbarToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.gridToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.faTabStrip1 = new FarsiLibrary.Win.FATabStrip();
this.faTabStripItem1 = new FarsiLibrary.Win.FATabStripItem();
this.downloadList1 = new MyDownloader.App.UI.DownloadList();
this.faTabStripItem2 = new FarsiLibrary.Win.FATabStripItem();
this.webSpider1 = new MyDownloader.Spider.UI.WebSpider();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.cntxMenuDownLimit = new System.Windows.Forms.ContextMenuStrip(this.components);
this.setCustomToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.enableSpeedLimitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripLblRate = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripLblRateTxt = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripMain.SuspendLayout();
this.notifyIconContextMenu.SuspendLayout();
this.menuBarStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.faTabStrip1)).BeginInit();
this.faTabStrip1.SuspendLayout();
this.faTabStripItem1.SuspendLayout();
this.faTabStripItem2.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.cntxMenuDownLimit.SuspendLayout();
this.SuspendLayout();
//
// tmrRefresh
//
this.tmrRefresh.Enabled = true;
this.tmrRefresh.Interval = 1500;
this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick);
//
// toolStripMain
//
this.toolStripMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsbMenu,
this.toolNewDownload,
this.toolStripButton1,
this.toolStripSeparator1,
this.toolStart,
this.toolStripScheduler,
this.toolPause,
this.toolPauseAll,
this.toolStripSeparator2,
this.toolRemove,
this.toolRemoveCompleted,
this.toolStripSeparator3,
this.toolMoveSelectionsUp,
this.toolMoveSelectionsDown});
this.toolStripMain.Location = new System.Drawing.Point(0, 0);
this.toolStripMain.Name = "toolStripMain";
this.toolStripMain.Size = new System.Drawing.Size(541, 25);
this.toolStripMain.TabIndex = 1;
//
// tsbMenu
//
this.tsbMenu.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsbMenu.Image = ((System.Drawing.Image)(resources.GetObject("tsbMenu.Image")));
this.tsbMenu.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbMenu.Name = "tsbMenu";
this.tsbMenu.Size = new System.Drawing.Size(23, 22);
this.tsbMenu.Text = "Toggle menu bar";
this.tsbMenu.Click += new System.EventHandler(this.tsbMenu_Click);
//
// toolNewDownload
//
this.toolNewDownload.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolNewDownload.Image = ((System.Drawing.Image)(resources.GetObject("toolNewDownload.Image")));
this.toolNewDownload.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolNewDownload.Name = "toolNewDownload";
this.toolNewDownload.Size = new System.Drawing.Size(23, 22);
this.toolNewDownload.Text = "New Download";
this.toolNewDownload.Click += new System.EventHandler(this.toolNewDownload_Click);
//
// toolStripButton1
//
this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton1.Name = "toolStripButton1";
this.toolStripButton1.Size = new System.Drawing.Size(127, 22);
this.toolStripButton1.Text = "New Video Download";
this.toolStripButton1.ToolTipText = "New Video Download (from YouTube, GoogleVideo, Break...)";
this.toolStripButton1.Click += new System.EventHandler(this.newVideoDownloadToolStripMenuItem_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// toolStart
//
this.toolStart.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStart.Image = ((System.Drawing.Image)(resources.GetObject("toolStart.Image")));
this.toolStart.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStart.Name = "toolStart";
this.toolStart.Size = new System.Drawing.Size(23, 22);
this.toolStart.Text = "Start";
this.toolStart.Click += new System.EventHandler(this.toolStart_Click);
//
// toolStripScheduler
//
this.toolStripScheduler.CheckOnClick = true;
this.toolStripScheduler.Image = ((System.Drawing.Image)(resources.GetObject("toolStripScheduler.Image")));
this.toolStripScheduler.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripScheduler.Name = "toolStripScheduler";
this.toolStripScheduler.Size = new System.Drawing.Size(106, 22);
this.toolStripScheduler.Text = "Auto-Downloads";
this.toolStripScheduler.ToolTipText = "Toggle Auto-Downloads On/Off";
this.toolStripScheduler.Click += new System.EventHandler(this.toolStripScheduler_Click);
//
// toolPause
//
this.toolPause.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolPause.Image = ((System.Drawing.Image)(resources.GetObject("toolPause.Image")));
this.toolPause.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolPause.Name = "toolPause";
this.toolPause.Size = new System.Drawing.Size(23, 22);
this.toolPause.Text = "Pause";
this.toolPause.Click += new System.EventHandler(this.toolPause_Click);
//
// toolPauseAll
//
this.toolPauseAll.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolPauseAll.Image = ((System.Drawing.Image)(resources.GetObject("toolPauseAll.Image")));
this.toolPauseAll.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolPauseAll.Name = "toolPauseAll";
this.toolPauseAll.Size = new System.Drawing.Size(23, 22);
this.toolPauseAll.Text = "Pause All";
this.toolPauseAll.Click += new System.EventHandler(this.toolPauseAll_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
//
// toolRemove
//
this.toolRemove.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolRemove.Image = ((System.Drawing.Image)(resources.GetObject("toolRemove.Image")));
this.toolRemove.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolRemove.Name = "toolRemove";
this.toolRemove.Size = new System.Drawing.Size(23, 22);
this.toolRemove.Text = "Remove";
this.toolRemove.Click += new System.EventHandler(this.toolRemove_Click);
//
// toolRemoveCompleted
//
this.toolRemoveCompleted.Image = ((System.Drawing.Image)(resources.GetObject("toolRemoveCompleted.Image")));
this.toolRemoveCompleted.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolRemoveCompleted.Name = "toolRemoveCompleted";
this.toolRemoveCompleted.Size = new System.Drawing.Size(120, 22);
this.toolRemoveCompleted.Text = "Remove Completed";
this.toolRemoveCompleted.Click += new System.EventHandler(this.toolRemoveCompleted_Click);
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25);
//
// toolMoveSelectionsUp
//
this.toolMoveSelectionsUp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolMoveSelectionsUp.Image = ((System.Drawing.Image)(resources.GetObject("toolMoveSelectionsUp.Image")));
this.toolMoveSelectionsUp.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolMoveSelectionsUp.Name = "toolMoveSelectionsUp";
this.toolMoveSelectionsUp.Size = new System.Drawing.Size(23, 20);
this.toolMoveSelectionsUp.Text = "Move Selections Up";
this.toolMoveSelectionsUp.Click += new System.EventHandler(this.toolStripButton2_Click);
//
// toolMoveSelectionsDown
//
this.toolMoveSelectionsDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolMoveSelectionsDown.Image = ((System.Drawing.Image)(resources.GetObject("toolMoveSelectionsDown.Image")));
this.toolMoveSelectionsDown.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolMoveSelectionsDown.Name = "toolMoveSelectionsDown";
this.toolMoveSelectionsDown.Size = new System.Drawing.Size(23, 20);
this.toolMoveSelectionsDown.Text = "Move Selections Down";
this.toolMoveSelectionsDown.Click += new System.EventHandler(this.toolStripButton3_Click);
//
// notifyIcon
//
this.notifyIcon.ContextMenuStrip = this.notifyIconContextMenu;
this.notifyIcon.Text = "notifyIcon1";
this.notifyIcon.Visible = true;
this.notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(this.showHideToolStripMenuItem_Click);
//
// notifyIconContextMenu
//
this.notifyIconContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.showHideToolStripMenuItem,
this.toolStripSeparator4,
this.clipboardMonitoringToolStripMenuItem,
this.toolStripSeparator14,
this.newDownloadToolStripMenuItem2,
this.newBatchDownloadToolStripMenuItem1,
this.toolStripSeparator11,
this.pauseAllToolStripMenuItem,
this.toolStripSeparator12,
this.optionsToolStripMenuItem1,
this.toolStripSeparator13,
this.exitToolStripMenuItem1});
this.notifyIconContextMenu.Name = "notifyIconContextMenu";
this.notifyIconContextMenu.Size = new System.Drawing.Size(188, 188);
this.notifyIconContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.notifyIconContextMenu_Opening);
//
// showHideToolStripMenuItem
//
this.showHideToolStripMenuItem.Name = "showHideToolStripMenuItem";
this.showHideToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
this.showHideToolStripMenuItem.Text = "Show/Hide";
this.showHideToolStripMenuItem.Click += new System.EventHandler(this.showHideToolStripMenuItem_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(184, 6);
//
// clipboardMonitoringToolStripMenuItem
//
this.clipboardMonitoringToolStripMenuItem.CheckOnClick = true;
this.clipboardMonitoringToolStripMenuItem.Name = "clipboardMonitoringToolStripMenuItem";
this.clipboardMonitoringToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
this.clipboardMonitoringToolStripMenuItem.Text = "Clipboard monitoring";
this.clipboardMonitoringToolStripMenuItem.Click += new System.EventHandler(this.clipboardMonitoringToolStripMenuItem_Click);
//
// toolStripSeparator14
//
this.toolStripSeparator14.Name = "toolStripSeparator14";
this.toolStripSeparator14.Size = new System.Drawing.Size(184, 6);
//
// newDownloadToolStripMenuItem2
//
this.newDownloadToolStripMenuItem2.Name = "newDownloadToolStripMenuItem2";
this.newDownloadToolStripMenuItem2.Size = new System.Drawing.Size(187, 22);
this.newDownloadToolStripMenuItem2.Text = "New Download...";
this.newDownloadToolStripMenuItem2.Click += new System.EventHandler(this.toolNewDownload_Click);
//
// newBatchDownloadToolStripMenuItem1
//
this.newBatchDownloadToolStripMenuItem1.Name = "newBatchDownloadToolStripMenuItem1";
this.newBatchDownloadToolStripMenuItem1.Size = new System.Drawing.Size(187, 22);
this.newBatchDownloadToolStripMenuItem1.Text = "New Batch Download...";
this.newBatchDownloadToolStripMenuItem1.Click += new System.EventHandler(this.newBatchDownloadToolStripMenuItem_Click);
//
// toolStripSeparator11
//
this.toolStripSeparator11.Name = "toolStripSeparator11";
this.toolStripSeparator11.Size = new System.Drawing.Size(184, 6);
//
// pauseAllToolStripMenuItem
//
this.pauseAllToolStripMenuItem.Name = "pauseAllToolStripMenuItem";
this.pauseAllToolStripMenuItem.Size = new System.Drawing.Size(187, 22);
this.pauseAllToolStripMenuItem.Text = "Pause All";
this.pauseAllToolStripMenuItem.Click += new System.EventHandler(this.toolPauseAll_Click);
//
// toolStripSeparator12
//
this.toolStripSeparator12.Name = "toolStripSeparator12";
this.toolStripSeparator12.Size = new System.Drawing.Size(184, 6);
//
// optionsToolStripMenuItem1
//
this.optionsToolStripMenuItem1.Name = "optionsToolStripMenuItem1";
this.optionsToolStripMenuItem1.Size = new System.Drawing.Size(187, 22);
this.optionsToolStripMenuItem1.Text = "Options...";
this.optionsToolStripMenuItem1.Click += new System.EventHandler(this.toolOptions_Click);
//
// toolStripSeparator13
//
this.toolStripSeparator13.Name = "toolStripSeparator13";
this.toolStripSeparator13.Size = new System.Drawing.Size(184, 6);
//
// exitToolStripMenuItem1
//
this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1";
this.exitToolStripMenuItem1.Size = new System.Drawing.Size(187, 22);
this.exitToolStripMenuItem1.Text = "Exit";
this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// menuBarStrip
//
this.menuBarStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
this.toolStripMenuItem4,
this.helpToolStripMenuItem});
this.menuBarStrip.Location = new System.Drawing.Point(0, 0);
this.menuBarStrip.Name = "menuBarStrip";
this.menuBarStrip.Size = new System.Drawing.Size(541, 24);
this.menuBarStrip.TabIndex = 0;
this.menuBarStrip.Text = "menuStrip1";
this.menuBarStrip.Visible = false;
this.menuBarStrip.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.menuBarStrip_ItemClicked);
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.newDownloadToolStripMenuItem1,
this.newVideoDownloadToolStripMenuItem,
this.newBatchDownloadToolStripMenuItem,
this.toolStripSeparator8,
this.importFromTextFileToolStripMenuItem,
this.toolStripSeparator5,
this.exitToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);
this.fileToolStripMenuItem.Text = "File";
//
// newDownloadToolStripMenuItem1
//
this.newDownloadToolStripMenuItem1.Name = "newDownloadToolStripMenuItem1";
this.newDownloadToolStripMenuItem1.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
this.newDownloadToolStripMenuItem1.Size = new System.Drawing.Size(255, 22);
this.newDownloadToolStripMenuItem1.Text = "New Download...";
this.newDownloadToolStripMenuItem1.Click += new System.EventHandler(this.toolNewDownload_Click);
//
// newVideoDownloadToolStripMenuItem
//
this.newVideoDownloadToolStripMenuItem.Name = "newVideoDownloadToolStripMenuItem";
this.newVideoDownloadToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.N)));
this.newVideoDownloadToolStripMenuItem.Size = new System.Drawing.Size(255, 22);
this.newVideoDownloadToolStripMenuItem.Text = "New Video Download...";
this.newVideoDownloadToolStripMenuItem.Click += new System.EventHandler(this.newVideoDownloadToolStripMenuItem_Click);
//
// newBatchDownloadToolStripMenuItem
//
this.newBatchDownloadToolStripMenuItem.Name = "newBatchDownloadToolStripMenuItem";
this.newBatchDownloadToolStripMenuItem.Size = new System.Drawing.Size(255, 22);
this.newBatchDownloadToolStripMenuItem.Text = "New Batch Download...";
this.newBatchDownloadToolStripMenuItem.Click += new System.EventHandler(this.newBatchDownloadToolStripMenuItem_Click);
//
// toolStripSeparator8
//
this.toolStripSeparator8.Name = "toolStripSeparator8";
this.toolStripSeparator8.Size = new System.Drawing.Size(252, 6);
//
// importFromTextFileToolStripMenuItem
//
this.importFromTextFileToolStripMenuItem.Name = "importFromTextFileToolStripMenuItem";
this.importFromTextFileToolStripMenuItem.Size = new System.Drawing.Size(255, 22);
this.importFromTextFileToolStripMenuItem.Text = "Import from file...";
this.importFromTextFileToolStripMenuItem.Click += new System.EventHandler(this.importFromTextFileToolStripMenuItem_Click);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(252, 6);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(255, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.removeToolStripMenuItem,
this.removeCompletedToolStripMenuItem,
this.toolStripSeparator6,
this.selectAllToolStripMenuItem,
this.copyURLToClipboardToolStripMenuItem1,
this.toolStripSeparator9,
this.optionsToolStripMenuItem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.editToolStripMenuItem.Text = "Edit";
//
// removeToolStripMenuItem
//
this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
this.removeToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;
this.removeToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.removeToolStripMenuItem.Text = "Remove";
this.removeToolStripMenuItem.Click += new System.EventHandler(this.toolRemove_Click);
//
// removeCompletedToolStripMenuItem
//
this.removeCompletedToolStripMenuItem.Name = "removeCompletedToolStripMenuItem";
this.removeCompletedToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Delete)));
this.removeCompletedToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.removeCompletedToolStripMenuItem.Text = "Remove Completed";
this.removeCompletedToolStripMenuItem.Click += new System.EventHandler(this.toolRemoveCompleted_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(216, 6);
//
// selectAllToolStripMenuItem
//
this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.selectAllToolStripMenuItem.Text = "Select All";
this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
//
// copyURLToClipboardToolStripMenuItem1
//
this.copyURLToClipboardToolStripMenuItem1.Name = "copyURLToClipboardToolStripMenuItem1";
this.copyURLToClipboardToolStripMenuItem1.Size = new System.Drawing.Size(219, 22);
this.copyURLToClipboardToolStripMenuItem1.Text = "Copy URL to Clipboard";
//
// toolStripSeparator9
//
this.toolStripSeparator9.Name = "toolStripSeparator9";
this.toolStripSeparator9.Size = new System.Drawing.Size(216, 6);
//
// optionsToolStripMenuItem
//
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.optionsToolStripMenuItem.Text = "Options...";
this.optionsToolStripMenuItem.Click += new System.EventHandler(this.toolOptions_Click);
//
// toolStripMenuItem4
//
this.toolStripMenuItem4.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.segmentsToolStripMenuItem,
this.toolbarToolStripMenuItem,
this.gridToolStripMenuItem});
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
this.toolStripMenuItem4.Size = new System.Drawing.Size(41, 20);
this.toolStripMenuItem4.Text = "View";
//
// segmentsToolStripMenuItem
//
this.segmentsToolStripMenuItem.Name = "segmentsToolStripMenuItem";
this.segmentsToolStripMenuItem.Size = new System.Drawing.Size(121, 22);
this.segmentsToolStripMenuItem.Text = "Segments";
this.segmentsToolStripMenuItem.Click += new System.EventHandler(this.viewMenuClickClick);
//
// toolbarToolStripMenuItem
//
this.toolbarToolStripMenuItem.Name = "toolbarToolStripMenuItem";
this.toolbarToolStripMenuItem.Size = new System.Drawing.Size(121, 22);
this.toolbarToolStripMenuItem.Text = "Toolbar";
this.toolbarToolStripMenuItem.Click += new System.EventHandler(this.viewMenuClickClick);
//
// gridToolStripMenuItem
//
this.gridToolStripMenuItem.Name = "gridToolStripMenuItem";
this.gridToolStripMenuItem.Size = new System.Drawing.Size(121, 22);
this.gridToolStripMenuItem.Text = "Grid";
this.gridToolStripMenuItem.Click += new System.EventHandler(this.viewMenuClickClick);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem2,
this.toolStripMenuItem1,
this.toolStripSeparator10,
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20);
this.helpToolStripMenuItem.Text = "Help";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(205, 22);
this.toolStripMenuItem2.Text = "My Downloader Home Page";
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(205, 22);
this.toolStripMenuItem1.Text = "Make a Donation";
//
// toolStripSeparator10
//
this.toolStripSeparator10.Name = "toolStripSeparator10";
this.toolStripSeparator10.Size = new System.Drawing.Size(202, 6);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(205, 22);
this.aboutToolStripMenuItem.Text = "About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.toolAbout_Click);
//
// faTabStrip1
//
this.faTabStrip1.AlwaysShowClose = false;
this.faTabStrip1.AlwaysShowMenuGlyph = false;
this.faTabStrip1.Dock = System.Windows.Forms.DockStyle.Fill;
this.faTabStrip1.Font = new System.Drawing.Font("Tahoma", 8.25F);
this.faTabStrip1.Items.AddRange(new FarsiLibrary.Win.FATabStripItem[] {
this.faTabStripItem1,
this.faTabStripItem2});
this.faTabStrip1.Location = new System.Drawing.Point(0, 25);
this.faTabStrip1.Name = "faTabStrip1";
this.faTabStrip1.SelectedItem = this.faTabStripItem1;
this.faTabStrip1.Size = new System.Drawing.Size(541, 353);
this.faTabStrip1.TabIndex = 2;
this.faTabStrip1.Text = "Downloads";
//
// faTabStripItem1
//
this.faTabStripItem1.CanClose = false;
this.faTabStripItem1.Controls.Add(this.downloadList1);
this.faTabStripItem1.IsDrawn = true;
this.faTabStripItem1.Name = "faTabStripItem1";
this.faTabStripItem1.Selected = true;
this.faTabStripItem1.Size = new System.Drawing.Size(539, 332);
this.faTabStripItem1.TabIndex = 0;
this.faTabStripItem1.Title = "Downloads";
//
// downloadList1
//
this.downloadList1.ClipboardMonitorEnabled = false;
this.downloadList1.Dock = System.Windows.Forms.DockStyle.Fill;
this.downloadList1.Location = new System.Drawing.Point(0, 0);
this.downloadList1.Name = "downloadList1";
this.downloadList1.Size = new System.Drawing.Size(539, 332);
this.downloadList1.TabIndex = 0;
//
// faTabStripItem2
//
this.faTabStripItem2.CanClose = false;
this.faTabStripItem2.Controls.Add(this.webSpider1);
this.faTabStripItem2.IsDrawn = true;
this.faTabStripItem2.Name = "faTabStripItem2";
this.faTabStripItem2.Size = new System.Drawing.Size(655, 320);
this.faTabStripItem2.TabIndex = 1;
this.faTabStripItem2.Title = "Web Spider";
//
// webSpider1
//
this.webSpider1.Dock = System.Windows.Forms.DockStyle.Fill;
this.webSpider1.Location = new System.Drawing.Point(0, 0);
this.webSpider1.Name = "webSpider1";
this.webSpider1.Size = new System.Drawing.Size(655, 320);
this.webSpider1.TabIndex = 0;
//
// statusStrip1
//
this.statusStrip1.ContextMenuStrip = this.cntxMenuDownLimit;
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripLblRate,
this.toolStripLblRateTxt});
this.statusStrip1.Location = new System.Drawing.Point(0, 378);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(541, 22);
this.statusStrip1.TabIndex = 3;
this.statusStrip1.Text = "statusStrip1";
//
// cntxMenuDownLimit
//
this.cntxMenuDownLimit.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.setCustomToolStripMenuItem,
this.enableSpeedLimitToolStripMenuItem});
this.cntxMenuDownLimit.Name = "cntxMenuDownLimit";
this.cntxMenuDownLimit.Size = new System.Drawing.Size(164, 48);
this.cntxMenuDownLimit.Opening += new System.ComponentModel.CancelEventHandler(this.cntxMenuDownLimit_Opening);
//
// setCustomToolStripMenuItem
//
this.setCustomToolStripMenuItem.Name = "setCustomToolStripMenuItem";
this.setCustomToolStripMenuItem.Size = new System.Drawing.Size(163, 22);
this.setCustomToolStripMenuItem.Text = "Set Custom...";
this.setCustomToolStripMenuItem.Click += new System.EventHandler(this.setCustomToolStripMenuItem_Click);
//
// enableSpeedLimitToolStripMenuItem
//
this.enableSpeedLimitToolStripMenuItem.CheckOnClick = true;
this.enableSpeedLimitToolStripMenuItem.Name = "enableSpeedLimitToolStripMenuItem";
this.enableSpeedLimitToolStripMenuItem.Size = new System.Drawing.Size(163, 22);
this.enableSpeedLimitToolStripMenuItem.Text = "Enable Speed Limit";
this.enableSpeedLimitToolStripMenuItem.Click += new System.EventHandler(this.enableSpeedLimitToolStripMenuItem_Click);
//
// toolStripLblRate
//
this.toolStripLblRate.Name = "toolStripLblRate";
this.toolStripLblRate.Size = new System.Drawing.Size(34, 17);
this.toolStripLblRate.Text = "Rate:";
//
// toolStripLblRateTxt
//
this.toolStripLblRateTxt.Name = "toolStripLblRateTxt";
this.toolStripLblRateTxt.Size = new System.Drawing.Size(38, 17);
this.toolStripLblRateTxt.Text = "0 kbps";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(541, 400);
this.Controls.Add(this.faTabStrip1);
this.Controls.Add(this.toolStripMain);
this.Controls.Add(this.menuBarStrip);
this.Controls.Add(this.statusStrip1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MainMenuStrip = this.menuBarStrip;
this.Name = "MainForm";
this.Text = ".Net Download Manager";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.Load += new System.EventHandler(this.MainForm_Load);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown);
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.MainForm_KeyPress);
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp);
this.toolStripMain.ResumeLayout(false);
this.toolStripMain.PerformLayout();
this.notifyIconContextMenu.ResumeLayout(false);
this.menuBarStrip.ResumeLayout(false);
this.menuBarStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.faTabStrip1)).EndInit();
this.faTabStrip1.ResumeLayout(false);
this.faTabStripItem1.ResumeLayout(false);
this.faTabStripItem2.ResumeLayout(false);
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.cntxMenuDownLimit.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Timer tmrRefresh;
private System.Windows.Forms.ToolStrip toolStripMain;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripButton toolStart;
private System.Windows.Forms.ToolStripButton toolPause;
private System.Windows.Forms.ToolStripButton toolPauseAll;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripButton toolRemove;
private System.Windows.Forms.ToolStripButton toolRemoveCompleted;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripButton toolNewDownload;
internal System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.MenuStrip menuBarStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem newDownloadToolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem newBatchDownloadToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyURLToClipboardToolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem removeCompletedToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem4;
private System.Windows.Forms.ToolStripMenuItem segmentsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolbarToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem gridToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
private System.Windows.Forms.ContextMenuStrip notifyIconContextMenu;
private System.Windows.Forms.ToolStripMenuItem newDownloadToolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem newBatchDownloadToolStripMenuItem1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
private System.Windows.Forms.ToolStripMenuItem pauseAllToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator13;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator14;
private System.Windows.Forms.ToolStripMenuItem showHideToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem newVideoDownloadToolStripMenuItem;
private System.Windows.Forms.ToolStripButton toolStripButton1;
private System.Windows.Forms.ToolStripButton toolStripScheduler;
private FarsiLibrary.Win.FATabStrip faTabStrip1;
private FarsiLibrary.Win.FATabStripItem faTabStripItem1;
protected internal DownloadList downloadList1;
private System.Windows.Forms.ToolStripMenuItem importFromTextFileToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel toolStripLblRate;
private System.Windows.Forms.ToolStripStatusLabel toolStripLblRateTxt;
private System.Windows.Forms.ToolStripButton toolMoveSelectionsUp;
private System.Windows.Forms.ToolStripButton toolMoveSelectionsDown;
private System.Windows.Forms.ContextMenuStrip cntxMenuDownLimit;
private System.Windows.Forms.ToolStripMenuItem setCustomToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem enableSpeedLimitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem;
private FarsiLibrary.Win.FATabStripItem faTabStripItem2;
private WebSpider webSpider1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem clipboardMonitoringToolStripMenuItem;
private System.Windows.Forms.ToolStripButton tsbMenu;
}
}
MyDownloader.App/UI/MainForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Web;
using System.Diagnostics;
using MyDownloader.Core;
using MyDownloader.Core.Common;
using MyDownloader.App.SingleInstancing;
using MyDownloader.Extension.AutoDownloads;
using MyDownloader.Core.Extensions;
using MyDownloader.Extension.SpeedLimit;
using MyDownloader.Extension.Video;
using MyDownloader.Extension.WindowsIntegration.ClipboardMonitor;
namespace MyDownloader.App.UI
{
public partial class MainForm : Form, ISingleInstanceEnforcer
{
SpeedLimitExtension speedLimit;
public MainForm()
{
InitializeComponent();
downloadList1.SelectionChange += new EventHandler(downloadList1_SelectionChange);
downloadList1.UpdateUI();
speedLimit = (SpeedLimitExtension)App.Instance.GetExtensionByType(typeof(SpeedLimitExtension));
this.KeyUp+=new KeyEventHandler(MainForm_KeyUp);
this.KeyPreview = true;
}
void downloadList1_SelectionChange(object sender, EventArgs e)
{
int cnt = downloadList1.SelectedCount;
bool isSelected = cnt > 0;
bool isSelectedOnlyOne = cnt == 1;
removeToolStripMenuItem.Enabled = isSelected;
removeCompletedToolStripMenuItem.Enabled = isSelected;
toolStart.Enabled = isSelected;
toolPause.Enabled = isSelected;
toolRemove.Enabled = isSelected;
copyURLToClipboardToolStripMenuItem1.Enabled = isSelectedOnlyOne;
toolMoveSelectionsDown.Enabled = isSelected;
toolMoveSelectionsUp.Enabled = isSelected;
}
private void tmrRefresh_Tick(object sender, EventArgs e)
{
string strRate;
if (speedLimit.CurrentEnabled)
{
strRate = String.Format("[{0:0.##} kpbs] {1:0.##} kbps",
speedLimit.CurrentMaxRate / 1024.0,
DownloadManager.Instance.TotalDownloadRate / 1024.0);
}
else
{
strRate = String.Format("{0:0.##} kbps", DownloadManager.Instance.TotalDownloadRate / 1024.0);
}
toolStripScheduler.Checked = downloadList1.SchedulerStarted();
toolStripLblRateTxt.Text = strRate;
notifyIcon.Text = String.Concat(this.Text, "\n", toolStripLblRate.Text, " ", strRate);
downloadList1.UpdateList();
}
private void MainForm_Load(object sender, EventArgs e)
{
LoadViewSettings();
notifyIcon.Icon = this.Icon;
notifyIcon.Text = this.Text;
notifyIcon.Visible = true;
}
private void toolNewDownload_Click(object sender, EventArgs e)
{
downloadList1.NewFileDownload(null, true);
}
private void toolStart_Click(object sender, EventArgs e)
{
downloadList1.StartSelections();
}
private void toolPause_Click(object sender, EventArgs e)
{
downloadList1.Pause();
}
private void toolPauseAll_Click(object sender, EventArgs e)
{
downloadList1.PauseAll();
}
private void toolRemove_Click(object sender, EventArgs e)
{
downloadList1.RemoveSelections();
}
private void toolRemoveCompleted_Click(object sender, EventArgs e)
{
downloadList1.RemoveCompleted();
}
private void toolOptions_Click(object sender, EventArgs e)
{
using (OptionsForm options = new OptionsForm())
{
options.ShowDialog();
}
}
private void toolAbout_Click(object sender, EventArgs e)
{
using (AboutForm about = new AboutForm())
{
about.ShowDialog();
}
}
#region ISingleInstanceEnforcer Members
public void OnMessageReceived(MessageEventArgs e)
{
string[] args = (string[])e.Message;
if (args.Length == 2 && args[0] == "/sw")
{
this.BeginInvoke((MethodInvoker) delegate { downloadList1.NewDownloadFromData(args[1]); });
}
else
{
downloadList1.AddDownloadURLs(ResourceLocation.FromURLArray(args), 1, null, 0);
}
}
public void OnNewInstanceCreated(EventArgs e)
{
this.Focus();
}
#endregion
private void LoadViewSettings()
{
downloadList1.LoadSettingsView();
toolStripMain.Visible = Settings.Default.ViewToolbar;
if (toolStripMain.Visible)
{
faTabStrip1.Top = menuBarStrip.Height + toolStripMain.Top + 1;
}
else
{
faTabStrip1.Top = menuBarStrip.Height + 4;
}
faTabStrip1.Height = this.ClientSize.Height - statusStrip1.Height - faTabStrip1.Top;
gridToolStripMenuItem.Checked = Settings.Default.ViewGrid;
segmentsToolStripMenuItem.Checked = Settings.Default.ViewTransDetails;
toolbarToolStripMenuItem.Checked = Settings.Default.ViewToolbar;
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void newBatchDownloadToolStripMenuItem_Click(object sender, EventArgs e)
{
downloadList1.NewBatchDownload();
}
private void viewMenuClickClick(object sender, EventArgs e)
{
ToolStripMenuItem menu = ((ToolStripMenuItem)sender);
menu.Checked = !menu.Checked;
Settings.Default.ViewGrid = gridToolStripMenuItem.Checked;
Settings.Default.ViewToolbar = toolbarToolStripMenuItem.Checked;
Settings.Default.ViewTransDetails = segmentsToolStripMenuItem.Checked;
LoadViewSettings();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
Settings.Default.Save();
}
private void showHideToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowHideForm();
}
public void ShowHideForm()
{
if (this.Visible)
{
HideForm();
}
else
{
ShowForm();
LoadViewSettings();
}
}
public void ShowForm()
{
this.ShowInTaskbar = true;
this.Visible = true;
this.WindowState = FormWindowState.Normal;
}
public void HideForm()
{
this.ShowInTaskbar = false;
this.Visible = false;
}
private void showHideToolStripMenuItem_Click(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ShowHideForm();
}
}
private void newVideoDownloadToolStripMenuItem_Click(object sender, EventArgs e)
{
downloadList1.NewVideoDownload();
}
private void toolStripScheduler_Click(object sender, EventArgs e)
{
downloadList1.StartScheduler(toolStripScheduler.Checked);
}
private void importFromTextFileToolStripMenuItem_Click(object sender, EventArgs e)
{
downloadList1.ImportFromTextFile();
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
downloadList1.MoveSelectionsUp();
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
downloadList1.MoveSelectionsDown();
}
private void setCustomToolStripMenuItem_Click(object sender, EventArgs e)
{
((SpeedLimitUIExtension)speedLimit.UIExtension).ShowSpeedLimitDialog();
}
private void enableSpeedLimitToolStripMenuItem_Click(object sender, EventArgs e)
{
speedLimit.Parameters.Enabled = enableSpeedLimitToolStripMenuItem.Checked;
}
private void cntxMenuDownLimit_Opening(object sender, CancelEventArgs e)
{
enableSpeedLimitToolStripMenuItem.Checked = speedLimit.Parameters.Enabled;
}
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
downloadList1.SelectAll();
}
private void clipboardMonitoringToolStripMenuItem_Click(object sender, EventArgs e)
{
downloadList1.ClipboardMonitorEnabled = (clipboardMonitoringToolStripMenuItem.Checked);
}
private void notifyIconContextMenu_Opening(object sender, CancelEventArgs e)
{
clipboardMonitoringToolStripMenuItem.Checked = downloadList1.ClipboardMonitorEnabled;
}
private void menuBarStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
{
}
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
}
private void tsbMenu_Click(object sender, EventArgs e)
{
menuBarStrip.Visible = !menuBarStrip.Visible;
}
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Alt)
{
menuBarStrip.Visible = !menuBarStrip.Visible;
}
}
}
}
MyDownloader.App/UI/MainForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="tmrRefresh.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="toolStripMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>124, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="tsbMenu.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolNewDownload.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHNSURBVDhPrdJLTxNRGMZxPosLl14WkvgRdOvGjSvdundD
IgmJpOIFKw1Y1FoVoxNqNEqNkBbEUokx1AhiuViHdppebKbj9Dpl+nfmYCeplykLT/LmzFm8v7znOdPX
9z+WHDuPmhzGKIyzGTpIM3cNdfsmO+8vsS+/kgnw7dVR0EZIvzlt7ddJzRxC3fLuDzCKE6D7oBVHV6at
fVGcd9Yv43swI2rs/kvm4x//DialA8jRU1RyTzEpUyu+EGdltp/OuhF4Tv/Jc0SXEn8iYgLNC42oQOxJ
xLl81wGuToZ4HVsVSCS20o1UlSCp8BHM/ADZpTNWo9fK4LAVZsABPOOPRXOnusJNL1/Ye4WsByVynNSX
CWryKPnEoAOY7Ta3p98yKS0KxPV1nK5fH1Yv9WaLklYjNJ/k2Imz/wZGbkm/99MwdlH1OpnCD6S5NXdg
eOxRF2C0dtEqTbLfdTbSJabCK+7A0GjQAVqmiV5tkitV2MqoJDbz3Hv2zh24eOWOAEyzTbVuUFCrpLJl
Pm0Xia8q+J8suAMDHj9tK7V6Yy80Oafx+WuR5TWFyAcZ38O53oAdmp22HZh954A1tl9awDc1izcY7n0F
+5l6Vec/+AnmUPTg0ZAUnAAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABYAAAASCAYAAABfJS4tAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMbSURBVDhP1VRLKK1RGN1TUwMDIsnreL8fx1sij5BnOByl
GJlTKBMDBl4pZKIMJMpIkpRn8gpxBqfDySuP8joHdSLr3vXpv7lncu/kDu6u1f/v/e+9vvWt79u/Uv/L
2NzcxF9p/fj4wPv7O+x2Oz4/P/Hy8oLl5WV0dXWhpaUF4+Pj2N/fx9raGrq7u+Hj44OzszMo/BxPT08w
mUx4e3sTEofDgeHhYZSXlyM5ORn9/f0wm824ubnBwMAAgoODhcBoNGJ7exsbGxvo6+uDr68vPD09cX5+
DpWXl4eAgACJ/vz8jKurKywuLsqat7c3GhsbcXp6itvbW4yNjSE+Pl6CVVRUiLLDw0NcXl5ibm4OKysr
2NraEh6VmJiIzs5OChfS6+trpKWloa2tTVJjdA5a8Pj4+HXoD8Nms0E1NDTg+PgYr6+vQnB0dIShoSFM
T09jZGRE0r+/v4fVahVVXB8dHRX19H13dxd3d3eYnZ1FR0cHenp6ZK5qa2tRVlaGk5MTPDw8CKg2MDBQ
vKyvr4fFYpEALFJJSQn8/PwQFhYGg8GAnZ0dHBwcYHJyEkVFRXBxcRFLVHNzM8LDwyV9Fuji4kKKV1dX
h5iYGPj7+wv53t4elpaWpFiVlZXIz8+Hh4cH2tvbJYuFhQVMTU1Bp9NhfX0dqqmpCaWlpbIxISEB2dnZ
8PLykuIUFBQgKSkJUVFRSE1NlW+svF6vR0REhJDExsaKenZDbm4u3N3dMT8/D1VTU4PMzEwBiUjAIERc
XJwcysnJAYvM98LCQoSEhAghs2S20dHRco7WcS6KW1tbZUN6erqA7wQ3pqSkSGsRzIatRjAgbSIhwYy4
xqerqytWV1eh6BdJMjIyBBq5MzEVk1wLQCKqZgCCc35jTdhZqqqqCsXFxb8p1pTSSxISJNGgqaVCIjIy
UmwgKT3m9VbV1dXi2XcrnImpRFP2PX2NlMQ8w3lQUNAX8cTEBHitv6vgRladxQoNDRXwgDPYFRrc3NxE
cVZWllxzuZxs7sHBQQF/MgR/PPyxEL29vb/etTXnJ2/rzMzMV0f8y/EDxS7Ufs2gVXAAAAAASUVORK5C
YII=
</value>
</data>
<data name="toolStart.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC3SURBVDhPY2CgBTj/6Mx/isxNmJHw//zD0+QbAjLAocLg
/7kHp8gzJGFGwP8NNxaADTn74CTphgRMCPhfcKAAbsiZ+ydIMySgwwFsAAgnLAgAu+TMvePEG+LQADRg
QwJEc4PBf4MChf8KGQL/L90gMmANgJqQNQskMBCvGRT/BhUKcJtBmi9cJzEMFIBOBjkbpPn8VRL8Dkt9
IP+CNJ+9fJT4gENOugIJAv9PXzxEnmaK8sCAaAYAI/1yOuyCUFkAAAAASUVORK5CYII=
</value>
</data>
<data name="toolStripScheduler.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADfSURBVDhPzZO7DcMgEIYZgREYgRE8AiNQpnTp0mXKlC4z
gkeIIkV52I7zUBRXiZNFLoCVw5bN1UaiQN/9HwcCxmYx6m8JoUYohhmdaag/xaSEYgNBlEg4t6eRxApC
rCdQkDdrV1i1x4FEZ2GGArVSEG9ilJTvA0oo5gXLyAns1GvlOilfeydRBENBlBpBrrtwKkHGAsSCw60p
zDrMUCBNqB/mmrmwLaCYFyQCd7bhy9PfgSQYCoRp2bZtw/WjO/t/UMwXmfPacHXfjd6BvYsQQwHXHIrr
dvIlUmwW/5D9AAiU5HOciitHAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolPause.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACUSURBVDhPY2AYfmDChv//Qbh8zoP/IN+h8wn6GKThwoP/
/w0iNsANQOYTNKBhw4f/D178/68QsABsADqfsAErPoBdoOABNQCNT9iABUADbvz/L+AwAeICND5RBhy4
ADTAAmEAMp+gAQUzHvzfcAJogEED2AXofKIMWHDgw38GJAOQ+QQNKJtzH6IZagA6n6ABI1ABADKdl1Hq
gthwAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolPauseAll.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACzSURBVDhPY2AYVGDChv//Qbh8zoP/IIeh8wk6FqThwoP/
/w0iNsANQOYTNKBhw4f/D178/68QsABsADqfsAErPoBdoOABMYBkLzUsABpw4/9/AYcJWL2A7kUMF4EM
OHABaIAFxACSvVQw48H/DSeABhg0QAxA8xI6H8MFIAMWHPjwnwFmAJqX0L2IYUDZnPsQzUgGoHgJzYsE
YwXdS+h8ogxA9hK6FwkagO4ldD5BA+iiAADgBf5+NvTs7wAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolRemove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFjSURBVDhPrZJNKMNhHMd3Vd5K7eKCWu2ATLIJyWRIQ2Qa
kbdJO3BYJLTLDg6kXMgBF8mBpKScaNlpjMlLmqxJyWUH1v/4fOwlatnsT57Lc3i+38/v+/s9P4Xivw7W
NnA7+ROP3Q3ESDNiwADHBz9CePbD9mq8hv1NGDchBg2I4UZYX0wIiSQUA/XgGEtcJArpKEOYK8HWHScS
MxaESQtL9p/bZGsF0aSOgpi1gO8a5idj0PAta0b476GnJtZSWymiUwcTvfLMnxU4Ow1H1iGMRdCq+Z05
AsFcBeU5SJps3jWZ0F4mH4KpAqpzCQ4Z4fYi+kOvhWHIzlpqCH16QrV5+OqKCLpOvgzM2fCqMpCuzpND
mB4CfT6XhUqCh3txQkJvvDQUE+hvSbIDp0dIWiXegjQCo12JF+npEacqC8nr/v7OsoOAOh2foQQCD0lj
SnYr3HgSAO68sDAFHlfqQcnaJpmiD4li7HlpWRgfAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolRemoveCompleted.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACjSURBVDhP7ZHBCYNAEEUHRFCsSsRCRETEMjyIiAcLsAgR
ewkJnnNOBS+MZjUJiRevLjxmZufzWf6KnOd4AhcR9rhaFsrkOCvvetEFfQ/j+JthAIPqtH9pH56HqBtd
B3EMSQJpCnm+obOi+yhaapbNJvfVoG0hDCEI/uP7YFDdh0HTQF2DVtPrrJTlQlFsVNV8t75gcl2+udn2
brgmyOPfeDrIE2+j8lfhrSv8AAAAAElFTkSuQmCC
</value>
</data>
<data name="toolMoveSelectionsUp.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACWSURBVDhPY2AY/sCx/P5/sn3pU33l/6JD///7Nz0h3RC7
rL3/e9a++z9z5w/SDTGKWv4/p//q/9r5jyCG7CLBEFWfmf9BOLrhBNiQmvmP//esgxhiV3j9P9FhAjIk
pv4kxCXzHv03Sd5PWjiADPAp2At3iUHMFtINsE/dDDYE5BKdsJWkGwALDxCt7j+fNAPITjxDTyMA5vB1
magAfuoAAAAASUVORK5CYII=
</value>
</data>
<data name="toolMoveSelectionsDown.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACeSURBVDhPY2AYBVhDQN1//n9Vn5komKSg0glb+T+m/uR/
n4K9/+1TN4MNIskAg5gt/3P6r/6PbjgBNoRkA0yS9/+vnfcIbAjIJUQb4Fh+/79d4fX/M3f9+N+z7t3/
mvmP4S6BhQlBr/g3Pfm/6NB/iCFr3/2vnQ9xiVHUcuLDAW7IToghdll7idcMcyLMEJ/qK6RrhhkCChOC
fh76CgCQHnWZxAuPXQAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="notifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>238, 20</value>
</metadata>
<metadata name="notifyIconContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>335, 21</value>
</metadata>
<metadata name="menuBarStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>502, 21</value>
</metadata>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>621, 21</value>
</metadata>
<metadata name="cntxMenuDownLimit.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>731, 21</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>72</value>
</metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAQAAAAAAAEAIABmZAAARgAAABAQAAABACAAaAQAAKxkAAAgIAAAAQAgAKgQAAAUaQAAMDAAAAEA
IACoJQAAvHkAAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgGAAAAXHKoZgAAZC1JREFUeJzsvQmYJNdV
Jnoi960qa9+X3le1utWtltSyVsvCRuB9kz14PGNsA48xw8PGw2LAhnnzeDAMM9gMDMPwwTDY2BjjBWFs
g7xLxrIleZFktdyt7lZ37XvuS0S8c+69J+JmVFZ1dVdWV1VnHOl2ZGVGRkZGxn/Of5Z7rmHbNvjiiy/N
KYHNPgFffPFl88RXAL740sTiKwBffGli8RWAL740sfgKwBdfmlh8BeCLL00svgLwxZcmFl8B+OJLE4uv
AHzxpYnFVwC++NLE4isAX3xpYvEVgC++NLH4CsAXX5pYfAXgiy9NLL4C8MWXJhZfAfjiSxOLrwB88aWJ
xVcAvvjSxOIrAF98aWLxFYAvvjSx+ArAF1+aWHwF4IsvTSy+AvDFlyYWXwH44ksTi68AfPGlicVXAL74
0sTiKwBffGli8RWAL740sfgKwBdfmlh8BeCLL00svgLwxZcmFl8B+OJLE4uvAHzxpYnFVwC++NLE4isA
X3xpYvEVgC++NLH4CsAXX5pYfAXgiy9NLL4C8MWXJhZfAfjiSxOLrwB88aWJxVcAvvjSxOIrAF98aWLx
FYAvvjSx+ArAF1+aWEKbfQLXSkbu/rnNPoWGSSAUhcVz34CFs1/b7FOpkd6b3gjRtkGwzcpmn4oug7Zt
34Db/ZZll3H7zVKl+uSLTx203veT90FHWxpy+TxUymWIx+MQCAahUqlAJBKBID7O5XIQi8XANE0IGAAL
2TL86d/9C3zzOz+E+cUclBBCVnsvgLHcll76m1+45l/2SqVpFIAvTSctCPw7bRveYlv2i8CAlmAYwWpZ
Z6sF6/+tmtbHN/sEt4L4LoAv15MkEPCnLAt+v1o1Hwsaxt8nE9EHR3f2Dh+9aW/bnbcfbHvzq04df8eD
d31sqK/t/6tUzTbDMEJgGJt93psmPgPwZTsLGbDdaOlvNU37dsTxnaGgcTgQDhldXe3Q1p6CHUPdsGuw
A47s6IPhnjREwkGk81Ujlyu+NxgKPZjP5z9nmeY38TifRkUwZTSZMvAZgC/bSZDWA4LdehuODyGdfwyt
+JMI2r/s7Ej9THdf+w0HD40aL7n3KLz07iPw9lfdBv/2gZvhwXuPwbG9A9DZmoDWZBx6uzphdKgP2lpS
I0Yg8A58/4cQ/P+Ix/uTUqn0Rvx7dLO/6LUSnwH4slWF6Hw/gL0LbLjNsq1TpmXvC4eCg8lkNGYbAWhN
J2C4vwMSiRj0d7XAwR290JaMwWB3K3S1JiEaCUMwYABZdQroIdgpBgDZbFZskTmIAF8oFIoiC7ipUq0e
QwXw1nKp9B18z2/ie/5+sy/CRouvAHzZChLD0Y3jBsuyjyM4jyJm94RCwT2GEWgBBG5PRwu0I6UPI6hH
+tthD1L7VCwMAwj8gc4WSMQiEA2HcAQR7PK2poh+AN9brVahUCyKLRH8qAS9UAr0XKlcBhO3pmka4XA4
gu85WS6X/wf+/Ye4+x+jMpiTroG9eVdog8RXAL5ca4ni2INA348W+AA+3o/YOoLbA6YN8Ra04Gm07AYC
tLUlDntHu6EdrXkSwb57sBP62lsgHg1CKh6FZDQCwVAQCJgEaAI7GnUBahstfLFUEo8R1ALsqVRK7EMp
PXo+n8sBBQDpvZQCpC2lAOm1gGEMoGL4Ndz/1fjc4zi+EY9FH8bdz2/u5Wus+ArAl40Sii/1I9CHcbsL
QXojgvO4aVn70Ja2J+LRlmg8bFi4WyoVh51DndCKPno0EoTdA50w0tcO8UgI2hJRaEvFIIFgN5DOE4AJ
0AF0AWz6z5ajVCoL8BLQSQuEcB+R1yfaj4An211EFkDgJ2tOz8cTCbE/vZ9Av7i4KF/DEcP3JpLJWLVS
udm2rZuRWfwbAOvbqDH+CzKT7+C5jOEH5bY7J/AVgC81kk6nqQgmiQ87EBgtp06d6u3s6tqBnvQAoqMN
wdEFEtwBpNiXMktL3/7Hz3/hW5ls0Sibxq5A1TwOpoVgt/eg/z0YjoT6jGBApNo6kML3d6chiDQ+iRb8
wI5u6OtohUg4AJ1o7Xvw9VQ8AiEEJ41IRFpuAhkBk0g4+e5Iz8WWLL9lWkIhkPWm4h0CNgkpAwK8UBC4
ryGOF3H3weNR8U+hUBDHos9JKIVAn4XAx3MwIJVOwcxCHp74wYXIZ7745KmzL0x9LJMtLS3mimOoKf7B
sOzfxvOb2bQfbJ3iK4AmFEWXDbR60eHhkbYjR47sI8Dic/tuPHp0Z0tLywiCYCfu2oP7Ggw+4QcbhgNG
ssj4Lxw7fkt5bK4E43OFyNQi+tOBMITRzzbCEehF/3zXUAe0JGLCPx9BBdDTkRTWPYL0PYojFo0ooNsQ
DMhgHQGXLDeBnRQA++9B5bsLFoD7MVhpX9pWycLTd1RKgfYNEgvA4xHgiQFU1DFZIdCx6PPo64RD9G5S
IhF49sI0fOGRp+HL33wGfnB2HKqoc+xw1KiEYmkj3JIOBQMHUXn8WMy2fwFP47Ob9XuuR4Lvf//7N/sc
ron8/p9vy9+nrhhoUEsLF6E4f2HN79m3b3/rzp27bhwcHLz7ta993YP3veQlP3vHHXf+h1tvu+19Bw4e
/Mndu3e/Gscd4VDoMO4+hMBKobU3aiiu7f7FjwgusVg42N8RD+4ZbIGDo21ww2gajuzuhpv398GxvX1w
Yt8Q3LRnAG7c3QcDXWloRWWQbklAKkGUP6IObQtLXEIQV9B3J6DS3wEF9mg0qvn5tlAMZeXjE7jp3MJ4
LIrq0/6kGMR+uE9RHY+EjiHofTyG4A8JlhEQMYQgTMxm4bvPTcCnHv4O/MFf/hP86d98Gb7y7dMwncH3
x1JgJtEt6eyCF53YD6+8+wi85Jb9EE8mu56fWHwTujqkU7+kX653v+HUlf+411gM297uXszapFnmAhBA
+vr6w3j/j5w4cWL/6I4dt9mWfdvQ0NAe9Hl7cJck0WMBZlX0QveAbuV5gPKHV/pbDGWF2XcOBAMIKENo
BnpLGFkAAbO1pQUGBgZEIC6EoC4pGh9QQGXLzv45nR8B27Hq2rkSiAXIQSkipTzKlYr7fQBk8I+OS+eI
5p1SgmTl6fhzi3mYmsvCxckFeOqHY/D40+fh/KUZmJxdglypCiFiMJE4VPBaI8hhz3AP3HV0BH7s1r1w
CF2XdDIqPqOA+37iq8/A+/7sYSiWqz+Fn/Un/Fv4cwF82TAxgpGav5OpVOyuO++6DUH2sv0HDtyOFvMG
BEK7pLaGAFFVASTAwA0EloG+Btj0Gm7l/qQgDOdvRxnw68seGyJQJ1wGhGkmm4PTz/0QLXlExBn6enuF
zy38egY6Re/xMVlrBjopi6iy/GzVReoOrToBv0r+O8UMcB86toGfSUAni05b07QhWyhBvliBsalFePrM
BDxzdgzOXpiCsxenYRYVAaUZIRQBG8FuJzoh2Z3Ac0zBUE8bnDo0BLcfHkYW0w+drTEwLWQVVROPWRbX
kj7jJ+6/ES5MLcF//ugjv5aIBR/Cpy9d05thHeIzgG0rBow/9hdQLSyi3xqAN7/pzQ/u3rvnv4eD4Xa6
SYWfjJY3JCLmykJTXpwtrBIRYANYZsm9gCdgSVCz1QcB8GUKQH+fpgScxyAVDlnnRDIBSXIDkN7zMYIa
zSe/3lLWXcQA6HVxXPm5BPKI2F+yA6HkTAuy+TI8f2kWAT4Dz9N4YRpOn5uA2YUcVPD1EnoDFoI9EIlC
GN0BGi2pOOwZ7EQXphuO7u6BG3b2wO5+pPxRWUxUqlSFMgG9UtiW14+u/8xiAV7xqx+BF6aWfiYSDv4x
vXzxY//3NboXrl58BbA9JWgEQl256R/25yaeHj5w6Oibe9PBl4UCdjIUMMLRcEDUvAeJjgeCAmARvNkj
uI3GooKGk/WNxxNOKkyxdukZgKsQXMCvYPHrgVx77FUWzmNDfiBZ7o72dqEQCOQc7DOUG0AKIYTfJRQM
CfrOrgq9nC1UYHImg1Q+A+MzS/DD85No3cfhwtgsLGULsJBF/x/BHqTIf4QAH0MrHxGVg6MI7tHedjgw
0gk37emDgyNd0N4Sh1ak9iG8bqRIqoKJ1IQ+lgm/RHUK7/njL8D/+ocnvoyP76HnfAWwhWSbKoAk/jzt
eJt14uOD+PgAWsMD+JvtRoB1R2OxHgRIvFIpQhDK0JkMQGsC4WGbELCr0J4IQTKCgMG/rWqFJsFAVfne
HP2OJ5LQ0dkBPT090NbWAamWlFAYliWDZrUsoP5jmVarA/J67MBhGQGHZVD0P+wU48g4gEgFBuV7cki3
FxHQS7mSoPHPojU/fW4SLk3OwzSCfxJHBq1+AI9BmQdA626FCPQR6EAq39neAv2dLXBotAstezfsGegQ
1YN9HSnxGYRiE68JMSdL1RVcidDexBS+/J3z8IYPfHwxHA6ewEtw5uJHf77xd0SDxc8CbL6IQDoOCtAd
xRvwpXgjPoggfSf+/fMIgF9CQPyCbRivSyRj9wz0td8wMNA50NHd0bZrZ0/4zpO74UXH98CN+4fh2EH0
VQ/vhuOHduHfO2DvrhEYHR6CHSMjMIJjaGgQ+vrRl+3qEpafbvRsJgPTU1Nw/tw5HM/DzPQ0lEtlaG1t
hbZ0m4iYy6CbDOZFUGkI5RHBbdjd1n8clu8Ly6AdjUiI0nM48Dnh46tBFX0iqIa+Oo1nz03B1588C5/5
0vfgb7/wOHz4oW/Cn33i6/AJfPzId87B0+dn4MJcEWbKATBjLZBEBdba2wd9+B1P3LgLHrjjMPzEj9wE
b3vgOPzUy0/ATz5wE9x/fBcc2dkLg12tot6AAE+W3rQtmUkAGbisGxPRB9QGRoVrQkoLlcnnHjsbm88U
HsHnFt79+lOZzbut1ia+Ari2gqiDXXiz3WRZ9ksQgA8iCn8a/36faVq/irfg2+PxyCvb2lIvamlNHkq1
pQZ27+pP3HoTgvrITji0bxBedGw33H/bAbjv5B4RoDq6i+gr+q17BmD/aD8M9XXBQG8XDA8M4LYX+nq7
oRMtfHtHO3R0dCCo09CGlLuruwt6EDC9uE9Xdzda/hbBDGZnZoQy+OFzz0EmsySi990ILnIdQiKusBzw
DG7+O6QAL3LxAuhhAXCRxgtK18QNQNJlkcU65Gs/iqD/1f/6KQH6f3r0Gfj6d8/DM5fmYSJrQjkch0BL
Oxit+H3wvA8d2Al3nNgPD7zoMDx431EB9He9+iS88e7DcP+JnXBsdy+M9KSRniPYidIj4E01bAfwCtBX
8p8H/OzOJNAN+OfHz8KZsfnv4He5+J43nJrczJttLeIrgMYLRbq68AbbiffYUby3fxwfvxVvwHdXqtYv
483+s7FY+O2xeOQVoWjk9lQ6eXDPzt6uGw4NR3bt6g/s2zsA99yyD176okNw78174LYbRuDkgUG4Bcet
B4Zg71An9CJ17Um3QE9HmwheJRCcUUXpQyrtJWrcBRApOh6DZDIprHo7gp9GZ0cndLS1iYg8gV9YfFIQ
bdLqU6rw4gsvwDNPPw2ZpQwMI4Nob29zinDCobAD8nCNNQ+KfSj2wDPxxH82VfFJoNPEm0q5Igbl6UtF
9NULebFtT0Xh6YsLcA5tZyGcgtaeXti5ZxQOH9wBdx3fB69/8Y3w06+4GX72VSfhLfcfhTfcfRDuPjqK
lr1H0HoqMCK3wVa03lJgV3j1jHrZj9UtPwk5LVJv2eIxxSboM2gy0le++wI8eWbyB6jkLr33wdvPfOAD
HwAeWxFrvgK4OqHfP4UD/XM4hD/+i3G8BkH+M5Zp/xzeKz+PFu89eBO8DVHwo63p5MnR4e6dO0Z72nsH
u+P79vQH7rvtINx723647egOuP1GvLmP7YR7cNx+aAQODnfBUHcr7Ohrh8FuBGxLEhLxqArmhUW1nG1T
kIpSZ3JiS1WlzkRKTBXOhBUF16P+4FTxBQTQW1papELo7IQuHKQA6DnyxykARwU35BqcfvZZGBwYRDdi
SAAhKNJsQSc95+bpLVGeSyCvVqqi6q5cLomy3GKhAPl8HvK0zeXkwL+p7x6V5NIIBwFZSxfs2z0Eb/nR
m+EdL8eB9P0nX3YT/PipvagMB2BnP7KZ1riwuGTH2W8Xw/2al6fydZVCnaEAz48DirWIuAco5QIy8Pn4
Dyfgmz8YO4uKZDz/zOe/o980WxFrfh3A5SWOYzdNaqFyWRw7AoaxE2+gXXi77TBtO02Wrw1vSJrJRrPY
AgiOod42GKW56ghcijORdRrsQjoaR6uJf8cFXQ4K601Aops4oFJbtiVIsSxbRSCJfLeqZAuoNBgF18Kh
iAs8EcSSvqylcuokQTUlloZIoVHEH8DJt1vCSspcOgfiWpEVkLvQ29sDU5OTMHbpIkyMjcPH/voj8Na3
vQ127twpAM3v5SGOh0Pf8mfon8X1+U7ATQGXvkkGn9+Hiu/+20aho7MLFZV2vqL+/+plTb1+9ACgKkYy
1PUFdb7it1DfgbWESLFCGFqTpHCNOO6XXNfJXiPxFYArPfijHcZB3WAG8PclsO/DG2AH/p2OxyIJHAGK
NNv4g7elEzAy0C6mqtqo+dOJKOwd7haWKYIIjyO4U+h70qSXWJRz8SDSWaQwZNDJVmkmCQKi3VTgwhbb
ATuBEyk++60MKKqm4/1IuPEFBemIATCwGHhUKWfje5zjG7JgJkw58UDCLbShiTTdnTA2kYZixYCLUxnI
mrOQnZ2DL3z+c/CvfuItghmQdReluB6Q26wUFEgcy6xbaR1ohuGAk54toCuwlMlDLFESc/c5z7/edl3L
3q3OQT8fWwM8D1GYRN+HCpUEs6nIxzTJiK4juUJUOYgjIllCwLLXebLXSPw0IMCtaN3fiTfsSyORUB+O
YNU2IJGQE1na0klh0SPo39F89MGetGg+EcabsiMVg7aWmAgyhYSlFVPkICZmnEk/lMttuVy1qkDCYOPS
V7bULFzxxjXsTHFJ2N/mnDioY5nKv+bj8iw4nhAju+LIklg+X0qxLWWLkMkVYX6pABcn5uH5SzPw3PkJ
mJpZhNnZWZiemoSF+RnYNxCF2w4Pwate/WpkB32Qy2Yd0DvnyI/V3zWyhnuNzpeUFwUe+/sHaEqurFO4
SnGCffr51CghCk7YzrnzEFOIaVQrklGVyrhFhUfzCmhacUk2EREpS5pX0NIK8fY2+MtHzsJv/tWjD1XA
+Ozsp977h/XOZStJMyuATvzqv4M+61sT8Uiwq7sN2jpaYc9IF4z00lz0IFrzhCgOocBUmIJfQZmbJotO
0W4hhlsfb2m02vFJ1fVlCg5ablyvduPHTHN54gv72Kwc2NLysRl8IdXyKiAAHhSWPRSSn1UuV6FQqiAD
qIpc+oXxeRyz8AKCfWJqASZmMzA2vQAzCzkJXCMIVSS0JrkmdEy7CiErCyl7Ce7YEYWXveReuOHIEeG7
87k0SrhKkNyQwaEhEY+ga7FGAl8jQhnRbyH+sB0aTzUOtmk5z4mhrDxZeLMqLbxFsweJ5RDgkZVUiwWx
rRTyqABKQjFQhWQolYRYRyek+nrhY9+bhN/62GP/gKr3s+VP/8qHFvXz2YJYa9YgYC/+GJ/BW+rlg0Nd
gb0HRuHkkVH48dsPwt3HdsHxvQNwYLgLhnvaoAuVQDqVgNYUla3GRZ+5QCDoWFyy0mXlczMYA6o2nWvZ
A2qSi5jWivuWFXVmP5gkpEp3uUCH6S6XwZJ7wIolwP56TFa1xYl6RsKieIYAT7Xv58Zm4YlnXoBHnjgL
n3/kGfjY574Nf/53j8BffuYb8NCXvwtf+tYZePSpi/DMxQW4tFiGLEQg2NIGgdYOiLSjEtwxBDce3gn3
nDwIL8Prcv+J3XB8T7coPaac9649exwmo7sq6x2CrdDA75dMpUQGg+IAV0L/hXIU1hvBjNeNQCysNo5K
oQDVPI08VFGBVXJZqGRwIJspLy3JsbgEpYUFKM3PQ2luHorzc1Ccm4MSukClhXnxWhlfK2cy+L4MWKLv
gCUqDp+eysHXfnDpDF6VH/acfvgxvVHAVsRaMzKAMH7nT6KlfGD3ngE4dGAEbj84BLceHIEUgonAaahm
FDJQZgm/nCwdz1YjcRpNatacxFSTbjio5zAAkZaTsQBQZa7Oe+hGVdaJS2C51j2kAMFRbU6tEW2fW8wh
bc+LSjii7ucuzcKZC1Mwh89lidJnkNoXy8KiB0mpROQcfSsQEn93t6fE6EynYKSnFfYOtMOO/jbYjdsO
ZD6pRFT03SOaPDszDd/7/lPwxX9+GPK5PLzpX71ZKIBKpfGrABFTorLlnp5eaO/oEEpxrQrAseIE/FJJ
Ar5UBKskrTm9RtYdVKDS1gb9DqD8e1NZf7LydCxRQUlKm/1/+t60PylBPNd4Vxe07hiFT10swO899NQX
rED4oYf+/tf/oEvUZUrZsQWx1oxBwHfg/fzAzl19cDNVjJ3cDYd2D4uUFS0R1dKSEmksajElovD4Q1Nk
nAbdgvRcWVljtsh0I4FSCDwJRw/M8b4cmWcflKfPiny9Sq2Ri0GuBikQqojLIGXP47nML+bRN5+D82Mz
SN/nYGp2CWYXsgj+rPDdDSquCYWRtocEwK0gui2U4utH9tIi22EPdrfAvsEO2IUAH+1Ji1LY7nQCFUBc
uid1hL5fhQCCSoTKhlvb20VcgLIARM851tAwUS6VaOZpVlXbL6vu0lvLzlUF6oiyV9C6kzUv4SDrLmg8
KgRSAAR2UNRfxAHYZVNuAKjsha1YGrsIhmA8eCrUh5BiPJTeEe3G0FBUUEGQW1BGt8C2jIBlGc/jrtNa
5GNH465Sw6TZFEAKLfpPdeKNPzraB/ceHYXDe0YcX5aKYkp4ozBoicLTxBlSAhVtuipbfp0B1CgEZRk5
GBdUs9eIVYSVkiD/nNhFpWqKQVNMJ9A3n5hZFNZ8bHpR1LnT44uT87CQLYiiFgpQFiyKM4cQ9Kg4Yi0Q
H+iBMFmheBSG0JIPd6dFrpys+kBXSoCd6gqSwpovt6TEPiqmufxqsdggOu3GYtRIIyGuFSmAjs5Ox+1p
qCgFILMIlIpDvF3OeNJ1x2toUoERKvICUvf81JSk7qgEqtT6q0rgVLN71DRpl1m4AVU+nmRohnT58Pvr
U6fFaypAKNie6kVIxoAUAP5M8GgyCQ/jvcUhzJc2/kqtW5pNAdyE1P/Gnv5OOLanD27cO+J0laECGFIE
FIGm9BZRb6KhJdVOmkCiesg7+W0CAYkMUoFkAQT0sKyI0xtJk/3KIR2/hMCenUfLPZsRDSkoGEfU/dLU
PNL2EjWVQNpegUIFb6RgWKSYgjSTLYlkMhgWSmQfgrm/gyoBEdy9bQj2NgHyXQj6lkQE4tGQqEpjoXMg
ZVOuXjlYGR4B1VMvFouKm5++O8UqTJUTb6hw0FMpUz2YupLYitKTpS+hD5+fnobc5AQU0G8nP5+i9qBn
Xcg9I8UclLEHlcKRFp6Lm+i43P9AnZfzmgB7RFp91FDEvgyeFGXbopMS/QKPN/bKNFyaSQEM4U10igDU
39sOtx4YhmgkBAsLOUFlyWIT+IWVx52JxpNCEB1miQngPhQLoMHWncpruc00/U35fwpekRWfQZBP46A5
6DQfXUTc8Xny3cmazyClJzyKGWx489A0VTtI01WDkOyNw2g6KYKPnUjRyXqTX04AH0ar3pWmzEQcWhNR
J0dOYjmz2QDdlDrR+avITDuVdQH53aLIAuhzqIKPFIKprlejhbMfepXfiueoaDz56kT9ixzAU4E6q1xy
gqfkchFzCqjgLPcWMFQWxWmGosqp5XfXKh0BHMVOzED0BKD4kJrnADbPEQDj4Bb0+b3SNAoAb4BO07T3
tbclBJioxLaQLzg0nqfI0qoxVAVH4OfIND1PZatBZf0pHkBReFpsgqa1UlNL+vEff+YCfOZL34Vvf/95
tOrTaM0tYVXQI5RpNSOoAnAJSPV1iZbXdCzqiEvBt519bUjh0zCCgO9pS0Jvuxw0eUYXkQokkFevMAVX
Z1fD+efyQulF6itAPi9dH1KSrAwbLTo1F7xltTn5luwOXEErXy4o/x9HtVSRQCXrHJSB0ACnSw1ZFWlo
bch4Uo/B8RB90g+fDVctEgPA/wSLIJYSCKoqS0OVJ4P9dMOvSuOlaRQACjrAdjKEDODAaI8IttFklIi6
iWm7hL4iWXWit8IHxR+WWAFZOwIq3fS0FRQYmQC9J45+9YXxBfj9v/gn+MLXvwe5fAkCaCXNaCsYaKWp
EUVLPCKWqhoSPnkrDHa1wI6+NAx0yC2tWUddZSKhoAN2WTRkQwlBjg76VVnvtbzFdv5Zw/HQEkaiMiJP
yi+k0nUNdwHA9bXp5AzvSXq+mIAcBQrNqrD2RMspmi+6/EYk6EH0HNRqK9TW+Szd4oOmgGxwmIhzFssq
Gt2JA6oA8Eou66ZKMykA+rWDVP/Rin4yz+ByVopREWD6m3PuBHZKC1L3HGIGFAPgQpwYTcxB0D7+9EX4
xf/8N3D2/ATEUimAzg4IJlNwfO8g3Hd8B5zcPyAAH0efPIWfSyOsKttMBXIOpJUI6JX6lNq4irvJrYGr
d8C1H0cCQnYXogIoYk0UOxEzDlXf/o0QWTthLz9+nQJDKuyhIKClUneim5CoK4iK+RmGsv4BeWC3K5H6
Ww8AOpdGMQIbai8XKwMRnaTPtS01KcjgiyVCij24/b/wz6uvY9x4aSYFIIR+rGCgNkVHoKcbmigtB7Vo
H4oH0M1OQUH6Uen1ArIBESuolGF6wYT3/O7fwLkXJiFOQcRYO9x50274mZcfF40k08mYiPBzvb9oKFk2
oQTVOme2OiJXA9lVvdNx7ld9s7Or9HkRUOGQsPolLQBqrYEBeAuGSPSJRF43wpkb4FTvrh4DsLiaj34/
VeUn4itk7WnLPj5o7MID/PrfXH1/WUss1ZH6LHAmNMm9OcQqPp00Nn5eH2ztJbibTgFISldr/Xl5KFG4
o35UstL0GrsGlCUg8BMbIFegu6sTfv2P/hrOnB+HVFs7FOKd8NOvuAXe++ApaEHfntpFL2SLdX3s+rfb
VdhRww1IXdWbr+Bjyc+WllMuvlkS0W9LguwyqUBOmRKD4jbg/DyxoJLKxNT5VGdG3op6TAUA5RRkU7AA
ca7iA/D3xFFZXILsxITIBggFRGwgJBUZP3YGV25yIFApF4srC0UhUUUwjYoqLqLgI1H/+R/EITpbhGNL
c93PJkfDS3gKXYODzrl+cGhobRd7DfKuixcbcpzmUwDAt77tlOfqE24szb+TdfRlEfDjugCR/25Pw3dO
j6PP/11UCHHIRVrgVXcegl99yx3iRqX+dIaOL7sW9LZ7Ems81xVkZVysQeq/83KfR1mHsOoTQNctTErz
Mp9E4Kdy5enpaXj66adFGzK6QNSE5PDhwyLoyqv31jtLzfuue1LiP8MW7M4WQykBfExpwDP/+Fko4GdT
qW6IFhihdC4FcqlnAip0+pse02tBeoz7BZVi4AYmVAlIhURVNSoUbCwVRX1Bhc5djTi+9tJy9YbD4TOv
6Esk/gi/UfYyl2dTpSkVgJTaW11vakHC68VRKSndEGKVWbwhqA89BQof/saXYHExB7HOLujp6YSfe+0t
wu8rVqpOd1220CT67Xsl8by68YAreP+VykowE1ZYdhIRJc1FBdhIJLLCO6SQxSXL/4Nnn4VPfvKTMIxW
8NZbbxXX95FHHoFv/Mu/wGtf8xrYsXOn4w54P5dX/ql/wjwpSvUYMPkYNhSzWXj205+S5boc2ddmBJIY
2jx/ZhNO9R8/ryYV6fsZ4BYUObMLQV6iSCgQ3AWZO0rh8O+jgvhpVDarVFltrjSxAqgVt6ON7c7U06a2
8uIaVAhTQj/+yWfOQygSgrwRgTfduhf2DnRCsVwBZqurgfRyr19O1mL1G60knKo4FQtZouKaurRdOwc1
s48s/x/8t/8G+/fvh9cg2Ekh0Gv9/f3woQ99CD74wQ/Cb/zGb4hGpcvSiqJE1+UBdU5MWHt3Cq8lc3A4
Jh//tqDtie5uiO/ZI+i6CFyq9RKCosgqIlcPovJtzS0wVIqQgC8Kgehveo32R/ZALkC4Il0BU80XsNQ8
AfoOC0jR0YC8vRoIfKSSzz+8cpxhc8VXACuIowDIctDNpQJG0UhUVOuduziNN0xE9Na/9dAg0Cp6lsW+
rTQMhsoJs+h/1Q951ZcVX13lbZeLnF+psNtC2QBSAMJv15bsWkmIRX3m05+Gp596Ct75znfCwsKCaP1F
QvGUe++9F9797nfD5z//eXjd61+/fHLRKsafX5fWX5X1q9+NKDsVBPUeOyYyNksISCsiW4WLfUgZEHhz
OVkefIXCwUPaEojIFQqgYjORddBsQQuVyCJ+VvvAwNsnn3jCVwBbRez6iaX6+6p6cbbYIjgYDkGuZEEm
WxDFHx3pJOzqb4NC2ZQKwHBTdgbTZiU1t8AKNKDebbLi2V7DRDOzXSNoCNpPLsDlGADRfwI7Uf/+gQER
M3juuedqgoCkBCgGQPu88lWvqplZ6RbVXIYBKDdBVEKqRqBhdNPi7e0QIR8dAbnjvvsgjJ8DqoxXdPKB
9bMxw7vFY+dR2Zz/6EdhFrfRzs5bbvu1XzMyZ85sybKAplMAsMq9VE9014BElntS4w5TpIGT6BJQ1R41
53T6xwHUbNWRPAfWz2MlZrD8LZsl0u81BAOgakBiANTcczUGQGCcnJyEp9D633///QL8bP1ZqNaCJmE9
8cQTYpYhlWUv/+xVsgxODEAFAIX/bkK0tRViFMPBz9//jneIKbtV1ULN0EYjhY/XcfQoxDs7Ye4XfxGq
Cwsdu++/P/FcuZzbiIKp9UrzKYB1ikv9JIIDaBFp+i5NtgGH+quScHDpK7kINT+/rR1vjbKZt4/e2Sis
5ucvLS6uqADoeVIS42NjIo1KqdPTp08vo/jMJsg1mBgfFxOwiLLz5+ltxlY4MbeeQAUATarjwGMUz56F
/jvuEFH+cj6/4rW+WkXg/T3oLIlVVPC6xPv7YfDUKXjmq1+NzTz9dNeNb35zzlptxuUmia8A1ilM952V
ZYAtv4f7NwK9m0gBJHGSDEDOnwjAHFrs1RQAAXt2bk5Y+TNnzog0qjfVR889//zzIgA4g8fr7esTCsD9
3LVUKinHjtO4FBOoVkQ5cGp4WJQGs5/PrExnAFd7Wfln1X9ah/3h92w/cgSCX/96aPLxx3sSnZ3n7QYq
gO6DBxtyHF8BrFcMcBaf8DqUempopTTgMr2w2t24AVPv1ypcGyFnBcqy2smpKTe9VkeoVmBhfl5QfAI5
WXtvmo8UxYULF2B0dBTmUVl4GYLY21pFe7Lvb8oWbZQFEGXBOAj0FOkXaUBNQTssjisBV/kOq32uOIxi
KN5YAqUXyQ2hZVfnz5xJLuL3b6QLsP+Vr2zIcZpSATSSShtaAErNXVE3mLuYhK1C6E5NwOVyhFtYRBdc
tVYgUXZTZQLqlepy3wBaiuws0nEaEa29ObsJ5B6kqdKS4gOe44jo/moTIZT1l0VA8rcwuREoCXf90Y7r
1HxoJeFXI/JnVfMHtPbnhvruItgoJxkZxgZNmlqvNJ8C2IAfgYtV6D41ePKIreIATgxgecxvayaGVhZb
3dAEfkHZp6eFhaeKPtNDb52W58gUUsmkAD4F+ZzmKUrIJaC6gCQej0twSejaUPrfZMW68kmpOgA3CyBb
fVnCHxdtvLiQB8AFvpr9d9W/ATcMsW2HTYi2Yfw6Kx5YXmS2laT5FEBDRZWgcl95cCmmC35DBQeXe7Nb
zx6sLvQNaEYgFdEkUil44fkzIshHabx6CoBiBaQcyAWgLSkAbwyAgoridbWPXANAKo9q1QLquHc5gm6r
WgAnEGjLNmI1Vt95oFF/9fd6xOAT4GNprsZ2EF8BrEsM4aTKFBQ4NQA8AUi6ALbjFji3hrF9bhCvcNNT
UgBEtZ988kk4fMMNdfel75hGUFPFX1dXl9NRiZUFTxCi12gf6r8o+/QFIJcvQgVkk9RV64AEva9dh8FW
fxsMSI0BgHJXaoC7HuFSYN6q1YK4fHir/87NqQBWis5dhRjgRp4d0IsX1OKTOt031Ifb21MB0D1ODIBW
Bo5G45BMpuDxb30L7rvvJdDT27MsgEeUnlwFWoJ8eHhYBAUzmYzDAohJkIKg13p6esQcC+qQfOHCC2AG
IqIl+NragdnOeoS06IfFi5Vo4Ld1F4Abd2gWez0XRZ9DwAuR2JoLsJWlORVAA4Xpp3AFFQuQG08wS3cJ
YPvRfxLOAlAhEK3Zl2xNw9TYRfi7T/wt/Nu3v112V1LFNiRiFmA8LoDc19cngnxUE1CuyglTEVIASP0H
BgagD5UEgfeRRx6FWKoddu3ZS5PqV00AiHNSeTiL3QCb3W/b2aFemq5h0gglsonSdApgrWXAaz+a7TTj
ZIsvt7VU32k+sy2hL4V7JkQR1LF4ArdJdAVa4dvfeky8/sY3vUnQebL05BbRRCCi9d3d3WKtv0UEv+z3
L4NlpDBof8oSXLp0CZ7+wWkYGtkJx0/ukj0awF6WNqx3TqAsv6kW96AqTb2QiK0zMzPH+l+2Icjargmv
K+B1AWzfBbjORQWaTBUD0DpCCaAbGvqdCkF+71a/M1YQWqaLrD+V7BK9jyRSqPxM+NZj3xTLiN/z4vvg
+IkTwrKTAiCwDyHFX1xcFP4/TanmdRhIGWRQKdBEoVRLG+w/fASGd+xAV6BFuA+ytGJ1hemskeikY7kc
2GUANVN2VXquYVZb9/89n7MdmEGTKoDG/TA2xwC0NCBZf6cmQNUDu4pBvW/r3xvLhKPnNCOytbVNRO6p
HJjao8VbgjA1PQt//eEPw5cefhj27N0rintEX0XRoNNwGqvQqsK0ChOVTydSLdDXPwC79+2HXbt3I1vo
EYFBulJrWXRElgqbMvqvFma1PBbZncMP0lprNQDrlWXgV5+zlrUMtoI0nwJo9G9CDNCUroAEueFYf1YC
TAU4UwCwPQmATHUaog6gFf3/rq4eyCwuCcovvlsCrbZZhem5eRj7yleRxj8iZk9ywU82lxfWv4JgjaOV
p7UWuhDww8Oj6PPvQ6YwikqlXczJXzN2HAPPtQB6UxBwMwBcHKRmA4rnGhEItN2GIbYWbAReMGWLK4Hm
UwANlhoGwNQfZN2foTMAx/Q3JPmwqUKLayRbUtDTKwN7VIVHZbxiijCt4RegRhvxmvRcMBqCFnwuhQCn
i0FWvr29A/oGBhH4I4IFtKXbhNsgMbNGC6pov5MFMGubjNqadfa+T37KOsXDAJzP2QbgJ2kyBSCh19Aw
oCWX3aphAFoMQD5envvfjgyAhUpzwugGtHd0Or0Sad1AqgosFPIiHShz/ZLycCfgEKUPaS2FZBLa2tqR
QXRDV08PtKEiSCSSAvwcL1kzfba5HZiMxYj1AUUnZpcB2MotEL8PuwBO15Z1/hLsZngYgNNGbItLkykA
gCvtB7AWWdawwqH6nPKz3dJgbZftKuL70IpI8QR0dndDCF2CJNL5uZkZEeyTSqAso+CGXFJMLKKC+xPt
p9hBGq19S2urAD69JoJ+ihpdiYq2VQMQ03KnBcvOvW6jV70QyFbU32iUEvDUG+ifw5+1laX5FICQBsIP
LY1p2Q7NNwydCagyVqNGH2xr6y+EA5yUEoxRR5+QyAgQpacFVMgtIAVAlpi6CAvLT/P8cR+51HpC/E2x
BFH/rwH/igNnNvv9smU3BSTNUlEuDqJe16Pzhk7ZYf2/RW0Fonb+24D+kzSXAmg48mh9OEk9WQEEFOUX
isAAZdUMJwuwYadyrcUtppcMQLkBrWjZqTuSSct0qVRcSCzLJZcRC6nl0d0uvUzK7Kub7sxBP1oXoFIV
qwBX8gWoFgvL6LkQck20OgD5Fa7y11BKZSUXYNVGJltEmksBQAMjAHzPEOszucyUab6aCefcY/YyBXD9
iaH6BCDIw+wSuWmPgFqVxymFsvi3WOfvIWi/KZdwp9WB0f0oZ5dEv35+3aHo9GnEzPQMgGr6elVC79ep
v+73bwPwkxjbIVfZCBm+6123IFV/T09P6+t/+9+/Am7cM6wqxq7sOH29PbCUr8CL3vgbMJs3YXj3Tvi9
d/0YMMiJ8jo5f6PW8rvVgNe/eC/rhn1n8vnLJdH4M3/xAmRPPwvZ556F4f17oPzQ38PoK18JkfZ2ZwKS
aPet1gmUTzQuCEgtwUF9DrUez/3wh/DYn/95tfWee34kGA5/sZFuwes+8YmGHKfpGICQRoYAbDlnHdS0
VZkNkJmAAFcDsiIA2NYzAdcjG2VmRO6/qoqA0AWwaMGSfA5dgJLcwVJrBmqlwOD11dcZBHTovl7+6/Ql
2NoGtjkVQAPFrVfnoJJbCOTUmmuVgNt1JuBWE1qqnFb4DYo1wINAaypT119aYiyfQzegUhar8tqeIKCY
z6C5ABsVBPQrAbeqNLwSkBcEsYX/H7BcBgAGFwBpU4OblAFcrQRFDYFUq1zvT8BayuYhkyvC/GIWsguL
MDU2AbPnz8L88+dgcWwa7t1bhGN0AM9kIIP9dp4WDLAhacDtEgNoKgXAWfmGaQFVsGIqBiBcgIBkAAFD
BpwCHAS83lKBDRVDgBwMUA1B5BJkpXIFFjN5yOaLsIDb6bkMTM0v4eMcWvqymFZcKpWhhHTfLmTBWpiG
KiqEarkkWoOTLMsC0A/hzQQ0oBS4bhZgC7YB90pTKQAhGzAXwDTlYpGCAdhqbUFxM9sqK2C4CkDJ9Z0R
uIyoakmy7jQohlJAEBdLFZhbysL49AJMzS3BIlr5bK6Elr4g1l1k5eANsMZCQTBpUPcgMvDcdVWz/jUK
gC11A3r12aspAN8FuJ5F8QnFANjvt9XNGXBSgu4sQEOjAM2kAAiqwaAsBxbr9qFlLCDYp9Gaz+CYns/g
NguzCxlh2Xl6Lwm7ANHICreqzWsCWLIzMNQu/VYToAPFyizVJlzvC+CtDfB8htzYNasEe+m/XwrchCJ/
f/lDB1So31CzgLgwyLb1GABPF93Ms9444VQoBeg43lGuVNGiL8LcQhYmcDs+tQAzCHZ6vkSRe9MSCoIC
eiKoV68N6ErXi7Ss7tXJSJ/7BLMAkLUIgWhUpAEFS6PagWIRKtSfoFAQj221wq+t3IQApw1pVeBYDELx
OISodyEdg+YukLLSVzSuMxnItldtBL82UQqLCqmMy6zJeCXSdArAdv5p1NEsJwgo737DBbpj+m2nWajh
BJ4adQ6bK/ydiJ4TiInOLyFlpzE1uwiXJueEpSc/nug8WemgmhxElydE26AX8FfyA1ku4G1RlVX7flLE
tJQZgrSaz0NpfFzUDJSmp8USXpVMRgDfAb1KGertvqlYKMDLg1M1YzIJ4bY2iLa3Q6y3lxYAhWBLC3Dv
f1IsNWwAFcDPfOITxh+9+tVXd+dR5gKPTeXTdI6mdwXldUjTKYBGBwEI/FVahUat/Uf+Z1DR/4CKBdQW
A3E93PYV9t9pWnClYqJ/XoaFpRy8MDELkwh6Ajz9XalajvsjZwMS0JeDfV1syFZdgJ3GH1DjexPYcy+8
AAunT4tVeyu0RiApLASUADQVBKmiIPHbhELL4wLqeGTpaVlxYgyFiQnxmcwQwuk0xFEZJEdGIN7XBway
BSo6UkFGY886viKVTbdS6/WyDHw2UppQATRenOYTxHotl/7TmgEBPQ1ogLsW/TbSACLfHgyIOAdZ+GK5
CjNI5SfnlmBiZkEMSslV1Vx89tsj4eC1PVGHfoOYhVhFoJ7/2MeElSebKRQRUflEAoK4BTERaQW/XxdW
2nWUN1lkKjsuzc/D4jPPCEWX6O+HziNHpLsB0hD8Mm7Lyw68BqHrqRRWtVS6miOsKr4CWK/Y4LoAtvR/
JfDZ9Mud3EDg1ke+9OENx4Uh+j6/mIPZ+QxcnJoT1D5fKENBdQAOBWhyD22J9mi31LWIc1iyGpDbAYs+
ALbMvtCioGUEv8M76Ds1qBWYI3RMVCQUEyDqTwwhh0yjiIPKgUG0NwN4Avc8fCVXRGUrbJrTEI839pw1
aT4F0OCbkoh/VWUBZDzKkDebymvXpAFV9G+rqQDp5nJKzhKLcpAPPz49D+NT8zCHdJ7y8SW0/LpyiITq
WfhrFd20VR0Gtd4iv70qegNSDMDmuEADKv2uVAxtUGWirRRA+AouDF1bKm2uLi2J32QjpfkUQINvUFu0
o9IUgG3UbL05a+eG3EQtUAt4W0TjFzJLIv8+OSNz8FRs4/Q6pAAfrQfgofTXPs9tO1FcGfezRA9CWgrc
qpRxlMDEx6L2fwu0XLmqn5hSpZUKFKenRXwhuIHWn6QJFUDjRawMrBf5swmg9ng2uIpAm3ey2oK3DRcV
tOOGpVUE9vTCkqD0kzOLMD4zD0vZglAEpvLhhR8f2kyuouqmVZ7fSd/YMtrPC4BaBP5iHul+HsxSAWxU
AqQUtgD+r1gMBf4sug9CQVOacYOliRSA4N/qcaNKgWVBiFwiW36EjAYgzAIuCwDD8Qg2PAbg6CBDltfS
jUSR+sWlLMyjVR+bnBOReqqlzxVKsmEnFemQlafh0Hr72oPIdn+fmpV9FNgZ+MLqE9U30dqT5UcFYOYW
wcxnUBEUkLlUtlyhxeXOhsBPUf7Fs2fF39FkcuNPCppKAWyESMSLSkAGOihTb7HJB4f7y4eNvTFdl8Jw
ou+VahWKxSrMLWYQ8POi2o5KbLP5kvMe2i9c14ffBHEKZiylQVUwT+TSTQX2qkP3BfDJ8lfRxy6XhPW3
EPxmfkk8tkWqbOtU4dH1Tqz2OoG/VILZZ58VdQiRVOpanVrzKQBexrtBR3NWo3EZgIKkY/LBowAa9NEK
8CJghJ9fLldEKS357zM4pnHkiiVn5WLaN+QpuNkSteoqjy8tPRfiaIA3K4Lm2wR25evXPCbKXy6CTUqg
mHNcgC3wzWpkJTJPGQQC//T3vid6GkYSq6mKxkvTKYDGi8yNswJwnwXpBgC4HYG5HBiuRhFISs9BxVKp
AjNI6ecWkdZPzwvQUx09zaBjnz+gSlm3rPC6AabpWHVbgZ2BToE9YekV2OVjVyHILTGBMgC+DvQcKpBr
GmOpI96ft97p6OCnAqXQBgf86klzKoBGWj4RA9AYgC0nnMhYlZsJ4P6ATmLqsrUnhlNBR++jFFy+UEQ6
nxHpOcrLZ3J5ManG8feNOrR+K1j5esIVfGStyY9HK26VC2pblMBHei8sulIEcosKjpSFqdpvmRLwQLSf
tjZP9Kn9OCcCtJbCn6sR7bhsC/Qr7/1EAf5iEaa//31RWWhskqJuTgXQQLHUghRuA1At3B+Qt4CzUrDY
rFwJaKh6erp/qbNusVQWZbVE5+eQ3hPoKVLPbcfq+fFbgtavRYR/X5VApyBeISsHRfTLeaEEbIcFlJVl
VzEAke/Ha2BVVTdhBXoCP6jAK7hgZNnonIacBm44SremYlDfT4F/Sln+zWRpzacANgAfNJvNVmk/mRBk
8HPi33ZdAG06MFt3eV42WviSrLhbWILJWVlPT4CnjrdGQPr8wWUTZ7anWMr6k5Un4Fey81DNLuJj8uML
CvSK5gtrX3WCgs7EHxUwZKg7bhiVJcLyIqBrmdRkBsDbrHqewF5VtL+6yeAnuWIFsB1KWevJ0J3vUo82
qBAooA7Ns38oBWhzYxBQnYJEmkBMeaX3ZKjbDdJ6su6cmiM/vqIW1DBUxV2Nld8uFt4jdk2Kz1JlsyUB
+Ep2ASqLc6gA5tEnzonnyeIbSkkYFi+0ablzKZQYCvXMvgwFftNengWwVH3Dmur/r0Cc9C67bep5VYIs
FokQ05EV+IXlR9pP9f2bLZt/BpshDcYQBQHJ4It7D1z6H6D/DDc1V0E/fgn9dgrYzS9lIZMtCAUgCokc
n38LpefWIbYzRdd9bDt+vyly9Sb6/FUEfKWQQSpMvfyXkBrnACoEflP07zdsVWTFbn1NHEUpVW9TD3wu
WpGz5mxt8Ou2Z3LPukU/noj/aC6AZQXy8/Pd9LCUycDcs8+KSUpbAfwkW+Mstqs4hUCWiPgHDQl4kR6k
efGFAiyqOnpqXrmYRapLPrxaMUdYeVo6K2h4Drv9rHxN4Y4DeMsFvdMxxxTLeFE03yzlEfTo5pQKqBzz
YvKOCPKh9Q/ge8QAl0o7HF/fao9tpQRa8Jmh7JJ4jvs1OwqAautVT4aGcQCeZMTHV7ND6fhmtWpkzp9/
d7yr65uTTzwhqnw2K+BXT3wF0AAJIIDp5qZJM9l8Qfju80jrc2jdxRJZqCAI5DTE5I6g0UgGummiW3Yn
qs898mwN8KqYx7LkEt5E603K7yPwq+UiVEkZoFIcbGuFgz07IRKQIKbIPqXJqAGGGOWyXHZMFAFxw03D
QTKdTQQ/c2dbG8RQ2dJMPOIBwikQTQyCWmlG438AoQTU5B1WMAH6vsXizUYo9BVUbp/Dz53H61L3w/H9
hhUMIvkxUfdZwoNAtyGIbKGMF+9SIBDI4YX9e3z+XKPOOfj+97//it7wgQ98oFGffU2ldfTWQbw5b4/H
QofvP3UA+rrarsrSplJJKFUs+LOPfwlKVbL8ISjkS/Dd0y/A6efH4MyFCTFdtliU3W/oVwyrdlcBLQO4
nfFvO/X4pqTzqiqPtiZNyKkgUGlL4C4rkJeKYiueq8iteFwtiffcP9wH73rgfrjlwAE4smsXjHZ1wUh3
N4zgdqi9HQbSaRhsbYX+VAr6EwkYoJFMwmCqdvS3pcUCpJ14jMq5c1BaXJTXmuoiqI2XagJiNCgW4Lyb
laAl1ot3ng9ScBfPNRyLtUbS6ZtC8fjtOE6FvSOROBVJJk9FWlpui7a03Bptbb0Fx0kcN+O4FZ9/Cb7+
QKy19TXlfP6pfa973dl1nbgSnwGsQ+gGojz8d5+7iCA3IBamGXMBYemNoDufXvdDt7u4lN5UK/JWJKVX
1XuWet5Wa/bpDKAeMyBXyQ4E4eWnboFENOrQ8wjVwiNIRdcdtPwOaAFEXGClhTdoDn7/yZMQzedhemxM
Pqnm7BuqFdlGiDg30d4sCDYqGV6dOITn2Iuj2NsLCFzBYuofwF2jwFAtyGgyUAhZTJBagVE8RHYYGkl0
df0m7vmFRpy3rwDWK/jjMr0XFt62axHf4PlHmy4qf28SbWdLL5RARS7P5YBdAt7SJ/HYqt4fXJdB+s1B
6Orugo6hQSghdS+i1S5S6y6x/HgMIkjpyR0QZc2qdx8vEOIttgkT7Z+agov//M/CbaASXG7YQe2+OAbQ
UB+MjyXcu6D4HJkdQneFnl5ago5CAeI33AABVGze24IfM/B50GrKQV5ZGVlNQCmE6WeeGWzUqfsKwJc1
C1t/AnwVwV+hIB5RearkYxagTdW1tYCg/N+uTWPaKqIfDIu2XeceegguPfoo5GZmoEDzG2imIjUeAZAz
FcH13Tm/7oAHZOutIPncqDxoXwK/6ATM/f/Y+m9QJSAzAO5EbCmXoIqKqPD978PCc8/hSYVFYLKqnT8n
LJ3vo5rGENOh7xFS3z+BLlG0vx9KocbN024yBWAoy9Ogwzlz1GH1Adp2Owvd1CKCjwqAAnhFit4XBBsQ
Fp99YNDSgCyrXXQjAGc/8xkoffc7wC0vOZ9O79LX1+E7n4m8Hs3nTxSAAZl3p95/ZDkD3A+Btw1kAbLs
Q1MA4mRkapdahPGyZCKgiYO/k/cWqTd/sar2paNGEwnInD4NC04TyvVLkwUB4fZ4LHj4/lMHoa97/UHA
YsWEKt68IRX8DaqtM7RMlZ6xErLdooBisQ6ZvyerXxHBvYIM+pELwGk+sFQ3HnttSk+BcP/CNLQsLdRY
pNBlBlt5HvrzRJ2pAWhAC/oFGKCNVACc99eO5cw5IFEKh++1gGcEta1gOOAqN35s8Ot4fSukTPr7T5/4
d//uf67/5H0FcMXH8SoAEwKiGaZY1MKQE3Jqh+wRwO3AVOnKtsM/KP+d+ueT3y8j+qoFFzfjvFrBi1PF
K3JgflKu6Avuza+DI6Rt9eeDhnvtCfjUppsCaDr4DU/kv9EMALTzZobB2Qc9+MjPM/DrKQPDc+yA+o4U
B8kGAmbXyZO/d/jNb/5GI879+igsX6u4OZvNPIttKcKmaxkAp7CHg3rrlKfiafjh0E5J4ZXfH/aMGiWA
gAojqEMUGKNW3zgoAEhBsrD621ECpBQUEBsNfpYat0I95s8mF4Qi+XRuIdyG1ZbOnb5DmL4LuApNVwpO
bANHHh8nDx78SqK7+3836rybiwEA3B6LBhQD6FgfA/hbZABlZAC2IVyAoKzvkRbfOwA0BrBN6wBUcI8s
vllVDIB8f9N0CoHWIxQwm0ym4UBmBuKVsgB4QAXDGAwC/CqoJ/x6tTwX5/cF4MnSqyh6PdA7BUAbkAUw
PFvH79NShAHPtiY96XHt+QzpWhD1N3t6FnpPnnwn7vvsvle/uiGn3nQKIB5hF6B93S5AARVAVbkAAeUG
BPRhaCvZOjEArRpoGwkvwEmVjSL9R2lASv15l+Jah+TxMNmePtg9eRGieEyhBMDjC5M1VYE9LuoJqHSZ
wRF/jXYvC/yRbFAWQG48ykb7bEPVIwRYIXgVFICKo7hxhJBaUDWbSFT67rjjvYmWlr+ldOv+17ymIafd
ZFmABovkxc2RBdCtPD92siCN+3LfrxjQdug43PfUtyCuCn9MLd8vYKIBSa/Dr0fta0p+N7r+2jCca+Gc
ixYgNPh7ELNRRU7cP8DLogxF++m5bChk99x2239NdXX9z0auC0jiK4B1yfVS37cW0TSaw2Zsz+uNEAMe
CSagY98RuPn09yBOVh5k41Xx6aacJegs/KFZWfHuawn4uqfvUUD1XuN0qXbOIosi1jOQ+4m24LjfIo62
W275aMfo6G8i+BuLfvAVwPrlctb/umEAsqbZcL6XUfudGod/ge1/bumD3t452DV5CUJUwWcYkgkQSKgn
IFFjspLkCrDl5Cq/rST6+aiYBrMAsDiuUhWlw+L7KWVG1D9LlYz79z/dvW/fL+Hr2Y3oBdGECqCxF3Et
+Pfqgu0o7neQ5l9vu7UR36toWvD5XUfhTYvz0FEuinJYUQJMn0flwGphT5vr7wFqm4VsNUWgxJ05absN
UWnVYeppaLh9IMnYVzo7s8PHjr0Hv9d58f024Ds1nwJo2N3q0rnmYAC1Pr+hfS9jjTU/a/4ckECZQEx8
8dhd8MC/fA6oUz6lzIgDC7pcLosOPwYBSMUERBR9C821rxH287lEmM5bWX4atnJlxHRxfG0pErF6b7nl
tyKx2GdJOWxUJ67mUwBCGonG7Y7stYpj/508puF5rXEiiTJlHZ4Kp2Do6O1w05NfF7MF6Yatss+MSsDU
5gZQRkCU3QYCNcG3TRVNoTnDksuoC/CTIlNMhovH5vC1tpMnP9La1/dBUy0JvlFNYppTATQa/03BAID7
m7pxAM/rjf08FRW3bHi0ew/0DFyCHRMXIBKJOD60aC6imADRZltlDWxVh7/lRDEA4DgGDXpOnT/5/Zli
EUL79j3dtWfP+1BBFDb6lJpOATTaVjVLDIDEjf2pOABszPdSy4ES9sXMggI++Mqx+6Dtix+FzmoJIuGw
cAUqHDknIIlzk66AiLArZSBks5SB1rPAbYkmy6mF30/nrqYAh3CUEPylzs7M8E03/QIqinO2tfHLmzVL
IVCgZfjEEN4JL4pFAofuv/0g9PessxLw41+GYqkKVctukkpAeTPTTcu9AEy1KAf3OGycqFJa6qQUDEMw
FIZSKAbFgREYOvM9iKk58jXRdK0nn14PsBFlv2sS7d6yVdpSdk9Sfj8H/fC7UJaDrutcMGj13nnnryfa
2v63eH0V2f/a1zbkNK9HBqBjjOdYhCvZ6dZgoiPW2K98Pdj1tYrH3hve5xqcXdH6DLI7cDrZA33H74Eb
v/1FaEkmhdWkT6XGG6BSg+wGuBWXtcU411KcfghKcVrK+osVjbiYiQbuO4OuTPrUqb9p6ev7Q9E16Bqd
7/WgAHSDynMpeP4IAh5owbVEaWl8JBZOpOWfvqxH3KYcG3mTLu8uTPLYyI3QOXEedk5eEL3/OHXGQTVy
A4g4BxQbcOIB11IJeComuU+gWLWY6D+dkypjJr9/PpMhv/+Z7n37fhm/Q/7anKSU7agA+FfUZ1HS96gB
PA5aYJ2ay7biSFfzczdY6cFO8c5GGiu97/R1HgSUgUDD870M9/VGCVfLEH4sTrNKMJXw8x65+WXQ+rm/
gF4EUzgs192tKstqK2rNBTVOPOAag1+P+Is4BbczU6lKAn8YlUA+l4NiRwf5/T+PZ/i8tUHR/pVkO8QA
vBPCaKYoAZ0AjhYdCNS08MIADvTzYQeOXTj24Nirxu5gNLUnnOweTbWmW2gyUKNiABWTegI2QUMQZYlp
8o+cEagmA9GSXZ7efOsWNWlK9sijKbXU2CPszPDLB8JQ6B+CgdNPQpym/apKQc6z633/auIBABvLAnTw
03kw+JXvTzULoCYu0VRgquufxr167rrrfej3/x/zMn6/LtfzZCDdh+cp0kzpo+BaeKoNIQufVlt+nFav
pdR+NCK2Ve3EXyK2ASHrpmIA7vdwG5s0/Ktp18zWrL94LPg9wHPJXug5fg8ce/xL0Nbe7ry1qpqGOkFB
8EzP3WBXwF5BCQjwq9mKFMCk+QyT+Tykb7vtb9N9fX/E+f5rLZutAHR7yIBnHz4KLuDJ2hOQdaC3qsEK
gPeh/SPqvW6fBdtO2BvSAGW7I3ut4hYCLE8AbkwhkAQ++f+mCgbq/hbAt4aPQNfkeYhMvgDJ1lb1VkM0
4RSuAMUAeLYgwMbGAzS/n5mIIXooqslLdA5s/fGzZxYXIYh+f9fevb+C4M9v1mpQ19oF0KPzDHSm9Axs
ovQ94FL6nTh2g6Ly2nYHjlEc1CK5D0cXjjaQlj+pjsmxgUAo1hqOtPQlU63t0YalAYvoAlTt5mgJBoaq
XZeRbLEIiOgFqPzaBt+/cv68dAEoFRgKRsRWTv2VgKY2YjM9IzB47ilIoJKI0LoC8s3uvIA6LKDhqcF6
fr+y/gZRfwCnZwH5/dlMBhbb2hYG77jjbYFA4FtXcx82Kg14LRSA14dnq05AZcD3ggT8CCz34feov3eo
1/vV/vQ+Bryg+QA1nZVqcCYUQGt/QigAigH0rl8B0KIgFbHsVzPEAEDGABBo5PvzEIuArKcf4Coim3pQ
f/wIGCEEf5CafQRrAno5WpmpdxAGTj8hSoVpdqBD9dWUW3vZj9D4eIDgJTrweeB5iJZgSgFUikWYrFat
XvL70+m/4nqAKx1bOQag3+I6pSeAxsGl9EzhWREwnWffXqf0UfV+p+mr53PW/Es2OFzVVOIyGJfFbKge
0+rnnTgAaGxb/ZY/SPRA99E74cR3vwadXV1y+jAJWV+abktZADVHwNaZQSNcAc/58TDUa4ZqUhpQ5zCF
1j99662fbO3t/R/XMt+/kjRKASwrvAHXj+eIvR6ka9Me0/MctIur/WPgdnquZ9Gv/qr5QcCrF+f7bAz8
be2BiALYbjBNLrKhXBCmVlqG8NGBG6FrZgwiMxehta3NsfAisq467/BEIfE5jZg05PH7RYxBKYCASvdx
vp/cw4nZWTAo379//3vtajW3vqvVGGmEAmDAc9COc/BsyRn4BPp2cK09U/cYuAE7HfAk24AwXw/IXqtc
Tqtd2bWwlz2ofY3XALRsOXvOVCW1Ac4IAGPQhgJuv3j4Xmj90v+BaKEAsURCBgDpZSpf1ubhG2oeA6xn
0pA32q/O1+AtWXzVn5AqFhfm5yHX0bEwfNNN/x7fdIaCg1tB1qMA2KcnEBOg29ToABfwOs3nLVt59tn1
DsjXCPANBG1TMQDN8utM4HLfkWuFbPfPlXa1tX9sg4NqcljCstpypSDDTREyCxhHO/LVW34cXva1j0M/
tQmnbkHitA2RhrNseQwdvFc1aahOnb9o4wUK/KrMl0t9S7kcTJum1XfLLb+FiukL1U1K+dWTq1UAhnov
AZoi8BSJpyAeRe8pOKfn4r1pObby18SN3Cjhk14L/pel0LepeMoAnOf07YpvrPOnXedJnRVYKu9PoEX8
OEE18YKhuQiaK/BEuAe6D70Ibv/Bo9Dd2yviAaQATPb5QQGfA2pX6QKw38+uhgh4GVqPQkX9KR05vrhI
+f5PtPT2/nF1C/j9ulyNAmDQEqgJ7BShPwAySk8VeUT5vbRet/IAmwr6RocBtzusr0SWqzJDd9jX8G73
D3v5c/pLhE2LqLSk/gL8JllsNcC1/M4AW+iGh7tvgJ455AML45Du6BA3oLDKCEZiD6YGQHmMK3AF9O+p
KQGOdgP3+leMYGxmBoy9e59Rff2uaZ3/WmQ9DIDATWAnBkDpuVGQ9J/A713laOuoPD8IuC6pW8XgpTde
a+75y+v7L3s76RQZBBDW3zBVBx1Ct6kKgoyAig8YINcsAPU3QAbHZ3bfBe3f/GuIIv2OpVLy3MklUO21
SBFYHA/QSplXTQ+y0mKfn3v44TbI/j9ZfdXaa352FrJtbYsjN930c/jSGYcxbCFZbxCQrgSvDMGKsF4Q
z5frTuRPW3NL296HGuj5DqkHenu5AnAWGGWrb8n59EHDcjSE9AYshwFYSgHQ2y7YEfiHIz8Kb3z872CA
WolFIjKISKdBbIKVAJ/HGl0BvXZE3PBqBSNh/dWcBAr6FbJZmKxU7N577/1/oonEPzW6n3+j5GoVAF0F
dGZgEccYuJafrkM7uCyAZAsqgUaaY1Wc3hSievXUMBwb+L/le0OtUrD1rV1XAdja3wbYKv1HLgCV1CpF
ADI4wOEAS1lwjsexIngUPdS+3bfBjzz/TegdGJANN7WTsVVKUCxDzgHCleICHuBzpaeguvRaMOgsAUbF
PZfm5sjv/3hrT89/F/n+LSpXowD4SlAocx7H8+rvIg7qYUbuAJXlUiqQ3IStpwAahf+10P9t7gJ4LTNw
fw5g628439MbBhD71Vh9W3usbW3PFtxAnWFTvh7fWUWABmgtZur+I5Wu5VEA5BmYtu0oBjrGJ5IH7MGO
cYjNTRvtXV3O1GBTpeEEYAn8CviuUtKUgPbFRDCLKD6XenMnYvL75dWAi1NTlO9/ivL9CP7cWuIjmyXr
YQB0BamYYRKoLFuCP6fGDpDluhwQ9K56vGnS2J/CBt3+rVUXbGXx+udS5E/nAA74+9iOtZXReKPmzbb2
pZcB3Pnb3dcFv2IAiuqLGECAJtaQylEKgBp/0GdbLtj5/OixWcoUzez4Qj43Pv3RYC7bXyiciGazkQRN
GtJdAdyazAy44Ai0E9GYgLD8yr93/H6KIZACMORqPnMI/kxra2bk+PFfwP3PbWXwk6wnBkDfjIBPgCdl
QIwgr/7OqseUHtRdgi3Albf2D7JZ4qXrNc8r5Nq2q+o4/ebs56H1y19zGYB3n1rwa+W+mgUm+h8wpUKQ
ltoSYKenLFEnYNlmcSFv5ScWrcwLU3Z+agasygK+e/5ZgLmvDQycT42NvXEwFjMoHiBEWX1DgZeyA6ZQ
KnIZMu80YgF61cE3yIEHVXZMU3wLmQyMl8tU5/+fItHo57eq36/LeoOAzAQI7PRty+pxBlwlMAwyXSjW
doDNzv37+BdSz9Lbnh1sF/4OxXd9bVlNV0PBl1l7jQnUfZ0fe95va+4FDcsQtINqAcRRDQF/dAsqJoI+
Z2ZemLVzY9N2ER1v21zCnWhQfGpWjZm/Ghv73LHu7kB0cvINfUNDso04fhBH73nF3oCKBbASIDHY32fa
D5I92Gq6Mb2X+vtfmJkhv/+j6d7eD1a3sN+vSyNKgfl3pG+8oLbsDmTUGAWZLqRqQKoP0CfzbG+xNWSs
xvs3WfHUp/a1z7un6v6hA1OuaKOotrC6IKv0bOl/czrOOW4dy+4Cn/c1tPdwpwF3UXCbbhWblgWT04Dt
SrFqFsaWrPz4nJ0fn7ZLiwRwMjYM+jmQsakF9Tfdf2SIyh8OBH7vp+PxA9GZmRs7+/pkdaCaOmwxkEGl
trSW3LKrs3w9wE0+6DxVFSG9/sLEBBh79ny/e9++X7Gq1dyWXJegjjS6RS65BPRjsEtQUH9n1WPdJeAC
oWso3h9ltaLU60NWB77HQqt/dJ3lUHubo+tqAKghfXGXuntYg0b79c/heAE/dtcaCMhhyHllthFEJl+u
WMWpHJQWFq3C1DQ6+ARwAjYBfF4bBHpSBGR8KChdVh9BBqflicnJ2KeHhv7olWNjvxNbWmppSaehopYW
C6iTE9V7KrrPJ1xTsqpnC5RSmJmchKXW1iz6/e/G189tVnOPq5FGTwdezSVgTUwuAWUJtoZLcJ3JZS09
eECqHiwHqHxka68JJYB03JRGUAXgZPCPg28rvR80Wi+tvOH+LebsB6XlN0RqDv35DIJ+rgjF2ZxdzRXA
MsmI0D00p8aC9phpP91fZIRINxHTpHusZhr6QxcvxloHBj77wNjY62OxmBGkeIBdO5PPUEqAr5UT2lTN
PRn81NE3j37/WLFo99xxB+X7P7+VU371ZKNagtEPwHUCrAT4B6QfaifUugRcKrz9ZDXqfw1cgGWHtZc/
7/XF+XENJa8DeH0/nu5qmrZoa18ln9ySUXiT3QAtMOhYdVBgr1EAhgC6JQAvgW+bZcsszZbt/GTZLmeq
YJap26ieXaJ7Z0Ftc+r5Krhl6dxDgoTu65g24tqIfmRsrNDZ3n46Oja2f2B0VPj2lvqOrNkCKrLPMQqn
wSf9qWr+Ceznp6chfcstfy38/i00yWetspE9AelaicVcQf5Q7BLoAULdJeCZgddAGoNGx5eFa5sGtJ1/
WIwaSq/72TUKwXb3q1UA3r+9wOe/bQF2MUgRWLIylyLxTiyA3qSAY2uzB5nWC2XAoK8WqmbuYhmKc1W0
8rR6Bu3M1aVkOOieKaot3UvcXCalHtN906pe4yvi7SnJzWR4iMlof5HLjfeHw/3xmZnWrt5e2c0H1BdX
QOf+gbwikrgWWvkv+f2wa9fT3fv3C7//6n/RzZNr0RSUfsyi2tIPRUqAGQFdNOr7Ry4BaXD6gbZMzcBW
krX58nbt844igBqg0yPrsoC3Xcttc4mtBH6VwG/bDvgl/TeczIBUNArsDq0XtNq2CvNI7WeqdnEWrXzJ
kI0+HSOhD1IA7EbSvUNuOQeQeQo631NcmsAxOVYCIW1wibowMplyOfCRdPpcz9LSDYmWlkCc+gdwcM+y
nEIkvq5OjENR/4WZGVrKqzxy9Ogvi3X8PDUD20WuVVdgr0vATIBp3ShIl4CmERNN27jYQCNN8QbK6oBX
j1fw5eVrXipfm6OvAbz+nFIUbnEP+/kuAxDTcykWoHx/01Zddw2pBATgKXinqL1VmKvY+Qmk9uj9WVU+
K1ONKrgWn/+uas/T0Cfc8QIwDHqnnF8JK4F6W9C28P3Fxfzn2ttfeM34+OjIjh2icafJSsB7zRSroTqA
YqEA5+fmoPOuu/40lko9tB3y/SvJtWwLTtePswS0JVZADICitxTIobgANfxkNhBV59dgRbC56F/tiyyn
9p4/2YrX/K0e2t5tvdy6subggp3EcoBe+7dAl8YAJBUmhmzIYCAC38SfyFLZFLksF4G+VDXz4xUozJh1
qL0O8grUAp0fe4FN24C2rXOl6oqxwmNHPr20NLEnkUjHJiba+oaHRTqQMxxe141XGjo/Pg6RQ4e+0bFj
x2+Z5fLWaO1zlXKt1wXg68kuAfl2zAJIEdA8AnIJSBFQRyEK6lxXdQPMU73PrcXS6/vWt/RroPb8nLLs
JNzV21I7OMU9zn6aklB+v2VTEI/AH0HQmGCVkNrnp8p2ac6EaoGQooPeC3ivlV8Jc165LKCvVMro03zE
ts/1lUqHo3Nz4bbOTuB2XfpJEfgjOC4h+HPt7bO7jh59D16QiUacw2bKZi0Mwi4BUz+KCZASmAI5t4Bc
AlIE1GGIFAG7BdsyPmDXbG0xp96bKr5iwPPz3gKbFai9pdgDA9yh9qC9rjEBt8ZfDmeSjSUNulU1TTM/
W7aWLpagOF21zSLtGALXerNf7wU9++xs6S8H+g2X89ls8ePd3WfeMjOzLxgOB5LptJgsRCdZseWswSiO
iYkJGLPt8sitt/5SKBT6+pUs5bVVZTNXBmI/kOIBdFOwEpgBqQhoUM0AtRqjTkMU9OFswVW5BYaxsXea
l67rf5BvbKi6I7sOBViN2tdSeVYja/PlaxSA2qdGAWgKQZ9QU/ua8P1tq5KvWrmJnJU5l4fibNmu5Hku
tE7XubqKf1+d2jca9Eyo1n2cr01Pz7X39Jz78bGxXSP4Q8VQCVA2wKLqQBzjk5NwKZulOv/f/k+PPfbn
//HFL17nR24NMa60amkDSxw5wEMRXrL6FBQk8BMbIEVAbgH1HdDLidecNoymB+OpoeNdXb1Drb/7ntfB
iaP7RW35lX7/vt4eWMpX4I4HPwAzCznIZgsQCwcgHDIgHJRDrBQktiBWDBKrA6mtqCFRx1oJ8DVbBeJl
Fl4Dd41/r/a1tL9dK78CrV/2mq1SezTBZq6IVj5nFybzdmGmQGV5UOvPeyPw+u9iAaxK768WuN731TvO
as/VOwexfV1///Bdk5O7+9rajBZ0B3J4LZ5Hy79kWdX2Eyf++KPnz//Hf7lwgWJW1U+9+c2bxlpe8Vd/
1ZDjbPbagLqwW8A1AxQgFBM5cEyDVAIcH6DaAV4NaFPjAww+5+9lD7S/mQGA57HnOG4arpYBOJZef66O
pYc6FtydKuv5G9wptYL2V0umlZssWLmxnJ0bK9iVTAnfoNN3Ts/pvrsOfr0d3GqWfrXnV7qCKykQ27NP
vfesBH7+Wyipj4+PzxWGh2dPZTJHYs8/n8iixq729i5Uhob+8neffPJPxjMZp9TvlR/+sLGZSqARspUY
gC58M5Glp4wAZQYI+KQEdoBkBtRvgNKGpAh4XsGKJ+cwgB5kAL/YOAaQydRhAEFDLBNGTIAtvxxGTarY
C3h+blmEXntuLdR+VcB7aT5Z+dJS2cqNF63MxSwU58q2WdALuBj0DHz26Rn8bO31HLxOy73gvNzfKz22
oZZJgPYc1HndO3i/lY6hpxWrJ/r720+m07ujkUj5fKXytU8+88yX8HkK+pFRElWI1wMD2KoKQHyUGlzW
SWCnWIDuFgxCbSfiFeMDG6MAsrCUKdYqAEX/XQUA7iKhPL1cHcsxPQ6wJbiBwQ0aG9Csvh6trwnmWZpV
t/VafQ/lNysWUvuCtfQCUvuJol1cQCtfZYvOoNetfUl7zhvEA8/X0R97gVfvsb6PqT3nBa8372/XeW61
1y73mP/WsxbMRKl8necfZMENYEPkyNu1r137A5e+8yew1WUrKwDnI8Gt96ZsAMcHyB0YUYP+5p4DetrQ
OdlaBfBaVAAH1q8A5qUCiEYCEFGWP6zAT75/KFDr+wcM7QZxAM0Vd/ZyCw+gWXoZSOTedct8eQDVEku+
ia08R+/NSrFq5Sezdn4iZ2cvZe3yEs+U4xueAV+C2hJcHqwMvLl6gJUtbj3wev8Gz3OrgbVeTGEl5aC/
BlD/8wDqH5/jG6z8uN0dzzCsqv19BXANhavBSBEQ0CkgSMAnJsD1A/R33fgAK4Du3qHW33lPgxQAMoDF
JVQAxADwk1wFwEMqAlk77laK6q2odWrv5OU91l4P9LkTb2pfMz203zJNovZFqzCdt7MXl+zCVAaqBbqB
GcQM6CK4YM+rx3lYrgD0VF49On2l1tnLCLwAhTrvW+1vfl89peT9W99ff817jvWyGPpn+ApgE2Sl+ACz
AVIE5BYQUyBFINyCaPtwMjV4vLOnZ6D19/7DG+DYkb1QrZrL8vGXE68CmF8sKAWgGIACfkBTAoKKGOD0
kSdZ5suDS/V1l0D66cupPSuAGmpfLZtWcb5gZS9l7Px4xi7N5ymqBy64icryRCwePNuuoA22ejzJpl7B
jhd4KwGtHiDrAb0eWFd7zftcvffBKq97ZbXP956nI74C2DzR68IpNUigp5jAKCyvH4jGOkbbkv03dnV0
Dba++60vgVf96CmoIgOQLGDt8zi8CmAOFUAk6CoAov20JYsfdOi/4ab/aui/qwSWF+K4gLfZlwfXr2cl
US1ny3aOqP1kzsqNL0Elw8Bl2kqA5045FMDiZho8GYv381J8rnJZLbC2FrCtBYgrPfa+xysr7Xu551ba
xxueuex7fQWwuaLHB8jaE/2n7ADHB9z6ASPQEghF4/0H7h7evXNv20vuvhledtcRBHSnA8i1SD0F4IJf
Wf0guP3jdAagHcdJ2YEnQKcUgVOea3movWVSbj5v5ZnaT2bJ9IPrr3JjVrL23DSD06mz4LIALsDilJ7j
18Lq4F7Ngq709xXyrDW/52qO21DxFcDWEE5BERug+QOkCDhtSIyAmIGID8QS6fZ4z/7uYPfRvhv39hs/
9YYXwa1H90EwFJRLT11G6ikAAntQKYCQQ//d6P8y8APU+PUulWeQ245bQI/NSoG64xTs7FjGzuEo44fa
FgfteFIVDW+LLO6PR88T8MnycyMNBvyVgHqtQu9rRIXelhdfAWwtqRcfIFdAVwQ0vyAd69zVl9xx52hX
e3v4X7/8BLzyJSegJZVQ389YMThYTwFwfp8ZAFf+BTXw1+T/GfiWpgB0mm9atoXU3spNILUfy1j5qTxU
8/WoPdN77oc3q7bcG4/bsOnRa70cF6B+7UTTAHi94iuArSfsFlB8gNKGK8YHQvH2rvTuu3aHWwbS95zY
BW95+S1wcM8QhCNhxx/3ykoKgET3+wN69B+3tnZv1Pj5iv5bZtUyCzN58uWFlS9M59HKc3qOqT03wtS7
3/JgK8/0Xo/4Cz8+dOCt4hsJdBvyswNqgY2aFbHU99b38zIY/i7O39r7nH2NWkVqaB9i80Ftft49BM/Z
8H6mVyMZYLgnrI6pfw/5EYZ73QHqqjuZlfF8KfcrqNfc46xcbrb9FMBWKgVulLB149QVAYFAwRaSZhuK
jEG1ML8499RnFlNDx3f+U7U0/L3nxoIP3HkIXn7PjbBjuFcs9iD6w69RR8qAnVpowrYV+Jfzf67GM8vZ
kk0FOdmLWciNZe1qrqzKbvX8M5/7PLi+PBelMOg5mMcFO06NfvDgW23wANsXX1iuRwWgCwOBqTNZUAKR
M+3Ytq3BzAvfWizOnp2sDp3Y+b9ml7oe/uZzgZffdRjuvmUf7BzpRfDQUlABZZ1WZ0BO6S2wtbAdK4S8
3rTLmZKdG8/auUsZBH8JTNFJUu+BpwfxmN7TXAgGPkfxc+AW6DjUPnTwrapr9cpujC++sFzvCoCEUMB9
CQkonA8nMJEioPru0Up+bmHh9BdmIi19/Wcyx0b/cGKh45Nf/J5x65FRuO82VARDPdDV2YqsIOBQVG3t
iBU+mPJ0JWqUkbPz4zmgKrzSQgHcqDu3R+MeiXrkXu91zxSf8/UMepfa+4D35SqkGRSAkME732Vd+uoH
2SemLUfNiRFMqzFSzkwslp/9R1IEvaWZfX0XLo23fe4bp6M7+tJwdP8QHD0wAidvOgjxWATSqSgsLBU8
FB8NMIG8OJ23idYj6GWL65rSUgY9W3kGPfv2TO+5aIeLcxxLH1T+vE/tfVmPNI0CINlx97vs3kTVnsyH
Sue+/EG2wOxjE8UWbADHMCqCJRyzgXAsXUgPt89fHEk/8f3ORCyRihzavzNYKZflIhEk1ULFLi8UKHiH
vvySXVosgm3yxBrd0utLWHnTdby4BSkmPXLvNNLwLb0vjZamUgC6DN31LvPiVz7IkXICJ4GvJj6AY9Cq
FHsLM88t4YgagWAon+iIPXqmNRKOp6OWEQ7A4nTeLEwtQSXL1J4tvb4Wgp6j11e24VSdTu1rgnihg//G
1len8cWXRsr1mAa8GtHrBzhtyIVE3JuQ1y0gESEAcAOMHMTTK/J08LNvrxfkePPzemGOL9tUths78xVA
rfD8Ap52TIVEVEHIcwq8CoCtvXcqLWcduOEpR/bZl1+pKMeXbS6+Atj+wmXF3H+AgN+iHrPLxKDVp4rq
jTS8ra/1STbejjS+XEfiK4DrR7j/APcg4EVKSPSJMroV9y5q4R2+XOey3RRA0wYB1yD0S+rpOxKvAvDu
v9JrvviyJcVXAJcXtt4rZdz9iTP/f3t3bAMADMMw7P+v80IzNiKPEODJfGs9AYA7no81gHsEAMIEAMIE
AMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIE
AMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIE
AMIEAMIEAMIEAMIGZefFHr8PQOIAAAAASUVORK5CYIIoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJyIfAD4wIwAnFAgACgIAAAoFAwADAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAA4NDEACwkHAFNLRgCXh3wBXjkhAUQkDwE3GgoAHw0DAAQAAAAAAAAA
AAAIAAgISQANDXAAAAAAAAAAAAAAAAAAAgICAAEBAQE6NDECUEM2CjEdDwsrGhEEVDUiAkwsGQEkEwkB
FAoFAQ0JLgEWFZMBFxejAA0NhwAXF6wAAAAAACUiIAELCQcKT0hDN4V2a4RTMhyMPyEOXTYbCzAiEAYZ
CQQCEwYEBBAFBBYOCgpXCg8PjgILC5oADw+bAAAAAAIFBQUdAgEBaE1IRLutoJfvbEgy9F07JulXNB7S
QiUUtR0OBqMOBwSQCQYkghMTg3kVFZ0dCwuRARMTowAAAAALAQEBWgEBAadMR0TRsqae9nJQOvpoRzT6
Z0Yy+ls8Kvg3Ihf2NSAd7CMYZt4XFqTlEhKlfQwMmg4UFKIBAAAAAgoKCBEJBgUrfnZwgbmtpPB5Vj77
b044/G9OOPxiRTL7Pisi+y8iTPoZFpb6FhWn+BAQpdoKCpxUDg6XBgAAAABwamYBWEs/BLiso1rBtazs
jW9X+4JjTPx8XET8cVM8/FM9M/wtJF/7FhWR+xYWp/kQEKLTFRWccR4enQ0AAAAAnJONAXlpXAO8sKhY
ysC57Luol/q5qJj7sJuK/KGLd/yOdmL8cV1Z+0A6hvs1NbH3LS2tkyMjnRQrK6MCAAAAAMK4sQCVhHUC
vrOqV87Gv+rRxbn62dDG+9nPxvvOxbz8qqKa/LSqpvuSjr36iYjP9nl5yYxUVLIKcnLBAQAAAADCuK8A
qpaJAr+zqlTRycPo2tDG+OXf2Prn4tv62NTQ+7Gwr/vFwsT6qafR+pGQzvN/fcF/Y2GtB4OBxAEAAAAA
vK+jALWrnQGzpJYvx721nsi8scPNwbfYzMO76sG8t/PFw8P21dHQ+crG1vi0sdDro5q1Y4p7jwOpobwA
AAAAAMO5sQCikH8Am4d3A6ydkBGzpJcesKKWMp+alVqem5l7s62pjcS6sq3LwLjHzMG7ncSzrC26p6MB
zL63AAAAAAC8r6QAtaueALmsnwDPyMMBw7iuAci+tQGtqKADlZKPBp+UiQquoJIUuKqgIbuurRKbg4MC
ua+0AIqFtgAAAAAAAAAAAAAAAACUgG4AqpqMALSkmACxo5cAopyXAaKfnAG5tbMBy8O9Ac/EvQHRxsAB
ybq0ALehlwDNv7cAAAAAAAAAAAAAAAAAAAAAAAAAAAATExIAYF9fAH59dgCAfnwAl4p9AKucjQC6q58A
v7KrAKOFdgDOxcAAAAAAAP/////x////wAf//4AD//8AAf//AAD//wAA//+AAP//gAD//8AA///AAP//
wAH//+AB///wA////gf///////8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIREAAODg4A
CgYEAAQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjHhsA
GBMPAEQ3LwBpU0QBQB8JASAMAAAKAwAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAA
CwoIAAkHBgBMQz0BaWViAj02MAUjEggFLhgJAz4fCwEwFgYBIg8DABsLAgAMBAAAAQAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAICFAAICDoAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAABAQEAEg8NAiMdGQs/NS40UUA0YjIYB14cDAFADQYCHw4IBQsvGxADTSoUAUAfCwEuFgUB
DAQAAQEAAAEAAAABAAAAAQAAAQEAAAcBDg5cARoakwATE3sAGxuXAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAQoJBwcKCAcjS0I7bZuTjcSfjYDpWzEV6UwmDtU+HgqvLxYGfiEPBEocDAQk
EgkDFAwGAw0HAwELBQIACgMBAAkBAAAIAAAABwEBCwYICDgGEhJyAxUVkgAXF58AGRmjAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAZAgICUwUEAp1uZF7b0M7N97mqn/tqQCT7Yz0l+mA6I/dbNBzw
UiwU30UiDsExGAihGw0DhwcCAHsBAABzAAAAbAEAAGcBAAFiAAAHXQsLSl8WFoI1ERF/BRcXnAANDYoA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAANQAAAIYBAQG9BQMC0HBmYOnU0tH7uquh/GtDKfxmRC/8
ZkQx+2VDL/tlQSv6Yz0l+lw1HvdJKBTwJxMH6RcLA+EMBQHTBgMBvAMBA6gEBCa3FxeN3x0dq7QZGaQq
FhahAxQUnQAPD6UAAAAAAAAAAAAAAAAAAAAACAAAAEwAAAClAAAAyAEBAc4FAwLScWdh6tTS0vu7rKL9
bUUr/WhGMv1oRzT9aEc0/WhHNP1nRjP8ZkUx/Fk6KPs4Ixb7MR0Q+jAaDfY7Hw/kNBsfvhgTf8wbG671
Gxux7xgYrJIUFKAXDw+YAhYWjAAJCZQAAAAAAAAAAAAAAAAKAAAATgAAAIkAAACrAQEBvwUDAstyaGLo
1dPT+7ytov1wRyz9bEkz/WtKNv1sSjb9a0s3/WxKN/1qSTb9XD8u/DsoHfw2JBn8OCUa/FE0Kvw+KFz7
GRaf+hgXqfwXF6r6FBSq5RERpWwPD5kLDQ2gAQ0NkwABAZcAAAAAAAAAAAAAAAAGAAAAEQAAACUDAwJD
CgcEa4Z8c8bW1dT6vK2i/XJKLf1uTDX9bk04/W5NOP1uTTj9bk45/W1NOP1dQS/9PCof/TgnHf08KiH9
QS5O/RsWlfwWFaf8GBiq/RcXqvwUFKn5Dg6k0w0NnUcZGZQFERGXAC4upAAAAAAAAAAAAAAAAAAAAAAB
AgEAAT46NwNIMyMPsKKYl9nX1ve+r6T8dk0w/XNQOP5yUTr9c1E6/nNRO/1zUjv+clE6/V9EMf0/LSD9
OSgf/TQlNf0bFX/9EhKk/RcXqf0YGKr9Fxeq/BYWqfwQEKb1BweesgwMlioMDJQCAQGXAAAAAAAAAAAA
AAAAAAAAAAAAAAAAZmBaAW1NNgq1p5yT2dfW976vpPx6UjP9d1Q6/XdVPf12Vj39d1Y9/XdWPf12VTz9
Zko0/UczJf09LCX9KyJh/RIRlP0REZ/9FBSn/RgYqv0YGKr8ExOo/A8PovYODpzqGRmegB8fmQkSEpsA
AAAAAAAAAAAAAAAAAAAAAAwHAwCvpJsBeFU7CreonZPa2Nf3w7Wq/JZ2W/2SdV79iGpS/YFiSf1+XkP9
fVxC/XtbQP13Vz39a084/V1ENP0+MlH9Hx1f/RYVc/0REaH9GBiq/RgYqvwNDaXvERGdmiYmnXI8PKlI
Pj6mBS4upAAAAAAAAAAAAAAAAAAAAAAAAAAAALKmnQF4VTsJt6idk9rZ1/fIurD8s5uG/byqmv24ppb9
sJ2L/aWOev2af2j9j3JZ/YZnTP2AYET9e1xB/WpPP/1QPDz9LSNX/RMSnP0ZGar9GRmq/A0NpeEMDJ9I
Hh6WCTg4owRISKkAAQGXAAAAAAAAAAAAAAAAAAAAAAAAAAAAsqaeAXtXPQm4qZ6S2tnY9sm8s/y/qpf9
y72v/cq9sP3LvbH9y72w/ci5rP3CsaL9uKWU/auVgv2dhG39knde/YZqVP1aS2f9REOu/UVFuf1ISLv7
Rka64Dk5sEMtLZQDODiuATc3pAAuLqQAAAAAAAAAAAAAAAAAAAAAAAAAAACzp54BeVY8CbipnpLb2dj2
y7+2/Mm3p/3XzcL918zD/djNw/3XzcP92M3D/djNw/3Tyb/9xLqw/b+1qv3JvrL9xLas/Y+Hp/2BgMn9
jo7U/Y2N1Pt+fs7gXV2+QlhYnAJfX8ABW1uxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALOnngF7WD0J
uKqektva2PbMwLf80sK0/eHZ0f3h2dH94trS/eLa0v3i2tL94drR/cvFvv2koJz9gn97/bGspv3b0879
rajI/ZKR0v2dndr9nZ3Z+4yM0uBnZ8FBZ2enAWpqxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
s6eeAH1ZPgi5qp+R29rY9s3CuPzZzL/96uXf/erl4P3r5uD96+bg/ezm4f3r5uD9y8fD/b++vf1tbGz9
n56c/eTg3f24tdT9lpbT/aCg2f2fn9j6jo7R3mdnwD9/f8gBaWnCAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAC6raMAgV1BCLmqnY/b2dj00Ma/+tDAsfzp4tz87efi/O/q5f3w7Oj98u7q/fDt6f3Qz839
1tXU/bu7uv3MzMv96+no/b672f2BgMT9iYnK/IeHyfpxbrfIUk2fKnJxtwFcXLsAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAALipmwCFbVMFrZqJddLMx+nW0s/3yr60+sq9sfvOwLP70sW5+9jMwvve1Mr8
4dnR/MXCwPzOzc79z8/P/djX2P3v7u792djo/ain1P2iodP8mpjO+ZGHra99YWAWjIWwAXBwxQAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtKieAJeQawCReF4frZyLZbiqnYi+saanw7mvwsa8tNnJv7fn
xr228r+2r/mupJz6ramm+sTExfvEw8X7yMTC+97Uzfzn4d384t7k/N3a5vrSz+L2wre9pp16WxLEvMcA
XFy7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5qZwAgmdOAJeFbgGNeGMGl4BrCqGJdRCeiHMa
nIRxLZ+KeEeVjYZ9kI+PrZSTksekoqHUsa2q2MC6tubMxsH0zMK6+cu/tfvLvbL6z8G19tbJvt3Qvq5v
pX9ZBt3PwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACalW4AlntiAL2wpAHQysUB
19XTAbKwsAGwq6gBoZiRAouHhAeDgn8Wh4WEJ4uIhzOShXw4pJGBTrGik3C6q5+Ww7euws/Iw9HPx8KY
taCQTqmKchSibmIAl5CzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrWTQA
c1Y7AIxwWACehnEAoYp2AJ+IdQCijXwAl5CIAYuKigGSkpABpKKhAYmFggKJem4DjnZgB5uCbQ2agGoe
p5F/KsjBvA/AvLcEz8K2AaeCVwDe0MQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAFhYWAEpKSQB+fn4Ag4OBAIaFhQCLiIgAk4Z9AKuajAHDubAB
083KAdza2gHY1dQByL2zAbGXgQGriWwApm5lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAQkFAAGRhYAAzJx0A
Wz8pAHtdQACUemMAmoFrAKmVhADJxMAAsK6sAJyamgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAP//////////////////////n////gP///wAAH/wAAA/wAAAH8AAAA+AAAAH
gAAAA8AAAAPgAAAB+AAAAfgAAAH4AAAD+AAAA/gAAAP4AAAH/AAAB/wAAAf8AAAH/gAAD/4AAA//AAAf
//wAH///4D//////////////////////KAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAQAAAAAAAAABAAAACQQCAAUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAsFAgASDQoACAYFADopHgGejoMBoo1/AVsoBgFPIgQBKhICAQsEAAEBAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEAAAYGBQAIBQMAXVBIATMyMQYLCwoiDwoGNwkEAS4FAgEf
CwYDDSgVCANPJgsBPBsFARYJAQEDAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEPCwgEEA0LHCwgGGZgU0q9
dl9P3UQeBNUtFAK8GQsBkQoEAV0EAgEwCQUCER4QBwVOJg4BSiIIASAOAgEFAgABAAAAAQAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBBgAODjwADg4sAAwMXAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQAAAgcGBREIBgRL
RjoyqaSZkevV0tD7tqOV/GEuC/xgMBH7WC0R9kokDOk2GQfNIxADnhEHAWgGAwE4BwQCFg4HAwsVCwQH
FQoCBQkEAAQCAAAEAAAAAwAAAAMAAAACAAAAAgAAAAIAAAABAAACAQwMVAEfH6EBHR2jACwsowAdHasA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAK
AAAAOAEBAYgLBwTFkoR88t3c3Pze3t79t6SW/mMzFP1kPCL+ZT4n/WQ8I/xjOB38XTIW+VEpD+9AHgnW
KxMFsBQJAo8FAgBzAQAAYQAAAFsAAABXAAAAUgAAAE0AAABJAAAARAAAAD8AAAA7AAABNwEBCzQNDTwr
ERFECBsbngAqKrwAGRmoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
AAAABQAAACcAAABzAAAAtwEBAc8MBwTVl4qB9t7d3f3e3t79t6SX/mM1GP1mQSn+Z0Ux/mdFMf1mQy7+
ZkAr/WU+JfxkOiD8YDQZ+1UsEfZDIQvqKRMF2Q4GAdEDAQDNAAAAwwAAAL4AAAC7AAAAuAAAALYAAAC1
AAADswoKRcEcHJjUHByUViIipAMcHKQAHR24ABcXoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAEAAAANAAAATgAAAKcAAADMAAAA0QEBAdMLBwTXl4qB9t7d3f3f39/9uKWX/mQ2Gf1nQiv+
aEc0/mhHNf1oRzX+aEc0/mdGMv1nRDD+ZkIs/mU/KP1kOyL9VS8Y/DUbC/ooFAb3HA0D7w8HAeMFAgDR
AQAAtAEAAJ0AAAKjBAQowRoaovIlJbz6Hx+y1R4epC8eHrACHBylABYWsQAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAQAAABsAAABwAAAAvQAAANAAAADRAAAA0wEBAdMMBwTXmIuC9t/e3v7f39/+
uKWY/mU3Gv5oQyz+aUg1/mlJNv5pSTb+akk2/mpJNv5pSTb+aUg1/mhHNP5oRTH+WDkn/TgkF/40HxL+
NB4P/TMbDPwyGQn1ORwJ2SwVB6gUChyAFRSYzB8fuPwiIrb8Hx+4+hsbra4fH6AVGBirARwcoQAQEKcA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAHcAAADCAAAAzwAAANEAAADSAAAA0gEBAdMMBwTX
mIuC9t/e3v3f39/+uaWY/2c4Gv5qRCz/a0k1/2tKN/5rSjf/bEo3/2xLN/5sSzj/a0o3/mtKN/5rSjf+
Wj4u/TooHf42JBr+NiMY/TYiFv4+Jhf+Xjcf/WA1HvwzH2P0GBix+xoZrf4aGq3+GRmu/BgYsfYYGKaB
Hh6gCBUVpgESEqYADg6dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAC0AAABcAAAAhwAAAKoAAADA
AAAAzAEBAdEMBwTWmIyD9t/e3v3f39/9uaaY/2k6G/1sRi3/bUs2/21MOP1tTDj/bkw4/21NOf1uTTn/
bUw4/21MOP9tTDj/Wj8u/TspHv44Jx3+OCcc/TgmHP5DLiH+ZEMx/U00Vv4YFaX9Fhas/RkZrP4aGqz+
GRms/RUVrPwSEqrqFhahVBcXogMUFKEABASiABAQmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD
AAAACwAAAB0AAAA5AAAAXwICAoYPCQSunI+G8d/e3v3f39/+uaaY/ms8G/5uSC7+b003/m9OOf5vTjn+
cE45/m9OOv5wTzr+b045/m9OOf5vTjn+WkAv/jsqH/45KB7+OSge/jkoHv5HMib+WT9K/R0Xl/4REan+
GRmr/RoarP4aGqz+Ghqs/RgYq/0QEKn7Dg6k0xcXnS4MDKECExOcAAEBnQAPD5cAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAQAAAxcXFws5IxQur6GW19/f3v3f39/+uqaY/20/Hf5wSzD/
cVA5/3FRO/5xUTv/clE7/3JRO/5yUjz/cVE7/3FRO/9xUTv/W0Ev/jwrH/86KR7/Oike/jopH/9GMjH/
Jh2D/g0Mp/8XF6r/GRms/hkZrP8aGqz+GRms/RkZrP4XF6v9Cwul+gsLn64ZGZsVCgqeAQ8PmQAFBZsA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWNjYwJuRCcYtaab0N/f3v3f39/9
uqeZ/29AHv1zTTH/dFI6/3RTPP10Uzz/dVM8/3VTPf11VD3/dFM8/3RTPP9zUzz/W0Iv/T4sIP88Kx//
Oyof/ToqI/8mHGT/CQmi/RQUqf8ZGav/GRmr/RoarP8aGqz/GRms/RkZq/4ZGav+ExOp/AcHofUMDJuB
JSWeCAYGnABJSa8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAMLCwgFyRykX
taab0N/f3/3f39/+uqeZ/nJDIP52UDP+d1U8/ndWPv53Vj3+d1Y9/ndXPv54Vz7+d1Y9/ndWPf52Vj3+
XkQx/kAuIf49LCD+PCsg/iwgR/4GBJH+BQWd/gwMo/4SEqj+GBir/hoarP4aGqz+Ghqs/RgYq/4TE6n+
DAyk/AQEn/oCApjqEBCaUgYGmQEICJkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAN/e3gF0SCkXtqeb0N/f3/3f39/+u6iZ/3hLJ/56VTb/elg9/3pZP/56WT//elk//3paQP57WkD/
elk//3lZP/95WT//blE5/lc/LP9MNyj/RDEk/kI6bv8xMZv/ICCV/h0dl/8QEKL/FBSp/hoarP8aGqz/
GRms/RMTqv4KCqT8Gxuf8R8fnO4vL6XtQECvgy4uogE+PrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAN/f3wF0SCoXtqec0ODg3/3g39/9vqud/518YP2jiHP/mH5o/41wWf2EZEv/
f15D/31cQf19XUH/fVxC/31cQf99XEH/fFtA/XlZPv90VTz/Z0w3/T8xPP8hHkf/ERBE/RMRSf8UFJH/
Dg6o/Roaq/8aGqz/Ghqs/Q4OqP0ICKPKICCWQycnmDpOTq05amq8GUpKqwBycsEAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/e3gF0SCoXt6ec0ODg3/3g4N/+v62f/6yPdv69qZn/
vayd/7uqm/61opL/qpWC/52Dbv6Qc1r/hmdL/4FhRP+AYEP/gF9D/n9fQv9/X0L/fl5C/m1RPv9TPjj/
PCw0/iQcNf8VFIn/Dg2n/hoarP8aGqz/Ghqs/Q0NqP0HB6OyISGfCQEBnAICApYBERGeAAwMlQAKCp4A
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/f3gF0SSoXt6ec0N/f3/3g39/+
wK6g/7SZgv7GtaX/xrep/8a3qv7Gt6r/x7ir/8e4qv7EtKX/vKqa/6+Zhv+ghnD/knVb/olpTf+EY0b/
g2JE/oJhRP+AYET/e1xE/ldCQf8fHYz/ERCo/hoarP8aGqz/Gxus/RISqv0SEqayJiaeCBsboQFPT60A
amq8AEpKqgBycsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/f3wF0SSoW
uKicz9/f3/zg4OD9wa+h/ruijf3PwLL+z8K1/s/Ctv3Pwrb+0MK2/s/Ct/3Qw7f+0MK2/tDDt/7PwrX+
y72w/cGxov60oI7+po54/Zl+ZP6PcVX+iWlN/WZPR/5QTZ7+Xl7E/VdXwf5UVMH+XFzE/GdnyPxRUb2x
NDSlB2xsywEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAN/f3gF0SSoXuKic0ODg3/3g4OD+wbCi/8Krl/7Xyr//18zB/9fMwv7XzML/2MzC/9fMwv7YzcP/
2MzC/9fNwv/XzML/18vB/tbMwf/Vy8D/1cq//tPIvP/OwbT/xreo/pWIk/9qaLb/jY3V/pOT1/+Tk9f/
k5PX/YyM1f1hYcOxPj6pB4OD1AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAODf3gF0SSoXuKmc0N/f3/3g4N/+wrCj/8izof7e1Mr/3tXL/97VzP7f1cz/
39bN/9/Wzf7f1s3/39bN/9/Wzf/e1cz/2NDH/rKro/+blY//qqOc/tDHv//d1Mv/3dTM/rmywv9+fMb/
lpbZ/pub2v+bm9r/m5va/ZWV2f1oaMSxQECpB42N1wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODf3wF0SSoWuKmdz9/f3/zh4OD9w7Gj/s67qv3l3dX+
5d7W/uXe1v3m3tb+5t/X/ube1/3m39f+5d7X/uXe1v7l3tb+wbu1/ZORj/6cm5r+UlFP/ZCNif7e19D+
5N3V/cW/zf6Ihsz+np7b/aOj3f6jo93+o6Pd/J6e2/xtbcawQUGqBpWV2QEAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/f3wF0SioWuKmdz+Dg4P3h4eD+
w7Kk/9PCsv7r5d7/6+Xf/+vm4P7s5uD/7Ofg/+zm4P7s5+H/6+bg/+vm4P/r5eD/t7Ow/tHR0P+goJ//
IiIi/nV1dP/k4d3/6uTf/s3I1/+Ojc//o6Pd/qen3v+np97+p6fe/aKi3fxycsewQ0OqBpyc2wAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/e3gF1SisW
uamcz9/f3/3h4OD9w7Kk/tbFtf7w6+b/8Ovn//Ds5/7x7Of/8ezo//Ht6P7y7en/8e3o//Ht6P/w7Of/
vLq4/uDg3/+vr67/d3d3/paWlf/q6Ob/8Ozo/tTQ3/+Hhsn/lZXR/piY1P+ZmdX+mJjV/ZKS0vxeXbul
Tk6uBXx8ygAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAN/f3gB1SisWuamdzuDf3/zh4eH9zMC3/rugif3s5Nz+8+7p/vXx7v328u/+9vLv/vbz7/328+/+
9fLv/vXy7/7y7+z+vr28/ePj4v7e3t3+zc3N/djY1/7t7Ov+9fLw/dvY5/6CgcP+amm5/X18xf6Hhsr+
ennD/GNgr/VEPIxgWVmyATU0nQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAANXQywB3TS8RsJyLxOHg3/vi4uL84N7d/cKzp/y6o5D9vaeT/sOtmv3Nuqj+
2Mm7/uTZz/3v6OH+9fHt/vj28/708/H/vLu7/tjY2P/a2dn/2tra/tra2v/p6Of/+Pb1/ufm7/+jotH/
kpHL/pmY0P+bmtL+mZjR/ZaOtu2IZVQ7j47NAXNxvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJyBaQCNa1MDjWxRZ7mpm97Mxb7y087J+tnX1Pzd3Nv9
3NrZ/dfSz/zPx8D9x7qv/cCvoPy8qJb+vaeU/sKsmf6+rZ7+qKWj/cTExv7Dw8T/w8PF/sTExv/n5+f/
/Pv7/vn4+v/h4O//y8vl/sLB4v6zstv+np7T/KGZuuySbVI5lpXPATk5pQAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJd5YwCAWjsAf1g8Bn9YOyaMa1BF
lnhgZJ+GcYerlYOotaSVxr+yp9/Jv7fw0cvG+dXS0PzT0tH9ycfH/bGtq/2Ri4f9ubi3/M/Pz/3Ly8z9
x8bI/cG/vv7Juaz+3M7B/enh2P707+z++ff2/fj3+f708/f97Ovz+93U0OanfVIx6ejxACsmiwAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKfiwCGYUgA
mHxjAdnW0gHh4eIB2tfWAbutowKJZk4GelEzEH1WNiKHY0Y8kHJYW4h6b56IhoTdioqK8pCPj/qioqH9
sbCv/Li3tv3Av779z87O/NrY2P3PyML9xrit/L6snP27pJL+v6iU/cu2pf3cz8L87+nj+9vKusOjdkcU
8evmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAHRIKACGYUIAcEIiAHlPMACJZ0sBm4BoAbOikQHNxb4B29rYAeDg4AHe3t4B1dXVAYeHhwiFhIQi
h4aFQ4iHhmWKiYiGjoyLlZCIgo6ahnWrsqKUzMK2rOfNxr/22NTR+97d3f3f3t792tfV/M/HwPu6p5jm
q4xxrLCNakGdckkCtZRzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqOhkAaDkYAGc8GgBpOxoAbUAfAHdMKwCEX0EA
lXdeAZ+OfwGalpMBiYmKAX9/fwGJiIgCkI6OA5qNhAKCXkMHe1M0FIJcPi2NbFFRm39of6qUgrS+r6Pj
083I3N3c3JTa2to6ycG7CtPDtgGwjWkA+vj2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAACDg4QAhIODAHNzcgCAf38AhoWFAYyLigGRkI8BlpWVAZqWlAGtpqAB09HPAd/f3wHc29sB
uaqfAn9YPAp9Vjcuk3RcKsK3rgWYc1QBvaCEAbqZdwCWZTMAxKmNAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwcHABMS0sAYV9dAFs+KQBrPhwA
cEQiAHxTNACObVIBq5WCAc/IwAHg398B4eHhAeDg4AHa2toAycK+ALammwDU09MAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAGo6GQBvQiEAc0orAGw+HQB4Ty8Aj29VAMW+uACKZ0sA29nZAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////////////////
////////////////////////////////////////////////////////////8B/////////gA///////
/4AAH//////+AAAAA/////wAAAAB////8AAAAAD////gAAAAAH///8AAAAAAP///wAAAAAAf///AAAAA
AB////AAAAAAD///8AAAAAAH////AAAAAAf///+AAAAAA////4AAAAAD////gAAAAAf///+AAAAAD///
/4AAAAAf////gAAAAB////+AAAAAH////4AAAAAf////gAAAAB////+AAAAAP////4AAAAA/////wAAA
AD/////AAAAAP////8AAAAA/////4AAAAH/////gAAAAf/////gAAAB///////AAAP///////gAB////
/////gf/////////////////////////////////////////////////////////////////////////
/////w==
</value>
</data>
</root>
MyDownloader.App/UI/NewDownloadForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
using MyDownloader.Core.UI;
namespace MyDownloader.App.UI
{
partial class NewDownloadForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tableLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.chkChooseZIP = new System.Windows.Forms.CheckBox();
this.pnlFileName = new System.Windows.Forms.Panel();
this.label4 = new System.Windows.Forms.Label();
this.txtFilename = new System.Windows.Forms.TextBox();
this.checkableTreeView1 = new MyDownloader.App.Controls.CheckableTreeView();
this.folderBrowser1 = new MyDownloader.Core.UI.DownloadFolder();
this.chkStartNow = new System.Windows.Forms.CheckBox();
this.pnlSegments = new System.Windows.Forms.Panel();
this.numSegments = new System.Windows.Forms.NumericUpDown();
this.label2 = new System.Windows.Forms.Label();
this.locationMain = new MyDownloader.App.UI.Location();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.locationAlternate = new MyDownloader.App.UI.Location();
this.btnRemove = new System.Windows.Forms.Button();
this.btnAdd = new System.Windows.Forms.Button();
this.lvwLocations = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.waitControl1 = new MyDownloader.Core.UI.WaitControl();
this.backgroundWorkerRetriveZIPInformation = new System.ComponentModel.BackgroundWorker();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.pnlFileName.SuspendLayout();
this.pnlSegments.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numSegments)).BeginInit();
this.tabPage2.SuspendLayout();
this.SuspendLayout();
//
// btnOK
//
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(328, 589);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 1;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(409, 589);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// tabControl1
//
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(8, 8);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(474, 573);
this.tabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.tableLayoutPanel1);
this.tabPage1.Controls.Add(this.locationMain);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(466, 547);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "General";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP);
this.tableLayoutPanel1.Controls.Add(this.pnlFileName);
this.tableLayoutPanel1.Controls.Add(this.checkableTreeView1);
this.tableLayoutPanel1.Controls.Add(this.folderBrowser1);
this.tableLayoutPanel1.Controls.Add(this.chkStartNow);
this.tableLayoutPanel1.Controls.Add(this.pnlSegments);
this.tableLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 153);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.Size = new System.Drawing.Size(455, 391);
this.tableLayoutPanel1.TabIndex = 1;
//
// chkChooseZIP
//
this.chkChooseZIP.Location = new System.Drawing.Point(3, 3);
this.chkChooseZIP.Name = "chkChooseZIP";
this.chkChooseZIP.Size = new System.Drawing.Size(400, 20);
this.chkChooseZIP.TabIndex = 0;
this.chkChooseZIP.Text = "Choose files inside ZIP";
this.chkChooseZIP.UseVisualStyleBackColor = true;
this.chkChooseZIP.CheckedChanged += new System.EventHandler(this.chkChooseZIP_CheckedChanged);
//
// pnlFileName
//
this.pnlFileName.Controls.Add(this.label4);
this.pnlFileName.Controls.Add(this.txtFilename);
this.pnlFileName.Location = new System.Drawing.Point(3, 29);
this.pnlFileName.Name = "pnlFileName";
this.pnlFileName.Size = new System.Drawing.Size(448, 40);
this.pnlFileName.TabIndex = 1;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(0, 1);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(55, 13);
this.label4.TabIndex = 1;
this.label4.Text = "File name:";
//
// txtFilename
//
this.txtFilename.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtFilename.Location = new System.Drawing.Point(0, 17);
this.txtFilename.Name = "txtFilename";
this.txtFilename.Size = new System.Drawing.Size(448, 20);
this.txtFilename.TabIndex = 2;
this.txtFilename.TextChanged += new System.EventHandler(this.txtFilename_TextChanged);
//
// checkableTreeView1
//
this.checkableTreeView1.CheckBoxes = true;
this.checkableTreeView1.Location = new System.Drawing.Point(3, 75);
this.checkableTreeView1.Name = "checkableTreeView1";
this.checkableTreeView1.Size = new System.Drawing.Size(449, 196);
this.checkableTreeView1.TabIndex = 2;
//
// folderBrowser1
//
this.folderBrowser1.LabelText = "Save to:";
this.folderBrowser1.Location = new System.Drawing.Point(3, 277);
this.folderBrowser1.Name = "folderBrowser1";
this.folderBrowser1.Size = new System.Drawing.Size(447, 42);
this.folderBrowser1.TabIndex = 3;
//
// chkStartNow
//
this.chkStartNow.Location = new System.Drawing.Point(3, 325);
this.chkStartNow.Name = "chkStartNow";
this.chkStartNow.Size = new System.Drawing.Size(449, 17);
this.chkStartNow.TabIndex = 4;
this.chkStartNow.Text = "Start Now";
this.chkStartNow.UseVisualStyleBackColor = true;
//
// pnlSegments
//
this.pnlSegments.Controls.Add(this.numSegments);
this.pnlSegments.Controls.Add(this.label2);
this.pnlSegments.Location = new System.Drawing.Point(3, 348);
this.pnlSegments.Name = "pnlSegments";
this.pnlSegments.Size = new System.Drawing.Size(448, 37);
this.pnlSegments.TabIndex = 9;
//
// numSegments
//
this.numSegments.Location = new System.Drawing.Point(0, 16);
this.numSegments.Name = "numSegments";
this.numSegments.Size = new System.Drawing.Size(75, 20);
this.numSegments.TabIndex = 1;
this.numSegments.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(-3, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(54, 13);
this.label2.TabIndex = 0;
this.label2.Text = "Segments";
//
// locationMain
//
this.locationMain.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.locationMain.Location = new System.Drawing.Point(8, 3);
this.locationMain.Name = "locationMain";
this.locationMain.Size = new System.Drawing.Size(453, 147);
this.locationMain.TabIndex = 0;
this.locationMain.UrlLabelTitle = "URL";
//
// tabPage2
//
this.tabPage2.Controls.Add(this.locationAlternate);
this.tabPage2.Controls.Add(this.btnRemove);
this.tabPage2.Controls.Add(this.btnAdd);
this.tabPage2.Controls.Add(this.lvwLocations);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(466, 547);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Alternate URL";
this.tabPage2.UseVisualStyleBackColor = true;
//
// locationAlternate
//
this.locationAlternate.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.locationAlternate.Location = new System.Drawing.Point(8, 3);
this.locationAlternate.Name = "locationAlternate";
this.locationAlternate.Size = new System.Drawing.Size(447, 98);
this.locationAlternate.TabIndex = 0;
this.locationAlternate.UrlLabelTitle = "URL";
//
// btnRemove
//
this.btnRemove.Location = new System.Drawing.Point(154, 107);
this.btnRemove.Name = "btnRemove";
this.btnRemove.Size = new System.Drawing.Size(75, 23);
this.btnRemove.TabIndex = 2;
this.btnRemove.Text = "Remove";
this.btnRemove.UseVisualStyleBackColor = true;
this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
//
// btnAdd
//
this.btnAdd.Location = new System.Drawing.Point(6, 107);
this.btnAdd.Name = "btnAdd";
this.btnAdd.Size = new System.Drawing.Size(142, 23);
this.btnAdd.TabIndex = 1;
this.btnAdd.Text = "Add / Update Selection";
this.btnAdd.UseVisualStyleBackColor = true;
this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
//
// lvwLocations
//
this.lvwLocations.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lvwLocations.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader4,
this.columnHeader2,
this.columnHeader3});
this.lvwLocations.FullRowSelect = true;
this.lvwLocations.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvwLocations.HideSelection = false;
this.lvwLocations.Location = new System.Drawing.Point(6, 130);
this.lvwLocations.MultiSelect = false;
this.lvwLocations.Name = "lvwLocations";
this.lvwLocations.Size = new System.Drawing.Size(447, 388);
this.lvwLocations.TabIndex = 3;
this.lvwLocations.UseCompatibleStateImageBehavior = false;
this.lvwLocations.View = System.Windows.Forms.View.Details;
this.lvwLocations.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvwLocations_ItemSelectionChanged);
//
// columnHeader1
//
this.columnHeader1.Text = "URL";
this.columnHeader1.Width = 248;
//
// columnHeader4
//
this.columnHeader4.Text = "Authenticate?";
this.columnHeader4.Width = 86;
//
// columnHeader2
//
this.columnHeader2.Text = "Login";
this.columnHeader2.Width = 73;
//
// columnHeader3
//
this.columnHeader3.Text = "Password";
this.columnHeader3.Width = 83;
//
// waitControl1
//
this.waitControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.waitControl1.Location = new System.Drawing.Point(8, 592);
this.waitControl1.Name = "waitControl1";
this.waitControl1.Size = new System.Drawing.Size(232, 16);
this.waitControl1.TabIndex = 3;
this.waitControl1.Text = "Loading zip contents...";
this.waitControl1.Visible = false;
//
// NewDownloadForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(489, 618);
this.Controls.Add(this.waitControl1);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "NewDownloadForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "New Download";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NewDownloadForm_FormClosing);
this.Load += new System.EventHandler(this.NewDownloadForm_Load);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tableLayoutPanel1.ResumeLayout(false);
this.pnlFileName.ResumeLayout(false);
this.pnlFileName.PerformLayout();
this.pnlSegments.ResumeLayout(false);
this.pnlSegments.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numSegments)).EndInit();
this.tabPage2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.Button btnRemove;
private System.Windows.Forms.Button btnAdd;
private Location locationMain;
private Location locationAlternate;
private System.Windows.Forms.ListView lvwLocations;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader4;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader3;
private DownloadFolder folderBrowser1;
private System.Windows.Forms.CheckBox chkChooseZIP;
private System.Windows.Forms.FlowLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Panel pnlFileName;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtFilename;
private MyDownloader.App.Controls.CheckableTreeView checkableTreeView1;
private System.Windows.Forms.Panel pnlSegments;
private System.Windows.Forms.NumericUpDown numSegments;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.CheckBox chkStartNow;
private WaitControl waitControl1;
private System.ComponentModel.BackgroundWorker backgroundWorkerRetriveZIPInformation;
}
}
MyDownloader.App/UI/NewDownloadForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core.Common;
using MyDownloader.Core;
using MyDownloader.Core.UI;
using MyDownloader.Extension.Protocols;
using ICSharpCode.SharpZipLib.Zip;
using MyDownloader.Extension.Zip;
using System.IO;
using System.Threading;
namespace MyDownloader.App.UI
{
public partial class NewDownloadForm : Form
{
Thread zipReaderThread;
public NewDownloadForm(string file, string filename, string location, int segments, string username, string password)
{
InitializeComponent();
txtFilename.Text = filename;
numSegments.Value = segments;
//folderBrowser1.
ResourceLocation[] rl = new ResourceLocation[1];
rl[0] = ResourceLocation.FromURL(file);
DownloadLocation = rl;
folderBrowser1.Folder = location;
chkStartNow.Checked = true;
if (username != "" || password != "")
{
locationMain.Username = username;
locationMain.Password = password;
}
//AddLocation(ResourceLocation.FromURL(file));
}
public NewDownloadForm()
{
InitializeComponent();
locationMain.UrlChanged += new EventHandler(locationMain_UrlChanged);
ShowZIPMode(false);
numSegments.Maximum = Core.Settings.Default.MaxSegments;
numSegments.Value = Core.Settings.Default.MaxSegments;
chkStartNow.Checked = true;
}
void locationMain_UrlChanged(object sender, EventArgs e)
{
if (Core.Settings.Default.AutomaticFileName)
{
try
{
Uri u = new Uri(locationMain.ResourceLocation[0].URL);
txtFilename.Text = u.Segments[u.Segments.Length - 1];
}
catch
{
txtFilename.Text = string.Empty;
}
}
}
public ResourceLocation[] DownloadLocation
{
get
{
return locationMain.ResourceLocation;
}
set
{
locationMain.ResourceLocation = value;
}
}
public ResourceLocation[] Mirrors
{
get
{
MyDownloader.Core.ResourceLocation[] mirrors = new MyDownloader.Core.ResourceLocation[lvwLocations.Items.Count];
for (int i = 0; i < lvwLocations.Items.Count; i++)
{
ListViewItem item = lvwLocations.Items[i];
mirrors[i] = MyDownloader.Core.ResourceLocation.FromURL(
item.SubItems[0].Text,
BoolFormatter.FromString(item.SubItems[1].Text),
item.SubItems[2].Text,
item.SubItems[3].Text);
}
return mirrors;
}
}
public string LocalFile
{
get
{
return PathHelper.GetWithBackslash(folderBrowser1.Folder) + txtFilename.Text;
}
}
public int Segments
{
get
{
return (int)numSegments.Value;
}
}
public bool StartNow
{
get
{
return chkStartNow.Checked;
}
}
private void lvwLocations_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
bool hasSelected = lvwLocations.SelectedItems.Count > 0;
btnRemove.Enabled = hasSelected;
if (hasSelected)
{
ListViewItem item = lvwLocations.SelectedItems[0];
ResourceLocation[]rl=new ResourceLocation[1];
rl[0]=MyDownloader.Core.ResourceLocation.FromURL(
item.SubItems[0].Text, BoolFormatter.FromString(item.SubItems[1].Text), item.SubItems[2].Text, item.SubItems[3].Text);
locationAlternate.ResourceLocation = rl;
}
else
{
locationAlternate.ResourceLocation = null;
}
}
private void btnRemove_Click(object sender, EventArgs e)
{
for (int i = lvwLocations.Items.Count - 1; i >= 0; i--)
{
if (lvwLocations.Items[i].Selected)
{
lvwLocations.Items.RemoveAt(i);
}
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
foreach (ResourceLocation rl in locationAlternate.ResourceLocation)
AddLocation(rl);
}
private void AddLocation(ResourceLocation rl)
{
if (lvwLocations.SelectedItems.Count > 0)
{
ListViewItem item = lvwLocations.SelectedItems[0];
item.SubItems[0].Text = rl.URL;
item.SubItems[1].Text = BoolFormatter.ToString(rl.Authenticate);
item.SubItems[2].Text = rl.Login;
item.SubItems[3].Text = rl.Password;
}
else
{
ListViewItem item = new ListViewItem();
item.Text = rl.URL;
item.SubItems.Add(BoolFormatter.ToString(rl.Authenticate));
item.SubItems.Add(rl.Login);
item.SubItems.Add(rl.Password);
lvwLocations.Items.Add(item);
}
}
private void btnOK_Click(object sender, EventArgs e)
{
foreach (ResourceLocation rl in this.DownloadLocation)
StartDownload(rl);
}
private void StartDownload(ResourceLocation rl)
{
try
{
rl.BindProtocolProviderType();
if (rl.ProtocolProviderType == null)
{
MessageBox.Show("Invalid URL format, please check the location field.",
AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
DialogResult = DialogResult.None;
return;
}
ResourceLocation[] mirrors = this.Mirrors;
if (mirrors != null && mirrors.Length > 0)
{
foreach (ResourceLocation mirrorRl in mirrors)
{
mirrorRl.BindProtocolProviderType();
if (mirrorRl.ProtocolProviderType == null)
{
MessageBox.Show("Invalid mirror URL format, please check the mirror URLs.",
AppManager.Instance.Application.MainForm.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
DialogResult = DialogResult.None;
return;
}
}
}
if (chkChooseZIP.Checked)
{
AddDownloadsFromZip(checkableTreeView1.Nodes, mirrors);
}
else
{
Downloader download = DownloadManager.Instance.Add(
rl,
mirrors,
this.LocalFile,
this.Segments,
this.StartNow);
}
Close();
}
catch (Exception)
{
DialogResult = DialogResult.None;
MessageBox.Show("Unknow error, please check your input data.",
AppManager.Instance.Application.MainForm.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void AddDownloadsFromZip(TreeNodeCollection nodes, ResourceLocation[] mirrors)
{
for (int i = 0; i < nodes.Count; i++)
{
if (nodes[i].Checked)
{
if (nodes[i].Nodes.Count > 0)
{
AddDownloadsFromZip(nodes[i].Nodes, mirrors);
}
else
{
//TODO:fix for multiple file download
ResourceLocation newLocation = this.DownloadLocation[0];
newLocation.ProtocolProviderType = typeof(ZipProtocolProvider).AssemblyQualifiedName;
string entryName = ((ZipEntry)nodes[i].Tag).Name;
Downloader download = DownloadManager.Instance.Add(
newLocation,
mirrors,
this.folderBrowser1.Folder + entryName,
1,
false);
ZipProtocolProvider.SetZipEntryNameProperty(download, entryName);
if (this.StartNow)
{
download.Start();
}
}
}
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
Close();
}
private void chkChooseZIP_CheckedChanged(object sender, EventArgs e)
{
ReleaseZIPThread();
ShowZIPMode(chkChooseZIP.Checked);
if (chkChooseZIP.Checked)
{
LoadZIP();
}
}
private TreeNode GetNodeFromPath(String path, out string displayName)
{
string[] subPaths = path.Split('/');
if (subPaths.Length == 0)
{
displayName = null;
return null;
}
TreeNode result = null;
TreeNodeCollection nodes = checkableTreeView1.Nodes;
displayName = subPaths[subPaths.Length - 1];
for (int j = 0; j < subPaths.Length - 1; j++)
{
TreeNode parentNode = null;
for (int i = 0; i < nodes.Count; i++)
{
if (String.Equals(nodes[i].Text, subPaths[j], StringComparison.OrdinalIgnoreCase))
{
parentNode = nodes[i];
break;
}
}
if (parentNode == null)
{
// add the path
result = new TreeNode(subPaths[j]);
result.ImageIndex = FileTypeImageList.GetImageIndexFromFolder(false);
result.SelectedImageIndex = FileTypeImageList.GetImageIndexFromFolder(true);
nodes.Add(result);
}
else
{
result = parentNode;
}
nodes = result.Nodes;
}
return result;
}
private void ReleaseZIPThread()
{
if (zipReaderThread != null)
{
if (zipReaderThread.IsAlive)
{
zipReaderThread.Abort();
zipReaderThread = null;
}
}
waitControl1.Visible = false;
}
private void LoadZIP()
{
checkableTreeView1.Nodes.Clear();
ResourceLocation rl = this.DownloadLocation[0];
rl.BindProtocolProviderType();
if (rl.ProtocolProviderType == null)
{
chkChooseZIP.Checked = false;
MessageBox.Show("Invalid URL format, please check the location field.",
AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ReleaseZIPThread();
zipReaderThread = new Thread(
delegate(object state)
{
ZipRemoteFile zipFile = new ZipRemoteFile((ResourceLocation)state);
try
{
if (zipFile.Load())
{
this.BeginInvoke((MethodInvoker)delegate() { DisplayZIPOnTree(zipFile); waitControl1.Visible = false; });
}
else
{
this.BeginInvoke((MethodInvoker)delegate()
{
waitControl1.Visible = false;
MessageBox.Show("Unable to load ZIP contents.",
AppManager.Instance.Application.MainForm.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
});
}
}
catch (Exception ex)
{
this.BeginInvoke((MethodInvoker)delegate()
{
waitControl1.Visible = false;
MessageBox.Show("Unable to load ZIP contents: " + ex.Message,
AppManager.Instance.Application.MainForm.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
});
}
}
);
waitControl1.Visible = true;
zipReaderThread.Start(rl);
}
private void DisplayZIPOnTree(ZipRemoteFile zipFile)
{
checkableTreeView1.ImageList = FileTypeImageList.GetSharedInstance();
checkableTreeView1.Nodes.Clear();
foreach (ZipEntry entry in zipFile)
{
// skip folders...
if (entry.Name.EndsWith("/"))
{
continue;
}
string displayName;
TreeNode parentNd = GetNodeFromPath(entry.Name, out displayName);
TreeNode newNd = new TreeNode(displayName);
newNd.Tag = entry;
newNd.ImageIndex = FileTypeImageList.GetImageIndexByExtention(Path.GetExtension(entry.Name));
newNd.SelectedImageIndex = newNd.ImageIndex;
if (parentNd == null)
{
checkableTreeView1.Nodes.Add(newNd);
}
else
{
parentNd.Nodes.Add(newNd);
}
}
}
private void ShowZIPMode(bool show)
{
if (show)
{
this.tableLayoutPanel1.Controls.Clear();
//this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP, 0, 0);
//this.tableLayoutPanel1.Controls.Add(this.checkableTreeView1, 0, 1);
//this.tableLayoutPanel1.Controls.Add(this.folderBrowser1, 0, 2);
//this.tableLayoutPanel1.Controls.Add(this.chkStartNow, 0, 3);
//this.tableLayoutPanel1.Controls.Add(this.pnlSegments, 0, 4);
this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP);
this.tableLayoutPanel1.Controls.Add(this.checkableTreeView1);
this.tableLayoutPanel1.Controls.Add(this.folderBrowser1);
this.tableLayoutPanel1.Controls.Add(this.chkStartNow);
this.tableLayoutPanel1.Controls.Add(this.pnlSegments);
//this.tableLayoutPanel1.RowCount = 5;
this.tableLayoutPanel1.AutoSize = true;
this.Height = 600;
/* this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());*/
}
else
{
this.tableLayoutPanel1.Controls.Clear();
//this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP, 0, 0);
//this.tableLayoutPanel1.Controls.Add(this.pnlFileName, 0, 1);
//this.tableLayoutPanel1.Controls.Add(this.folderBrowser1, 0, 2);
//this.tableLayoutPanel1.Controls.Add(this.chkStartNow, 0, 3);
//this.tableLayoutPanel1.Controls.Add(this.pnlSegments, 0, 4);
this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP);
this.tableLayoutPanel1.Controls.Add(this.pnlFileName);
this.tableLayoutPanel1.Controls.Add(this.folderBrowser1);
this.tableLayoutPanel1.Controls.Add(this.chkStartNow);
this.tableLayoutPanel1.Controls.Add(this.pnlSegments);
//this.tableLayoutPanel1.RowCount = 5;
this.tableLayoutPanel1.AutoSize = true;
this.Height = 444;
/* this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());*/
}
}
private void NewDownloadForm_FormClosing(object sender, FormClosingEventArgs e)
{
this.ReleaseZIPThread();
}
private void NewDownloadForm_Load(object sender, EventArgs e)
{
}
private void txtFilename_TextChanged(object sender, EventArgs e)
{
}
}
}
MyDownloader.App/UI/NewDownloadForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="backgroundWorkerRetriveZIPInformation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>59</value>
</metadata>
</root>
MyDownloader.App/UI/OptionsForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
namespace MyDownloader.App.UI
{
partial class OptionsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.treeOptions = new System.Windows.Forms.TreeView();
this.pnlExtension = new System.Windows.Forms.Panel();
this.btnCancel = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// treeOptions
//
this.treeOptions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.treeOptions.Location = new System.Drawing.Point(13, 13);
this.treeOptions.Name = "treeOptions";
this.treeOptions.Size = new System.Drawing.Size(150, 417);
this.treeOptions.TabIndex = 0;
this.treeOptions.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeOptions_AfterSelect);
//
// pnlExtension
//
this.pnlExtension.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pnlExtension.Location = new System.Drawing.Point(175, 16);
this.pnlExtension.Name = "pnlExtension";
this.pnlExtension.Size = new System.Drawing.Size(453, 414);
this.pnlExtension.TabIndex = 1;
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(553, 436);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 3;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// btnOK
//
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOK.Location = new System.Drawing.Point(472, 436);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 2;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// OptionsForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(640, 469);
this.Controls.Add(this.btnOK);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.pnlExtension);
this.Controls.Add(this.treeOptions);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "OptionsForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Options";
this.Load += new System.EventHandler(this.OptionsForm_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TreeView treeOptions;
private System.Windows.Forms.Panel pnlExtension;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
}
}
MyDownloader.App/UI/OptionsForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core.Extensions;
namespace MyDownloader.App.UI
{
public partial class OptionsForm : Form
{
delegate void ProcessItemDelegate(IExtension extension, Control[] options);
public OptionsForm()
{
InitializeComponent();
}
private void OptionsForm_Load(object sender, EventArgs e)
{
try
{
treeOptions.BeginUpdate();
for (int i = 0; i < App.Instance.Extensions.Count; i++)
{
IExtension extension = App.Instance.Extensions[i];
IUIExtension uiExtension = extension.UIExtension;
if (uiExtension == null)
{
continue;
}
Control[] options = uiExtension.CreateSettingsView();
if (options == null || options.Length == 0)
{
continue;
}
TreeNode node = new TreeNode(extension.Name);
node.Tag = extension;
for (int j = 0; j < options.Length; j++)
{
TreeNode optioNd = new TreeNode(options[j].Text);
optioNd.Tag = options[j];
node.Nodes.Add(optioNd);
}
node.Expand();
treeOptions.Nodes.Add(node);
}
}
finally
{
treeOptions.EndUpdate();
}
}
private void ProcessSettings(ProcessItemDelegate process)
{
for (int i = 0; i < treeOptions.Nodes.Count; i++)
{
TreeNode node = treeOptions.Nodes[i];
IExtension extension = (IExtension)node.Tag;
Control[] options = new Control[node.Nodes.Count];
for (int j = 0; j < node.Nodes.Count; j++)
{
options[j] = (Control)node.Nodes[j].Tag;
}
process(extension, options);
}
treeOptions.Nodes.Clear();
}
private void treeOptions_AfterSelect(object sender, TreeViewEventArgs e)
{
pnlExtension.Controls.Clear();
if (e.Node.Parent != null)
{
ShowOptionFromNode(e.Node);
}
else
{
ShowOptionFromNode(e.Node.Nodes[0]);
}
}
private void ShowOptionFromNode(TreeNode node)
{
Control ctrl = (Control)node.Tag;
ctrl.Visible = true;
ctrl.Dock = DockStyle.Fill;
pnlExtension.Controls.Add(ctrl);
}
private void btnOK_Click(object sender, EventArgs e)
{
ProcessSettings(
delegate(IExtension extension, Control[] options)
{
extension.UIExtension.PersistSettings(options);
for (int i = 0; i < options.Length; i++)
{
options[i].Dispose();
}
}
);
DialogResult = DialogResult.OK;
}
private void btnCancel_Click(object sender, EventArgs e)
{
ProcessSettings(
delegate(IExtension extension, Control[] options)
{
for (int i = 0; i < options.Length; i++)
{
options[i].Dispose();
}
}
);
DialogResult = DialogResult.Cancel;
}
}
}
MyDownloader.App/UI/OptionsForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.App/bin/Release/License.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
.Net Download Manager is Licensed under the Apache Version 2.0.
DNDM also uses the following projects from other developers:
* A command line parser licensed under the MS-PL.
* A ini parser licensed under MIT
Apache License 2.0
Copyright [2012]
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.
Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
MyDownloader.App/bin/Release/readme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.Net Download Manager (DNDM) is a fork of MyDownloader
Original Google code link = http://code.google.com/p/mydownloader/
Original Codeproject link = http://www.codeproject.com/Articles/21053/MyDownloader-A-Multi-thread-C-Segmented-Download-M
I contacted the author for special permission to fork under the Apache license instead of GPL.
Some of the features I have included in this forked release:
+ Fixed support for FTP
(The application would crash if you didn't give it a file name when downloading from FTP)
+ Fixed up the parameter support so you can add downloads via the command line
(This was needed for the following Chrome extension - https://chrome.google.com/webstore/detail/downloaders/lfjamigppmepikjlacjdpgjaiojdjhoj - I'm sure an extension exists for Firefox as well where you can use a custom download manager. See the wiki for more information on intergration.)
+ Upgraded to VS2010/.Net 3.5
+ Create an installer
+ Fixed cookie support
(Microsoft randomizes the cookie file names now)
+ Added cookie support for Chrome and Firefox (this can be changed in settings)
I highly recommend you check out his original project as it is freaking awesome. You will see "MyDownloader" tags all over this application - the reason is very simple - Guilherme Labigalini deserves most of the credit as all I did was merely added/updated some code and created the installer.
I do want to note a couple of things:
+ This fork's source will always be available
+ The installer that I create will NEVER contain toolbars/greyware/malware (unlike other download managers)
+ Please do not contact Guilherme with questions about DNDM - those should be directed to me adamsna[at]datanethost.net . Questions about MyDownloader should be directed to him, but I should be able to answer some.
+ Please do contact me with bugs/issues - while I can't make any promises at least they can be recorded.
MyDownloader.Core/CalculatedSegment.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
[Serializable]
public struct CalculatedSegment
{
private long startPosition;
private long endPosition;
public long StartPosition
{
get { return startPosition; }
set { startPosition = value; }
}
public long EndPosition
{
get { return endPosition; }
set { endPosition = value; }
}
public CalculatedSegment(long startPos, long endPos)
{
this.endPosition = endPos;
this.startPosition = startPos;
}
}
}
MyDownloader.Core/Common/ArrayExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core.Common
{
public static class ArrayExtension
{
public static int indexOf(this byte[] haystack, byte[] needle)
{
//int ret = -1;
// pos = index of needle 1
// if pos is not -1
// check next char
//Object[] tmphay = (object[])haystack;
//Object[] tmpneedle = (object[])needle;
int pos = -1;
bool found = false;
pos = Array.IndexOf(haystack, needle[0]);
if (needle.Length == 1)
return pos;
while (pos != -1 && !found)
{
if (pos != -1)
{
for (int i = 1; i < needle.Length; i++)
{
if (haystack[pos + i] != needle[i])
{
found = false;
break;
}
found = true;
}
}
if (found)
break;
pos = Array.IndexOf(haystack, needle[0], pos + 1);
}
return pos;
}
public static byte[] sub(this byte[] arr, int start, int end)
{
byte[] ret = new byte[end - start];
for (int i = start; i < end; i++)
{
ret[i - start] = arr[i];
}
return ret;
}
}
}
MyDownloader.Core/Common/BoolFormatter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core.Common
{
public static class BoolFormatter
{
private const string Yes = "Yes";
private const string No = "No";
public static bool FromString(string s)
{
if (s == Yes) return true;
return false;
}
public static string ToString(bool v)
{
if (v) return Yes;
return No;
}
}
}
MyDownloader.Core/Common/ByteFormatter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core.Common
{
public static class ByteFormatter
{
private const long KB = 1024;
private const long MB = KB * 1024;
private const long GB = MB * 1024;
private const string BFormatPattern = "{0} b";
private const string KBFormatPattern = "{0:0} KB";
private const string MBFormatPattern = "{0:0,###} MB";
private const string GBFormatPattern = "{0:0,###.###} GB";
public static string ToString(long size)
{
if (size < KB)
{
return String.Format(BFormatPattern, size);
}
else if (size >= KB && size < MB)
{
return String.Format(KBFormatPattern, size / 1024.0f);
}
else if (size >= MB && size < GB)
{
return String.Format(MBFormatPattern, size / 1024.0f);
}
else // size >= GB
{
return String.Format(GBFormatPattern, size / 1024.0f);
}
}
}
}
MyDownloader.Core/Common/CookieManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Runtime.InteropServices;
using System.IO;
using System.Data;
using IniParser;
using IniParser.Model;
namespace MyDownloader.Core.Common
{
public class CookieManager
{
// Cookies are now randomized in IE - http://blogs.msdn.com/b/ieinternals/archive/2011/08/12/internet-explorer-9.0.2-update-changes-file-protocol-and-cookie-naming.aspx
public class CookieStruct
{
//1 The Variable Name
//2 The Value for the Variable
//3 The Website of the Cookie’s Owner
//4 Optional Flags
//5 The Most Significant Integer for Expired Time, in FILETIME Format
//6 The Least Significant Integer for Expired Time, in FILETIME Format
//7 The Most Significant Integer for Creation Time, in FILETIME Format
//8 The Least Significant Integer for Creation Time, in FILETIME Format
//9 The Cookie Record Delimiter (a * character)
public string VarName;
public string VarValue;
public string Domain;
public int Flags;
public DateTime ExpirationDate;
public DateTime CreationDate;
}
public static CookieCollection GetCookieCollection(string url)
{
CookieCollection ret = new CookieCollection();
Uri location = new Uri(url);
if (Settings.Default.CookieSource == "Internet Explorer")
{
BinaryReader br = new BinaryReader(File.Open(Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "/Low/index.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
byte[] indexfile = br.ReadBytes((int)br.BaseStream.Length);
br.Close();
int loc = 0;
int locfile = 0;
int endlocfile = 0;
byte[] domainfind = Encoding.Default.GetBytes(location.Host.Replace("www.", ""));
loc = indexfile.indexOf(domainfind);
byte[] bfile;
if (loc != -1)
{
locfile = Array.IndexOf(indexfile, (byte)0xDE, loc);
endlocfile = Array.IndexOf(indexfile, (byte)0x2E, locfile);
bfile = indexfile.sub(locfile + 1, endlocfile);
CookieStruct[] cs = ReadCookie(Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "/Low/" + Encoding.Default.GetString(bfile) + ".txt");
foreach (CookieStruct c in cs)
{
Cookie nc = new Cookie(c.VarName.Trim(), c.VarValue.Trim());
nc.Expires = c.ExpirationDate;
nc.Domain = c.Domain;
ret.Add(nc);
}
}
}
else if (Settings.Default.CookieSource == "Chrome")
{
string chromepath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Google\Chrome\User Data\Default";
//string cookie = chromepath + @"\Cookies";
if (!File.Exists(chromepath + @"\Cookies"))
{
throw new Exception("Could not find Chrome cookie file!");
}
if (File.Exists(chromepath + @"\Cookies.dndm"))
{
File.Delete(chromepath + @"\Cookies.dndm");
}
// We have to copy the cookies SQLite file because Chrome locks it
File.Copy(chromepath + @"\Cookies", chromepath + @"\Cookies.dndm", true);
SQLiteDatabase db = new SQLiteDatabase(chromepath + @"\Cookies.dndm");
DataTable cookietable = db.GetDataTable(String.Format("SELECT * FROM cookies where host_key = \"{0}\" or host_key = \"{1}\" or host_key = \"{2}\" or host_key = \"{3}\"", location.Host, location.Host, location.Host.Replace("www.", ""), "." + location.Host));
if (cookietable.Rows.Count > 0)
{
foreach(DataRow dr in cookietable.Rows)
{
Cookie nc = new Cookie(dr["name"].ToString().Trim(), dr["value"].ToString().Trim());
nc.Expires = DateTimeExtension.FromUnixTime((Double.Parse(dr["expires_utc"].ToString()) / 1000000) - 11644473600);
nc.Domain = dr["host_key"].ToString();
ret.Add(nc);
}
}
File.Delete(chromepath + @"\Cookies.dndm");
}
else if (Settings.Default.CookieSource == "Firefox")
{
//Get default folder
string firefoxpath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\..\Roaming\Mozilla\Firefox";
firefoxpath = Path.GetFullPath(firefoxpath);
string profilesini = firefoxpath + @"\profiles.ini";
FileIniDataParser iniparser = new FileIniDataParser();
IniData inifile = iniparser.ReadFile(profilesini);
string profilefolder = inifile["Profile0"]["Path"];
string userfolder = firefoxpath + @"\" + profilefolder;
string ffbookmarks = userfolder + @"\cookies.sqlite";
string tmpffbook = userfolder + @"\cookies.dndm";
File.Copy(ffbookmarks, tmpffbook, true);
SQLiteDatabase db = new SQLiteDatabase(Path.GetFullPath(tmpffbook));
DataTable cookietable = db.GetDataTable(String.Format("SELECT * FROM moz_cookies where host = \"{0}\" or host = \"{1}\" or host = \"{2}\" or host = \"{3}\"", location.Host, location.Host, location.Host.Replace("www.", ""), "." + location.Host));
if (cookietable.Rows.Count > 0)
{
foreach (DataRow dr in cookietable.Rows)
{
Cookie nc = new Cookie(dr["name"].ToString(), dr["value"].ToString());
nc.Expires = DateTimeExtension.FromUnixTime(Double.Parse(dr["expiry"].ToString()));
nc.Domain = dr["host"].ToString();
ret.Add(nc);
}
}
File.Delete(tmpffbook);
}
// Old way of finding cookies - no longer works due to IE randomization of cookie file names
/*FileInfo[] fis = SearchCookies(Domain);
foreach (FileInfo fi in fis)
{
CookieStruct[] cs = ReadCookie(fi.FullName);
foreach(CookieStruct c in cs)
if (baseUrl.EndsWith(c.Domain) && c.ExpirationDate > DateTime.Now)
{
Cookie nc = new Cookie(c.VarName, c.VarValue);
nc.Expires = c.ExpirationDate;
nc.Domain = c.Domain;
ret.Add(nc);
}
}*/
return ret;
}
private static FileInfo[] SearchCookies(string Domain)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Cookies);
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] fis = di.GetFiles(string.Format("*@{0}[*.txt", Domain));
di = new DirectoryInfo(path + "//Low");
if (di.Exists)
{
FileInfo[] fisLow = di.GetFiles(string.Format("*@{0}[*.txt", Domain));
FileInfo[] ret = new FileInfo[fis.Length + fisLow.Length];
fis.CopyTo(ret, 0);
fisLow.CopyTo(ret, fis.Length);
return ret;
}
else
return fis;
}
private static CookieStruct[] ReadCookie(string fn)
{
StreamReader sr = new StreamReader(fn);
string cookie = sr.ReadToEnd();
sr.Close();
string[] data=cookie.Split('\n');
int cookieNum = data.Length / 9;
CookieStruct[] ret = new CookieStruct[cookieNum];
for (int i = 0; i < cookieNum; i++)
{
int bline = i * 9;
ret[i] = new CookieStruct();
ret[i].VarName = data[bline];
ret[i].VarValue = data[bline+1];
ret[i].Domain = data[bline + 2];
ret[i].Flags = Convert.ToInt32(data[bline + 3]);
long l = Convert.ToInt64(data[bline + 4]);
l += Convert.ToInt64(data[bline + 5]) << 32;
ret[i].ExpirationDate = DateTime.FromFileTime(l);
l = Convert.ToInt64(data[bline + 6]);
l += Convert.ToInt64(data[bline + 7]) << 32;
ret[i].CreationDate = DateTime.FromFileTime(l);
}
return ret;
}
//[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
//static extern bool InternetGetCookie(string lpszUrlName, string lpszCookieName, [Out] StringBuilder lpszCookieData, [MarshalAs(UnmanagedType.U4)] ref int lpdwSize);
//[DllImport("wininet.dll", EntryPoint = "InternetSetCookie", ExactSpelling = false, CharSet = CharSet.Unicode, SetLastError = true)]
//static extern bool InternetSetCookie(string url, string cookieName, string cookieData);
//const int ERROR_NO_MORE_ITEMS = 259;
//const int ERROR_INSUFFICIENT_BUFFER = 122;
//const int ERROR_INVALID_PARAMETER = 87;
//const int INTERNET_COOKIE_HTTPONLY = 0x00002000;
//public static void SetCookie(string siteUrl, string cookieName, string cookieData)
//{
// if (!InternetSetCookie(siteUrl, cookieName, cookieData))
// {
// throw new Exception("Exception setting cookie: Win32 Error code=" + Marshal.GetLastWin32Error());
// }
//}
/*public static CookieContainer GetUriCookieContainer(string uri)
{
CookieContainer cookies = null;
// Determine the size of the cookie
int datasize = 256;
StringBuilder cookieData = new StringBuilder(datasize);
if (!InternetGetCookieEx(uri, null, cookieData, ref datasize, INTERNET_COOKIE_HTTPONLY, null))
{
int er = Marshal.GetLastWin32Error();
if (er == ERROR_NO_MORE_ITEMS)
return new CookieContainer();
else
if (er == ERROR_INSUFFICIENT_BUFFER)
{
cookieData = new StringBuilder(datasize);
if (!InternetGetCookie(uri, null, cookieData, ref datasize))
return new CookieContainer();
}
else
if (er == ERROR_INVALID_PARAMETER)
throw new Exception("InternetGetCookie: Invalid Parameter submitted.");
else
throw new Exception(String.Format("InternetGetCookie: Error. (Error Code: {0})", er));
}
cookies = new CookieContainer();
cookies.SetCookies(new Uri(uri), cookieData.ToString().Replace(';', ','));
return cookies;
}*/
}
}
MyDownloader.Core/Common/DateTimeExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyDownloader.Core.Common
{
public static class DateTimeExtension
{
public static int ToUnixTime(this DateTime time)
{
TimeSpan span = (time - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
return (int)span.TotalSeconds;
}
public static DateTime FromUnixTime(double timestamp)
{
DateTime converted = new DateTime(1970, 1, 1, 0, 0, 0, 0);
DateTime newDateTime = converted.AddSeconds(timestamp);
return newDateTime.ToUniversalTime();
}
}
}
MyDownloader.Core/Common/PathHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.Core.Common
{
public static class PathHelper
{
public static string GetWithBackslash(string path)
{
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
path += Path.DirectorySeparatorChar.ToString();
}
return path;
}
}
}
MyDownloader.Core/Common/SQLiteDatabase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Windows.Forms;
// Copied library from http://www.dreamincode.net/forums/topic/157830-using-sqlite-with-c%23/
namespace MyDownloader.Core.Common
{
class SQLiteDatabase
{
String dbConnection;
/// <summary>
/// Default Constructor for SQLiteDatabase Class.
/// </summary>
public SQLiteDatabase()
{
dbConnection = "Data Source=recipes.s3db";
}
/// <summary>
/// Single Param Constructor for specifying the DB file.
/// </summary>
/// <param name="inputFile">The File containing the DB</param>
public SQLiteDatabase(String inputFile)
{
dbConnection = String.Format("Data Source={0}", inputFile);
}
/// <summary>
/// Single Param Constructor for specifying advanced connection options.
/// </summary>
/// <param name="connectionOpts">A dictionary containing all desired options and their values</param>
public SQLiteDatabase(Dictionary<String, String> connectionOpts)
{
String str = "";
foreach (KeyValuePair<String, String> row in connectionOpts)
{
str += String.Format("{0}={1}; ", row.Key, row.Value);
}
str = str.Trim().Substring(0, str.Length - 1);
dbConnection = str;
}
/// <summary>
/// Allows the programmer to run a query against the Database.
/// </summary>
/// <param name="sql">The SQL to run</param>
/// <returns>A DataTable containing the result set.</returns>
public DataTable GetDataTable(string sql)
{
DataTable dt = new DataTable();
try
{
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
SQLiteDataReader reader = mycommand.ExecuteReader();
dt.Load(reader);
reader.Close();
mycommand.Dispose();
cnn.Close();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
return dt;
}
/// <summary>
/// Allows the programmer to interact with the database for purposes other than a query.
/// </summary>
/// <param name="sql">The SQL to be run.</param>
/// <returns>An Integer containing the number of rows updated.</returns>
public int ExecuteNonQuery(string sql)
{
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
int rowsUpdated = mycommand.ExecuteNonQuery();
cnn.Close();
return rowsUpdated;
}
/// <summary>
/// Allows the programmer to retrieve single items from the DB.
/// </summary>
/// <param name="sql">The query to run.</param>
/// <returns>A string.</returns>
public string ExecuteScalar(string sql)
{
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
object value = mycommand.ExecuteScalar();
cnn.Close();
if (value != null)
{
return value.ToString();
}
return "";
}
/// <summary>
/// Allows the programmer to easily update rows in the DB.
/// </summary>
/// <param name="tableName">The table to update.</param>
/// <param name="data">A dictionary containing Column names and their new values.</param>
/// <param name="where">The where clause for the update statement.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Update(String tableName, Dictionary<String, String> data, String where)
{
String vals = "";
Boolean returnCode = true;
if (data.Count >= 1)
{
foreach (KeyValuePair<String, String> val in data)
{
vals += String.Format(" {0} = '{1}',", val.Key.ToString(), val.Value.ToString());
}
vals = vals.Substring(0, vals.Length - 1);
}
try
{
this.ExecuteNonQuery(String.Format("update {0} set {1} where {2};", tableName, vals, where));
}
catch
{
returnCode = false;
}
return returnCode;
}
/// <summary>
/// Allows the programmer to easily delete rows from the DB.
/// </summary>
/// <param name="tableName">The table from which to delete.</param>
/// <param name="where">The where clause for the delete.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Delete(String tableName, String where)
{
Boolean returnCode = true;
try
{
this.ExecuteNonQuery(String.Format("delete from {0} where {1};", tableName, where));
}
catch (Exception fail)
{
MessageBox.Show(fail.Message);
returnCode = false;
}
return returnCode;
}
/// <summary>
/// Allows the programmer to easily insert into the DB
/// </summary>
/// <param name="tableName">The table into which we insert the data.</param>
/// <param name="data">A dictionary containing the column names and data for the insert.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Insert(String tableName, Dictionary<String, String> data)
{
String columns = "";
String values = "";
Boolean returnCode = true;
foreach (KeyValuePair<String, String> val in data)
{
columns += String.Format(" {0},", val.Key.ToString());
values += String.Format(" '{0}',", val.Value);
}
columns = columns.Substring(0, columns.Length - 1);
values = values.Substring(0, values.Length - 1);
try
{
this.ExecuteNonQuery(String.Format("insert into {0}({1}) values({2});", tableName, columns, values));
}
catch (Exception fail)
{
MessageBox.Show(fail.Message);
returnCode = false;
}
return returnCode;
}
/// <summary>
/// Allows the programmer to easily delete all data from the DB.
/// </summary>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool ClearDB()
{
DataTable tables;
try
{
tables = this.GetDataTable("select NAME from SQLITE_MASTER where type='table' order by NAME;");
foreach (DataRow table in tables.Rows)
{
this.ClearTable(table["NAME"].ToString());
}
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Allows the user to easily clear all data from a specific table.
/// </summary>
/// <param name="table">The name of the table to clear.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool ClearTable(String table)
{
try
{
this.ExecuteNonQuery(String.Format("delete from {0};", table));
return true;
}
catch
{
return false;
}
}
}
}
MyDownloader.Core/Common/TimeSpanFormatter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core.Common
{
public static class TimeSpanFormatter
{
public static string ToString(TimeSpan ts)
{
if (ts == TimeSpan.MaxValue)
{
return "?";
}
string str = ts.ToString();
int index = str.LastIndexOf('.');
if (index > 0)
{
return str.Remove(index);
}
else
{
return str;
}
}
}
}
MyDownloader.Core/Concurrency/ObjectLocker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MyDownloader.Core.Concurrency
{
public class ObjectLocker : IDisposable
{
#region Fields
private object obj;
#endregion
#region Constructor
public ObjectLocker(object obj)
{
this.obj = obj;
Monitor.Enter(this.obj);
}
#endregion
#region IDisposable Members
public void Dispose()
{
Monitor.Exit(this.obj);
}
#endregion
}
}
MyDownloader.Core/Concurrency/ReaderWriterObjectLocker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MyDownloader.Core.Concurrency
{
public class ReaderWriterObjectLocker
{
#region BaseReleaser
class BaseReleaser
{
protected ReaderWriterObjectLocker locker;
public BaseReleaser(ReaderWriterObjectLocker locker)
{
this.locker = locker;
}
}
#endregion
#region ReaderReleaser
class ReaderReleaser : BaseReleaser, IDisposable
{
public ReaderReleaser(ReaderWriterObjectLocker locker)
: base(locker)
{
}
#region IDisposable Members
public void Dispose()
{
locker.locker.ReleaseReaderLock();
}
#endregion
}
#endregion
#region WriterReleaser
class WriterReleaser : BaseReleaser, IDisposable
{
public WriterReleaser(ReaderWriterObjectLocker locker)
: base(locker)
{
}
#region IDisposable Members
public void Dispose()
{
locker.locker.ReleaseWriterLock();
}
#endregion
}
#endregion
#region Fields
private ReaderWriterLock locker;
private IDisposable writerReleaser;
private IDisposable readerReleaser;
#endregion
#region Constructor
public ReaderWriterObjectLocker()
{
// TODO: update to ReaderWriterLockSlim on .net 3.5
locker = new ReaderWriterLock();
writerReleaser = new WriterReleaser(this);
readerReleaser = new ReaderReleaser(this);
}
#endregion
#region Methods
public IDisposable LockForRead()
{
locker.AcquireReaderLock(-1);
return readerReleaser;
}
public IDisposable LockForWrite()
{
locker.AcquireWriterLock(-1);
return writerReleaser;
}
#endregion
}
}
MyDownloader.Core/DownloadManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections;
using System.Threading;
using MyDownloader.Core.Concurrency;
namespace MyDownloader.Core
{
public class DownloadManager
{
#region Singleton
private static DownloadManager instance = new DownloadManager();
public static DownloadManager Instance
{
get
{
return instance;
}
}
#endregion
#region Fields
private List<Downloader> downloads = new List<Downloader>();
private int addBatchCount;
private ReaderWriterObjectLocker downloadListSync = new ReaderWriterObjectLocker();
private int maxSimultaneusDownloads = 10;
#endregion
#region Properties
public event EventHandler BeginAddBatchDownloads;
public event EventHandler EndAddBatchDownloads;
public event EventHandler<DownloaderEventArgs> DownloadEnded;
public event EventHandler<DownloaderEventArgs> DownloadAdded;
public event EventHandler<DownloaderEventArgs> DownloadRemoved;
public ReadOnlyCollection<Downloader> Downloads
{
get
{
return downloads.AsReadOnly();
}
}
public double TotalDownloadRate
{
get
{
double total = 0;
using (LockDownloadList(false))
{
for (int i = 0; i < this.Downloads.Count; i++)
{
if (this.Downloads[i].State == DownloaderState.Working)
{
total += this.Downloads[i].Rate;
}
}
}
return total;
}
}
public int AddBatchCount
{
get
{
return addBatchCount;
}
}
#endregion
#region Methods
void downloader_StateChanged(object sender, EventArgs e)
{
Downloader downloader = (Downloader)sender;
if (downloader.State == DownloaderState.Ended ||
downloader.State == DownloaderState.EndedWithError)
{
OnDownloadEnded((Downloader)sender);
}
}
public IDisposable LockDownloadList(bool lockForWrite)
{
if (lockForWrite)
{
return downloadListSync.LockForWrite();
}
else
{
return downloadListSync.LockForRead();
}
}
public void RemoveDownload(int index)
{
RemoveDownload(downloads[index]);
}
public void RemoveDownload(Downloader downloader)
{
if (downloader.State != DownloaderState.NeedToPrepare ||
downloader.State != DownloaderState.Ended ||
downloader.State != DownloaderState.Paused)
{
downloader.Pause();
}
using (LockDownloadList(true))
{
downloads.Remove(downloader);
}
OnDownloadRemoved(downloader);
}
public void ClearEnded()
{
using (LockDownloadList(true))
{
for (int i = downloads.Count - 1; i >= 0; i--)
{
if (downloads[i].State == DownloaderState.Ended)
{
Downloader d = downloads[i];
downloads.RemoveAt(i);
OnDownloadRemoved(d);
}
}
}
}
public void PauseAll()
{
using (LockDownloadList(false))
{
for (int i = 0; i < this.Downloads.Count; i++)
{
this.Downloads[i].Pause();
}
}
}
public Downloader Add(ResourceLocation rl, ResourceLocation[] mirrors, string localFile, int segments, bool autoStart)
{
Downloader d = new Downloader(rl, mirrors, localFile, segments);
Add(d, autoStart);
return d;
}
public Downloader Add(ResourceLocation rl, ResourceLocation[] mirrors, string localFile, List<Segment> segments, RemoteFileInfo remoteInfo, int requestedSegmentCount, bool autoStart, DateTime createdDateTime)
{
Downloader d = new Downloader(rl, mirrors, localFile, segments, remoteInfo, requestedSegmentCount, createdDateTime);
Add(d, autoStart);
return d;
}
public void Add(Downloader downloader, bool autoStart)
{
downloader.StateChanged += new EventHandler(downloader_StateChanged);
using (LockDownloadList(true))
{
downloads.Add(downloader);
}
OnDownloadAdded(downloader, autoStart);
if (autoStart)
downloader.ScheduleState = DownloaderScheduleState.Waiting;
else
downloader.ScheduleState = DownloaderScheduleState.Paused;
//if (autoStart)
//{
// downloader.Start();
//}
StartNextDownload();
}
public void StartNextDownload()
{
int cnt = 0;
foreach (Downloader d in downloads)
if (d.ScheduleState == DownloaderScheduleState.Working)
cnt++;
if(cnt>=maxSimultaneusDownloads)
return;
foreach (Downloader d in downloads)
{
if (d.ScheduleState == DownloaderScheduleState.Waiting)
{
d.Start();
Thread.Sleep(500);
return;
}
}
}
public virtual void OnBeginAddBatchDownloads()
{
addBatchCount++;
if (BeginAddBatchDownloads != null)
{
BeginAddBatchDownloads(this, EventArgs.Empty);
}
}
public virtual void OnEndAddBatchDownloads()
{
addBatchCount--;
if (EndAddBatchDownloads != null)
{
EndAddBatchDownloads(this, EventArgs.Empty);
}
}
protected virtual void OnDownloadEnded(Downloader d)
{
StartNextDownload();
if (DownloadEnded != null)
{
DownloadEnded(this, new DownloaderEventArgs(d));
}
}
protected virtual void OnDownloadAdded(Downloader d, bool willStart)
{
if (DownloadAdded != null)
{
DownloadAdded(this, new DownloaderEventArgs(d, willStart));
}
}
protected virtual void OnDownloadRemoved(Downloader d)
{
if (DownloadRemoved != null)
{
DownloadRemoved(this, new DownloaderEventArgs(d));
}
}
public void SwapDownloads(int idx, bool isThreadSafe)
{
if (isThreadSafe)
{
InternalSwap(idx);
}
else
{
using (LockDownloadList(true))
{
InternalSwap(idx);
}
}
}
private void InternalSwap(int idx)
{
if (this.downloads.Count <= idx)
{
//return;
}
Downloader it1 = this.downloads[idx];
Downloader it2 = this.downloads[idx - 1];
this.downloads.RemoveAt(idx);
this.downloads.RemoveAt(idx - 1);
this.downloads.Insert(idx - 1, it1);
this.downloads.Insert(idx, it2);
}
#endregion
}
}
MyDownloader.Core/Downloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Collections;
using System.Net;
using MyDownloader.Core.Concurrency;
using MyDownloader.Core.Common;
namespace MyDownloader.Core
{
public class Downloader
{
private string localFile;
private int requestedSegmentCount;
private ResourceLocation resourceLocation;
private List<ResourceLocation> mirrors;
private List<Segment> segments;
private Thread mainThread;
private List<Thread> threads;
private RemoteFileInfo remoteFileInfo;
private DownloaderState state;
public DownloaderScheduleState ScheduleState;
private DateTime createdDateTime;
private Exception lastError;
private Dictionary<string, object> extentedProperties = new Dictionary<string, object>();
private IProtocolProvider defaultDownloadProvider;
private ISegmentCalculator segmentCalculator;
private IMirrorSelector mirrorSelector;
//private CookieContainer cookieContainer;
private string statusMessage;
private Downloader(
ResourceLocation rl,
ResourceLocation[] mirrors,
string localFile)
{
//this.cookieContainer = new CookieContainer();
this.threads = new List<Thread>();
this.resourceLocation = rl;
if (mirrors == null)
{
this.mirrors = new List<ResourceLocation>();
}
else
{
this.mirrors = new List<ResourceLocation>(mirrors);
}
this.localFile = localFile;
extentedProperties = new Dictionary<string, object>();
defaultDownloadProvider = rl.BindProtocolProviderInstance(this);
segmentCalculator = new MinSizeSegmentCalculator();
this.MirrorSelector = new SequentialMirrorSelector();
}
public Downloader(
ResourceLocation rl,
ResourceLocation[] mirrors,
string localFile,
int segmentCount):
this(rl, mirrors, localFile)
{
SetState(DownloaderState.NeedToPrepare);
this.createdDateTime = DateTime.Now;
this.requestedSegmentCount = segmentCount;
this.segments = new List<Segment>();
}
public Downloader(
ResourceLocation rl,
ResourceLocation[] mirrors,
string localFile,
List<Segment> segments,
RemoteFileInfo remoteInfo,
int requestedSegmentCount,
DateTime createdDateTime):
this(rl, mirrors, localFile)
{
if (segments.Count > 0)
{
SetState(DownloaderState.Prepared);
}
else
{
SetState(DownloaderState.NeedToPrepare);
}
this.createdDateTime = createdDateTime;
this.remoteFileInfo = remoteInfo;
this.requestedSegmentCount = requestedSegmentCount;
this.segments = segments;
}
#region Properties
public event EventHandler Ending;
public event EventHandler InfoReceived;
public event EventHandler StateChanged;
public event EventHandler<SegmentEventArgs> RestartingSegment;
public event EventHandler<SegmentEventArgs> SegmentStoped;
public event EventHandler<SegmentEventArgs> SegmentStarting;
public event EventHandler<SegmentEventArgs> SegmentStarted;
public event EventHandler<SegmentEventArgs> SegmentFailed;
public Dictionary<string, object> ExtendedProperties
{
get { return extentedProperties; }
}
public ResourceLocation ResourceLocation
{
get
{
return this.resourceLocation;
}
}
public List<ResourceLocation> Mirrors
{
get
{
return this.mirrors;
}
}
public string FileName
{
get { return localFile.Substring(localFile.LastIndexOf("\\")+1); }
}
public long FileSize
{
get
{
if (remoteFileInfo == null)
{
return 0;
}
return remoteFileInfo.FileSize;
}
}
public DateTime CreatedDateTime
{
get
{
return createdDateTime;
}
}
public int RequestedSegments
{
get
{
return requestedSegmentCount;
}
}
public string LocalFile
{
get
{
return this.localFile;
}
}
public double Progress
{
get
{
int count = segments.Count;
if (count > 0)
{
double progress = 0;
for (int i = 0; i < count; i++)
{
progress += segments[i].Progress;
}
return progress / count;
}
else
{
return 0;
}
}
}
public double Rate
{
get
{
double rate = 0;
for (int i = 0; i < segments.Count; i++)
{
rate += segments[i].Rate;
}
return rate;
}
}
public long Transfered
{
get
{
long transfered = 0;
for (int i = 0; i < segments.Count; i++)
{
transfered += segments[i].Transfered;
}
return transfered;
}
}
//public CookieContainer CookieContainer
//{
// get
// {
// return cookieContainer;
// }
// set
// {
// cookieContainer = value;
// }
//}
public TimeSpan Left
{
get
{
if (this.Rate == 0)
{
return TimeSpan.MaxValue;
}
double missingTransfer = 0;
for (int i = 0; i < segments.Count; i++)
{
missingTransfer += segments[i].MissingTransfer;
}
return TimeSpan.FromSeconds(missingTransfer / this.Rate);
}
}
public List<Segment> Segments
{
get
{
return segments;
}
}
public Exception LastError
{
get { return lastError; }
set { lastError = value; }
}
public DownloaderState State
{
get { return state; }
}
public bool IsWorking()
{
DownloaderState state = this.State;
return (state == DownloaderState.Preparing ||
state == DownloaderState.WaitingForReconnect ||
state == DownloaderState.Working);
}
public RemoteFileInfo RemoteFileInfo
{
get { return remoteFileInfo; }
}
public string StatusMessage
{
get { return statusMessage; }
set { statusMessage = value; }
}
public ISegmentCalculator SegmentCalculator
{
get { return segmentCalculator; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
segmentCalculator = value;
}
}
public IMirrorSelector MirrorSelector
{
get { return mirrorSelector; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
mirrorSelector = value;
mirrorSelector.Init(this);
}
}
#endregion
private void SetState(DownloaderState value)
{
state = value;
if (state == DownloaderState.EndedWithError)
ScheduleState = DownloaderScheduleState.Error;
OnStateChanged();
}
private void StartToPrepare()
{
mainThread = new Thread(new ParameterizedThreadStart(StartDownloadThreadProc));
mainThread.Start(requestedSegmentCount);
}
private void StartPrepared()
{
mainThread = new Thread(new ThreadStart(RestartDownload));
mainThread.Start();
}
protected virtual void OnRestartingSegment(Segment segment)
{
if (RestartingSegment != null)
{
RestartingSegment(this, new SegmentEventArgs(this, segment));
}
}
protected virtual void OnSegmentStoped(Segment segment)
{
if (SegmentStoped != null)
{
SegmentStoped(this, new SegmentEventArgs(this, segment));
}
}
protected virtual void OnSegmentFailed(Segment segment)
{
if (SegmentFailed != null)
{
SegmentFailed(this, new SegmentEventArgs(this, segment));
}
}
protected virtual void OnSegmentStarting(Segment segment)
{
if (SegmentStarting != null)
{
SegmentStarting(this, new SegmentEventArgs(this, segment));
}
}
protected virtual void OnSegmentStarted(Segment segment)
{
if (SegmentStarted != null)
{
SegmentStarted(this, new SegmentEventArgs(this, segment));
}
}
protected virtual void OnStateChanged()
{
if (StateChanged != null)
{
StateChanged(this, EventArgs.Empty);
}
}
protected virtual void OnEnding()
{
ScheduleState = DownloaderScheduleState.Ended;
if (Ending != null)
{
Ending(this, EventArgs.Empty);
}
}
protected virtual void OnInfoReceived()
{
if (InfoReceived != null)
{
InfoReceived(this, EventArgs.Empty);
}
}
public IDisposable LockSegments()
{
return new ObjectLocker(this.segments);
}
public void WaitForConclusion()
{
if (! IsWorking())
{
if (mainThread != null && mainThread.IsAlive)
{
mainThread.Join(TimeSpan.FromSeconds(1));
}
}
while (IsWorking())
{
Thread.Sleep(100);
}
Debug.WriteLine(this.State.ToString());
}
public void Pause()
{
ScheduleState = DownloaderScheduleState.Paused;
if (state == DownloaderState.Preparing || state == DownloaderState.WaitingForReconnect)
{
Segments.Clear();
mainThread.Abort();
mainThread = null;
SetState(DownloaderState.NeedToPrepare);
return;
}
if (state == DownloaderState.Working)
{
SetState(DownloaderState.Pausing);
while (!AllWorkersStopped(5))
;
lock (threads)
{
threads.Clear();
}
mainThread.Abort();
mainThread = null;
if (RemoteFileInfo != null && !RemoteFileInfo.AcceptRanges)
{
// reset the segment
Segments[0].StartPosition = 0;
}
SetState(DownloaderState.Paused);
}
}
public void Start()
{
ScheduleState = DownloaderScheduleState.Working;
if (state == DownloaderState.NeedToPrepare)
{
SetState(DownloaderState.Preparing);
StartToPrepare();
}
else if (
state != DownloaderState.Preparing &&
state != DownloaderState.Pausing &&
state != DownloaderState.Working &&
state != DownloaderState.WaitingForReconnect)
{
SetState(DownloaderState.Preparing);
StartPrepared();
}
}
private void AllocLocalFile()
{
if(this.LocalFile.EndsWith("/"))
this.localFile = this.localFile.Substring(0, this.localFile.Length - 1) + this.remoteFileInfo.FileName;
else
if(this.LocalFile.EndsWith("\\"))
this.localFile += this.remoteFileInfo.FileName;
FileInfo fileInfo = new FileInfo(this.LocalFile);
if (!Directory.Exists(fileInfo.DirectoryName))
{
Directory.CreateDirectory(fileInfo.DirectoryName);
}
if (fileInfo.Exists)
{
// auto rename the file...
int count = 1;
string fileExitWithoutExt = Path.GetFileNameWithoutExtension(this.LocalFile);
string ext = Path.GetExtension(this.LocalFile);
string newFileName;
do
{
newFileName = PathHelper.GetWithBackslash(fileInfo.DirectoryName)
+ fileExitWithoutExt + String.Format("({0})", count++) + ext;
}
while (File.Exists(newFileName));
this.localFile = newFileName;
}
using (FileStream fs = new FileStream(this.LocalFile, FileMode.Create, FileAccess.Write))
{
fs.SetLength(Math.Max(this.FileSize, 0));
}
}
private void StartDownloadThreadProc(object objSegmentCount)
{
SetState(DownloaderState.Preparing);
int segmentCount = Math.Min((int)objSegmentCount, Settings.Default.MaxSegments);
Stream inputStream = null;
int currentTry = 0;
do
{
lastError = null;
if (state == DownloaderState.Pausing)
{
SetState(DownloaderState.NeedToPrepare);
return;
}
SetState(DownloaderState.Preparing);
currentTry++;
try
{
remoteFileInfo = defaultDownloadProvider.GetFileInfo(this.ResourceLocation, out inputStream);
break;
}
catch (ThreadAbortException)
{
SetState(DownloaderState.NeedToPrepare);
return;
}
catch (Exception ex)
{
lastError = ex;
if (currentTry < Settings.Default.MaxRetries)
{
SetState(DownloaderState.WaitingForReconnect);
Thread.Sleep(TimeSpan.FromSeconds(Settings.Default.RetryDelay));
}
else
{
SetState(DownloaderState.NeedToPrepare);
return;
}
}
}
while (true);
try
{
lastError = null;
StartSegments(segmentCount, inputStream);
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
lastError = ex;
SetState(DownloaderState.EndedWithError);
}
}
private void StartSegments(int segmentCount, Stream inputStream)
{
// notifies
OnInfoReceived();
// allocs the file on disk
AllocLocalFile();
if (this.segments.Count==0)
{
long segmentSize;
CalculatedSegment[] calculatedSegments;
if (!remoteFileInfo.AcceptRanges)
{
calculatedSegments = new CalculatedSegment[] { new CalculatedSegment(0, remoteFileInfo.FileSize) };
}
else
{
calculatedSegments = this.SegmentCalculator.GetSegments(segmentCount, remoteFileInfo);
}
lock (threads) threads.Clear();
lock (segments) segments.Clear();
for (int i = 0; i < calculatedSegments.Length; i++)
{
Segment segment = new Segment();
if (i == 0)
{
segment.InputStream = inputStream;
}
segment.Index = i;
segment.InitialStartPosition = calculatedSegments[i].StartPosition;
segment.StartPosition = calculatedSegments[i].StartPosition;
segment.EndPosition = calculatedSegments[i].EndPosition;
segments.Add(segment);
}
}
RunSegments();
}
private void RestartDownload()
{
int currentTry = 0;
Stream stream;
RemoteFileInfo newInfo;
try
{
do
{
lastError = null;
SetState(DownloaderState.Preparing);
currentTry++;
try
{
newInfo = defaultDownloadProvider.GetFileInfo(this.ResourceLocation, out stream);
break;
}
catch (Exception ex)
{
lastError = ex;
if (currentTry < Settings.Default.MaxRetries)
{
SetState(DownloaderState.WaitingForReconnect);
Thread.Sleep(TimeSpan.FromSeconds(Settings.Default.RetryDelay));
}
else
{
return;
}
}
}
while (true);
}
finally
{
SetState(DownloaderState.Prepared);
}
try
{
// check if the file changed on the server
if (!newInfo.AcceptRanges ||
newInfo.LastModified > RemoteFileInfo.LastModified ||
newInfo.FileSize != RemoteFileInfo.FileSize)
{
this.remoteFileInfo = newInfo;
StartSegments(this.RequestedSegments, stream);
}
else
{
if (stream != null)
{
stream.Dispose();
}
RunSegments();
}
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
lastError = ex;
SetState(DownloaderState.EndedWithError);
}
}
private void RunSegments()
{
SetState(DownloaderState.Working);
// TODO comparar o remote file Info se esta igual, se o download saiu de paused/prepared
// e nao veio da thread que le o fileinfo
using (FileStream fs = new FileStream(this.LocalFile, FileMode.Open, FileAccess.Write))
{
for (int i = 0; i < this.Segments.Count; i++)
{
Segments[i].OutputStream = fs;
StartSegment(Segments[i]);
}
do
{
while (!AllWorkersStopped(1000))
;
}
while (RestartFailedSegments());
}
for (int i = 0; i < this.Segments.Count; i++)
{
if (Segments[i].State == SegmentState.Error)
{
SetState(DownloaderState.EndedWithError);
return;
}
}
if (this.State != DownloaderState.Pausing)
{
OnEnding();
}
SetState(DownloaderState.Ended);
}
private bool RestartFailedSegments()
{
bool hasErrors = false;
double delay = 0;
for (int i = 0; i < this.Segments.Count; i++)
{
if (Segments[i].State == SegmentState.Error &&
Segments[i].LastErrorDateTime != DateTime.MinValue &&
(Settings.Default.MaxRetries == 0 ||
Segments[i].CurrentTry < Settings.Default.MaxRetries))
{
hasErrors = true;
TimeSpan ts = DateTime.Now - Segments[i].LastErrorDateTime;
if (ts.TotalSeconds >= Settings.Default.RetryDelay)
{
Segments[i].CurrentTry++;
StartSegment(Segments[i]);
OnRestartingSegment(Segments[i]);
}
else
{
delay = Math.Max(delay, Settings.Default.RetryDelay * 1000 - ts.TotalMilliseconds);
}
}
}
Thread.Sleep((int)delay);
return hasErrors;
}
private void StartSegment(Segment newSegment)
{
Thread segmentThread = new Thread(new ParameterizedThreadStart(SegmentThreadProc));
segmentThread.Start(newSegment);
lock (threads)
{
threads.Add(segmentThread);
}
}
private bool AllWorkersStopped(int timeOut)
{
bool allFinished = true;
Thread[] workers;
lock (threads)
{
workers = threads.ToArray();
}
foreach (Thread t in workers)
{
bool finished = t.Join(timeOut);
allFinished = allFinished & finished;
if (finished)
{
lock (threads)
{
threads.Remove(t);
}
}
}
return allFinished;
}
private void SegmentThreadProc(object objSegment)
{
Segment segment = (Segment)objSegment;
segment.LastError = null;
try
{
if (segment.EndPosition > 0 && segment.StartPosition >= segment.EndPosition)
{
segment.State = SegmentState.Finished;
// raise the event
OnSegmentStoped(segment);
return;
}
int buffSize = 8192;
byte[] buffer = new byte[buffSize];
segment.State = SegmentState.Connecting;
// raise the event
OnSegmentStarting(segment);
if (segment.InputStream == null)
{
// get the next URL (It can the the main url or some mirror)
ResourceLocation location = this.MirrorSelector.GetNextResourceLocation();
// get the protocol provider for that mirror
IProtocolProvider provider = location.BindProtocolProviderInstance(this);
while (location != this.ResourceLocation)
{
Stream tempStream;
// get the remote file info on mirror
RemoteFileInfo tempRemoteInfo = provider.GetFileInfo(location, out tempStream);
if (tempStream != null) tempStream.Dispose();
// check if the file on mirror is the same
if (tempRemoteInfo.FileSize == remoteFileInfo.FileSize &&
tempRemoteInfo.AcceptRanges == remoteFileInfo.AcceptRanges)
{
// if yes, stop looking for the mirror
break;
}
lock (mirrors)
{
// the file on the mirror is not the same, so remove from the mirror list
mirrors.Remove(location);
}
// the file on the mirror is different
// so get other mirror to use in the segment
location = this.MirrorSelector.GetNextResourceLocation();
provider = location.BindProtocolProviderInstance(this);
}
// get the input stream from start position
segment.InputStream = provider.CreateStream(location, segment.StartPosition, segment.EndPosition);
// change the segment URL to the mirror URL
segment.CurrentURL = location.URL;
}
else
{
// change the segment URL to the main URL
segment.CurrentURL = this.resourceLocation.URL;
}
using (segment.InputStream)
{
// raise the event
OnSegmentStarted(segment);
// change the segment state
segment.State = SegmentState.Downloading;
segment.CurrentTry = 0;
long readSize;
do
{
// reads the buffer from input stream
readSize = segment.InputStream.Read(buffer, 0, buffSize);
// check if the segment has reached the end
if (segment.EndPosition > 0 &&
segment.StartPosition + readSize > segment.EndPosition)
{
// adjust the 'readSize' to write only necessary bytes
readSize = (segment.EndPosition - segment.StartPosition);
if (readSize <= 0)
{
segment.StartPosition = segment.EndPosition;
break;
}
}
// locks the stream to avoid that other threads changes
// the position of stream while this thread is writing into the stream
lock (segment.OutputStream)
{
segment.OutputStream.Position = segment.StartPosition;
segment.OutputStream.Write(buffer, 0, (int)readSize);
}
// increse the start position of the segment and also calculates the rate
segment.IncreaseStartPosition(readSize);
// check if the stream has reached its end
if (segment.EndPosition > 0 && segment.StartPosition >= segment.EndPosition)
{
segment.StartPosition = segment.EndPosition;
break;
}
// check if the user have requested to pause the download
if (state == DownloaderState.Pausing)
{
segment.State = SegmentState.Paused;
break;
}
//Thread.Sleep(1500);
}
while (readSize > 0);
if (segment.State == SegmentState.Downloading)
{
segment.State = SegmentState.Finished;
// try to create other segment,
// spliting the missing bytes from one existing segment
AddNewSegmentIfNeeded();
}
}
// raise the event
OnSegmentStoped(segment);
}
catch (Exception ex)
{
// store the error information
segment.State = SegmentState.Error;
segment.LastError = ex;
Debug.WriteLine(ex.ToString());
// raise the event
OnSegmentFailed(segment);
}
finally
{
// clean up the segment
segment.InputStream = null;
}
}
private void AddNewSegmentIfNeeded()
{
lock (segments)
{
for (int i = 0; i < this.segments.Count; i++)
{
Segment oldSegment = this.segments[i];
if (oldSegment.State == SegmentState.Downloading &&
oldSegment.Left.TotalSeconds > Settings.Default.MinSegmentLeftToStartNewSegment &&
oldSegment.MissingTransfer / 2 >= Settings.Default.MinSegmentSize)
{
// get the half of missing size of oldSegment
long newSize = oldSegment.MissingTransfer / 2;
// create a new segment allocation the half old segment
Segment newSegment = new Segment();
newSegment.Index = this.segments.Count;
newSegment.StartPosition = oldSegment.StartPosition + newSize;
newSegment.InitialStartPosition = newSegment.StartPosition;
newSegment.EndPosition = oldSegment.EndPosition;
newSegment.OutputStream = oldSegment.OutputStream;
// removes bytes from old segments
oldSegment.EndPosition = oldSegment.EndPosition - newSize;
// add the new segment to the list
segments.Add(newSegment);
StartSegment(newSegment);
break;
}
}
}
}
}
}
MyDownloader.Core/DownloaderState.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
public enum DownloaderState: byte
{
NeedToPrepare = 0,
Preparing,
WaitingForReconnect,
Prepared,
Working,
Pausing,
Paused,
Ended,
EndedWithError
}
public enum DownloaderScheduleState : byte
{
Paused = 0,
Waiting,
Working,
Error,
Ended
}
}
MyDownloader.Core/EventArgs.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
#region ResolvingProtocolProviderEventArgs
public class ResolvingProtocolProviderEventArgs : EventArgs
{
#region Fields
private IProtocolProvider provider;
private string url;
#endregion
#region Constructor
public ResolvingProtocolProviderEventArgs(IProtocolProvider provider,
string url)
{
this.url = url;
this.provider = provider;
}
#endregion
#region Properties
public string URL
{
get { return url; }
}
public IProtocolProvider ProtocolProvider
{
get { return provider; }
set { provider = value; }
}
#endregion
}
#endregion
#region DownloaderEventArgs
public class DownloaderEventArgs : EventArgs
{
#region Fields
private Downloader downloader;
private bool willStart;
#endregion
#region Constructor
public DownloaderEventArgs(Downloader download)
{
this.downloader = download;
}
public DownloaderEventArgs(Downloader download, bool willStart): this(download)
{
this.willStart = willStart;
}
#endregion
#region Properties
public Downloader Downloader
{
get { return downloader; }
}
public bool WillStart
{
get { return willStart; }
}
#endregion
}
#endregion
#region SegmentEventArgs
public class SegmentEventArgs : DownloaderEventArgs
{
#region Fields
private Segment segment;
#endregion
#region Constructor
public SegmentEventArgs(Downloader d, Segment segment)
: base(d)
{
this.segment = segment;
}
#endregion
#region Properties
public Segment Segment
{
get { return segment; }
set { segment = value; }
}
#endregion
}
#endregion
}
MyDownloader.Core/Extensions/IExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
namespace MyDownloader.Core.Extensions
{
public interface IExtension
{
string Name { get; }
IUIExtension UIExtension { get; }
}
}
MyDownloader.Core/Extensions/IExtensionParameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace MyDownloader.Core.Extensions
{
public interface IExtensionParameters
{
event PropertyChangedEventHandler ParameterChanged;
}
}
MyDownloader.Core/Extensions/IInitializable.cs
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core.Extensions
{
public interface IInitializable
{
void Init();
}
}
MyDownloader.Core/Extensions/IUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Core.Extensions
{
public interface IUIExtension
{
Control[] CreateSettingsView();
void PersistSettings(Control[] settingsView);
}
}
MyDownloader.Core/IMirrorSelector.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
public interface IMirrorSelector
{
void Init(Downloader downloader);
ResourceLocation GetNextResourceLocation();
}
}
MyDownloader.Core/IProtocolProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.Core
{
public interface IProtocolProvider
{
void Initialize(Downloader downloader);
Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition);
RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream);
}
}
MyDownloader.Core/ISegmentCalculator.cs
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
public interface ISegmentCalculator
{
CalculatedSegment[] GetSegments(int segmentCount, RemoteFileInfo fileSize);
}
}
MyDownloader.Core/Instrumentation/MyStopwatch.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace MyDownloader.Core.Instrumentation
{
/// <summary>
/// MyStopwatch is a debbuging tool to count the amout of time used by an operation.
/// </summary>
public class MyStopwatch : IDisposable
{
#region Fields
private Stopwatch internalStopwatch;
private string name;
#endregion
#region Constructor
/// <summary>
/// Initializes the MyStopwatch
/// </summary>
/// <param name="name">The name of MyStopwatch</param>
public MyStopwatch(string name)
{
#if DEBUG
this.name = name;
internalStopwatch = new Stopwatch();
internalStopwatch.Start();
#endif
}
#endregion
#region Methods
/// <summary>
/// Disposes the MyStopwatch and writes into debug the amount of time used on the operation.
/// </summary>
public void Dispose()
{
#if DEBUG
internalStopwatch.Stop();
Debug.WriteLine(name + ": " + internalStopwatch.Elapsed);
#endif
}
#endregion
}
}
MyDownloader.Core/MinSizeSegmentCalculator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
public class MinSizeSegmentCalculator: ISegmentCalculator
{
#region ISegmentCalculator Members
public CalculatedSegment[] GetSegments(int segmentCount, RemoteFileInfo remoteFileInfo)
{
long minSize = Settings.Default.MinSegmentSize;
long segmentSize = remoteFileInfo.FileSize / (long)segmentCount;
while (segmentCount > 1 && segmentSize < minSize)
{
segmentCount--;
segmentSize = remoteFileInfo.FileSize / (long)segmentCount;
}
long startPosition = 0;
List<CalculatedSegment> segments = new List<CalculatedSegment>();
for (int i = 0; i < segmentCount; i++)
{
if (segmentCount - 1 == i)
{
// lvx bug?
//segments.Add(new CalculatedSegment(startPosition, remoteFileInfo.FileSize - 1));
segments.Add(new CalculatedSegment(startPosition, remoteFileInfo.FileSize));
}
else
{
segments.Add(new CalculatedSegment(startPosition, startPosition + (int)segmentSize));
}
startPosition = segments[segments.Count - 1].EndPosition;
}
return segments.ToArray();
}
#endregion
}
}
MyDownloader.Core/MyDownloader.Core.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E763345E-6696-4C53-8764-47E4ABD67DEF}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyDownloader.Core</RootNamespace>
<AssemblyName>MyDownloader.Core</AssemblyName>
<StartupObject>
</StartupObject>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="INIFileParser">
<HintPath>..\INIFileParser.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CalculatedSegment.cs" />
<Compile Include="Common\ArrayExtension.cs" />
<Compile Include="Common\BoolFormatter.cs" />
<Compile Include="Common\ByteFormatter.cs" />
<Compile Include="Common\CookieManager.cs" />
<Compile Include="Common\DateTimeExtension.cs" />
<Compile Include="Common\PathHelper.cs" />
<Compile Include="Common\SQLiteDatabase.cs" />
<Compile Include="Common\TimeSpanFormatter.cs" />
<Compile Include="Concurrency\ReaderWriterObjectLocker.cs" />
<Compile Include="EventArgs.cs" />
<Compile Include="Downloader.cs" />
<Compile Include="DownloaderState.cs" />
<Compile Include="DownloadManager.cs" />
<Compile Include="Extensions\IExtension.cs" />
<Compile Include="Extensions\IExtensionParameters.cs" />
<Compile Include="Extensions\IInitializable.cs" />
<Compile Include="Extensions\IUIExtension.cs" />
<Compile Include="IMirrorSelector.cs" />
<Compile Include="Instrumentation\MyStopwatch.cs" />
<Compile Include="IProtocolProvider.cs" />
<Compile Include="ISegmentCalculator.cs" />
<Compile Include="MinSizeSegmentCalculator.cs" />
<Compile Include="ResourceLocation.cs" />
<Compile Include="Concurrency\ObjectLocker.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProtocolProviderFactory.cs" />
<Compile Include="RemoteFileInfo.cs" />
<Compile Include="Segment.cs" />
<Compile Include="SegmentState.cs" />
<Compile Include="SequentialMirrorSelector.cs" />
<Compile Include="Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="UI\AppManager.cs" />
<Compile Include="UI\ClipboardHelper.cs" />
<Compile Include="UI\Connection.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\Connection.Designer.cs">
<DependentUpon>Connection.cs</DependentUpon>
</Compile>
<Compile Include="UI\CoreExtention.cs" />
<Compile Include="UI\CoreUIExtention.cs" />
<Compile Include="UI\DownloadFolder.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\DownloadFolder.Designer.cs">
<DependentUpon>DownloadFolder.cs</DependentUpon>
</Compile>
<Compile Include="UI\IApp.cs" />
<Compile Include="UI\Location.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\Location.Designer.cs">
<DependentUpon>Location.cs</DependentUpon>
</Compile>
<Compile Include="UI\WaitControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\WaitControl.Designer.cs">
<DependentUpon>WaitControl.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Settings.settings">
<Generator>PublicSettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="UI\Connection.resx">
<SubType>Designer</SubType>
<DependentUpon>Connection.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\DownloadFolder.resx">
<SubType>Designer</SubType>
<DependentUpon>DownloadFolder.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\Location.resx">
<DependentUpon>Location.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="UI\WaitControl.resx">
<SubType>Designer</SubType>
<DependentUpon>WaitControl.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="sqlite3.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
MyDownloader.Core/Properties/AssemblyInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("MyDownloader.Core")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Programmmers")]
[assembly: AssemblyProduct("MyDownloader.Core")]
[assembly: AssemblyCopyright("Copyright © Programmmers 2007")]
[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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("99822afd-3d8c-41e4-9481-578a49c9c0ae")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
MyDownloader.Core/ProtocolProviderFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace MyDownloader.Core
{
public static class ProtocolProviderFactory
{
private static Hashtable protocolHandlers = new Hashtable();
public static event EventHandler<ResolvingProtocolProviderEventArgs> ResolvingProtocolProvider;
public static void RegisterProtocolHandler(string prefix, Type protocolProvider)
{
protocolHandlers[prefix] = protocolProvider;
}
public static IProtocolProvider CreateProvider(string uri, Downloader downloader)
{
IProtocolProvider provider = InternalGetProvider(uri);
if (downloader != null)
{
provider.Initialize(downloader);
}
return provider;
}
public static IProtocolProvider GetProvider(string uri)
{
return InternalGetProvider(uri);
}
public static Type GetProviderType(string uri)
{
int index = uri.IndexOf("://");
if (index > 0)
{
string prefix = uri.Substring(0, index);
Type type = protocolHandlers[prefix] as Type;
return type;
}
else
{
return null;
}
}
public static IProtocolProvider CreateProvider(Type providerType, Downloader downloader)
{
IProtocolProvider provider = CreateFromType(providerType);
if (ResolvingProtocolProvider != null)
{
ResolvingProtocolProviderEventArgs e = new ResolvingProtocolProviderEventArgs(provider, null);
ResolvingProtocolProvider(null, e);
provider = e.ProtocolProvider;
}
if (downloader != null)
{
provider.Initialize(downloader);
}
return provider;
}
private static IProtocolProvider InternalGetProvider(string uri)
{
Type type = GetProviderType(uri);
IProtocolProvider provider = CreateFromType(type);
if (ResolvingProtocolProvider != null)
{
ResolvingProtocolProviderEventArgs e = new ResolvingProtocolProviderEventArgs(provider, uri);
ResolvingProtocolProvider(null, e);
provider = e.ProtocolProvider;
}
return provider;
}
private static IProtocolProvider CreateFromType(Type type)
{
IProtocolProvider provider = (IProtocolProvider)Activator.CreateInstance(type);
return provider;
}
}
}
MyDownloader.Core/RemoteFileInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
[Serializable]
public class RemoteFileInfo
{
private bool acceptRanges;
private long fileSize;
private string fileName;
private DateTime lastModified = DateTime.MinValue;
private string mimeType;
public string MimeType
{
get { return mimeType; }
set { mimeType = value; }
}
public string FileName
{
get { return fileName; }
set { fileName = value; }
}
public bool AcceptRanges
{
get { return acceptRanges; }
set { acceptRanges = value; }
}
public long FileSize
{
get { return fileSize; }
set { fileSize = value; }
}
public DateTime LastModified
{
get { return lastModified; }
set { lastModified = value; }
}
}
}
MyDownloader.Core/ResourceLocation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace MyDownloader.Core
{
[Serializable]
public class ResourceLocation
{
#region Fields
private string url;
private bool authenticate;
private string login;
private string password;
private Type protocolProviderType;
private IProtocolProvider provider;
#endregion
#region Constructor
public ResourceLocation()
{
}
public static ResourceLocation FromURL(string url)
{
ResourceLocation rl = new ResourceLocation();
rl.URL = url;
return rl;
}
public static ResourceLocation[] FromURLArray(string[] urls)
{
List<ResourceLocation> result = new List<ResourceLocation>();
for (int i = 0; i < urls.Length; i++)
{
if (IsURL(urls[i]))
{
result.Add(ResourceLocation.FromURL(urls[i]));
}
}
return result.ToArray();
}
public static ResourceLocation FromURL(
string url,
bool authenticate,
string login,
string password)
{
ResourceLocation rl = new ResourceLocation();
rl.URL = url;
rl.Authenticate = authenticate;
rl.Login = login;
rl.Password = password;
return rl;
}
#endregion
#region Properties
public string URL
{
get { return url; }
set
{
url = value;
BindProtocolProviderType();
}
}
public bool Authenticate
{
get { return authenticate; }
set { authenticate = value; }
}
public string Login
{
get { return login; }
set { login = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
public string ProtocolProviderType
{
get
{
if (protocolProviderType == null)
{
return null;
}
return protocolProviderType.AssemblyQualifiedName;
}
set
{
if (value == null)
{
BindProtocolProviderType();
}
else
{
protocolProviderType = Type.GetType(value);
}
}
}
#endregion
#region Methods
public IProtocolProvider GetProtocolProvider(Downloader downloader)
{
return BindProtocolProviderInstance(downloader);
}
public void BindProtocolProviderType()
{
provider = null;
if (! String.IsNullOrEmpty(this.URL))
{
protocolProviderType = ProtocolProviderFactory.GetProviderType(this.URL);
}
}
public IProtocolProvider BindProtocolProviderInstance(Downloader downloader)
{
if (protocolProviderType == null)
{
BindProtocolProviderType();
}
if (provider == null)
{
provider = ProtocolProviderFactory.CreateProvider(protocolProviderType, downloader);
}
return provider;
}
public ResourceLocation Clone()
{
return (ResourceLocation)this.MemberwiseClone();
}
public override string ToString()
{
return this.URL;
}
public static bool IsURL(string url)
{
Match m = Regex.Match(url, @"(?<Protocol>\w+):\/\/(?<Domain>[\w.]+\/?)\S*");
if (m.ToString() != string.Empty)
{
return true;
}
return false;
}
#endregion
}
}
MyDownloader.Core/Segment.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.Core
{
public class Segment
{
private long startPosition;
private int index;
private string currentURL;
private long initialStartPosition;
private long endPosition;
private Stream outputStream;
private Stream inputStream;
private Exception lastError;
private SegmentState state;
private bool started = false;
private DateTime lastReception = DateTime.MinValue;
private DateTime lastErrorDateTime = DateTime.MinValue;
private double rate;
private long start;
private TimeSpan left = TimeSpan.Zero;
private int currentTry;
public int CurrentTry
{
get { return currentTry; }
set { currentTry = value; }
}
public SegmentState State
{
get
{
return state;
}
set
{
state = value;
switch (state)
{
case SegmentState.Downloading:
BeginWork();
break;
case SegmentState.Connecting:
case SegmentState.Paused:
case SegmentState.Finished:
case SegmentState.Error:
rate = 0.0;
left = TimeSpan.Zero;
break;
}
}
}
public DateTime LastErrorDateTime
{
get
{
return lastErrorDateTime;
}
}
public Exception LastError
{
get
{
return lastError;
}
set
{
if (value != null)
{
lastErrorDateTime = DateTime.Now;
}
else
{
lastErrorDateTime = DateTime.MinValue;
}
lastError = value;
}
}
public int Index
{
get
{
return index;
}
set
{
index = value;
}
}
public long InitialStartPosition
{
get
{
return initialStartPosition;
}
set
{
initialStartPosition = value;
}
}
public long StartPosition
{
get
{
return startPosition;
}
set
{
startPosition = value;
}
}
public long Transfered
{
get
{
return this.StartPosition - this.InitialStartPosition;
}
}
public long TotalToTransfer
{
get
{
return (this.EndPosition <= 0? 0: this.EndPosition - this.InitialStartPosition);
}
}
public long MissingTransfer
{
get
{
return (this.EndPosition <= 0? 0: this.EndPosition - this.StartPosition);
}
}
public double Progress
{
get
{
return (this.EndPosition <= 0? 0: ((double)Transfered / (double)TotalToTransfer * 100.0f));
}
}
public long EndPosition
{
get
{
return endPosition;
}
set
{
endPosition = value;
}
}
public Stream OutputStream
{
get
{
return outputStream;
}
set
{
outputStream = value;
}
}
public Stream InputStream
{
get
{
return inputStream;
}
set
{
inputStream = value;
}
}
public string CurrentURL
{
get
{
return currentURL;
}
set
{
currentURL = value;
}
}
public double Rate
{
get
{
if (this.State == SegmentState.Downloading)
{
IncreaseStartPosition(0);
return rate;
}
else
{
return 0;
}
}
}
public TimeSpan Left
{
get
{
return left;
}
}
public void BeginWork()
{
start = startPosition;
lastReception = DateTime.Now;
started = true;
}
public void IncreaseStartPosition(long size)
{
lock (this)
{
DateTime now = DateTime.Now;
startPosition += size;
if (started)
{
TimeSpan ts = (now - lastReception);
if (ts.TotalSeconds == 0)
{
return;
}
// bytes per seconds
rate = ((double)(startPosition - start)) / ts.TotalSeconds;
if (rate > 0.0)
{
left = TimeSpan.FromSeconds(MissingTransfer / rate);
}
else
{
left = TimeSpan.MaxValue;
}
}
else
{
start = startPosition;
lastReception = now;
started = true;
}
}
}
}
}
MyDownloader.Core/SegmentState.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
public enum SegmentState
{
Idle,
Connecting,
Downloading,
Paused,
Finished,
Error,
}
}
MyDownloader.Core/SequentialMirrorSelector.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Core
{
public class SequentialMirrorSelector: IMirrorSelector
{
private Downloader downloader;
private int queryMirrorCount;
#region IMirrorSelector Members
public void Init(Downloader downloader)
{
queryMirrorCount = 0;
this.downloader = downloader;
}
public ResourceLocation GetNextResourceLocation()
{
if (downloader.Mirrors == null || downloader.Mirrors.Count == 0)
{
return this.downloader.ResourceLocation;
}
lock (downloader.Mirrors)
{
if (queryMirrorCount >= downloader.Mirrors.Count)
{
queryMirrorCount = 0;
return this.downloader.ResourceLocation;
}
return downloader.Mirrors[queryMirrorCount++];
}
}
#endregion
}
}
MyDownloader.Core/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Core {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
public 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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("200000")]
public long MinSegmentSize {
get {
return ((long)(this["MinSegmentSize"]));
}
set {
this["MinSegmentSize"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("30")]
public int MinSegmentLeftToStartNewSegment {
get {
return ((int)(this["MinSegmentLeftToStartNewSegment"]));
}
set {
this["MinSegmentLeftToStartNewSegment"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5")]
public int RetryDelay {
get {
return ((int)(this["RetryDelay"]));
}
set {
this["RetryDelay"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("10")]
public int MaxRetries {
get {
return ((int)(this["MaxRetries"]));
}
set {
this["MaxRetries"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5")]
public int MaxSegments {
get {
return ((int)(this["MaxSegments"]));
}
set {
this["MaxSegments"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string DownloadFolder {
get {
return ((string)(this["DownloadFolder"]));
}
set {
this["DownloadFolder"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool AutomaticFileName {
get {
return ((bool)(this["AutomaticFileName"]));
}
set {
this["AutomaticFileName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Internet Explorer")]
public string CookieSource {
get {
return ((string)(this["CookieSource"]));
}
set {
this["CookieSource"] = value;
}
}
}
}
MyDownloader.Core/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Core" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="MinSegmentSize" Type="System.Int64" Scope="User">
<Value Profile="(Default)">200000</Value>
</Setting>
<Setting Name="MinSegmentLeftToStartNewSegment" Type="System.Int32" Scope="User">
<Value Profile="(Default)">30</Value>
</Setting>
<Setting Name="RetryDelay" Type="System.Int32" Scope="User">
<Value Profile="(Default)">5</Value>
</Setting>
<Setting Name="MaxRetries" Type="System.Int32" Scope="User">
<Value Profile="(Default)">10</Value>
</Setting>
<Setting Name="MaxSegments" Type="System.Int32" Scope="User">
<Value Profile="(Default)">5</Value>
</Setting>
<Setting Name="DownloadFolder" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="AutomaticFileName" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="CookieSource" Type="System.String" Scope="User">
<Value Profile="(Default)">Internet Explorer</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Core/UI/AppManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.App;
namespace MyDownloader.Core.UI
{
public class AppManager
{
private AppManager()
{
}
private static AppManager instance = new AppManager();
public static AppManager Instance
{
get { return instance; }
}
private IApp application;
public IApp Application
{
get { return application; }
}
public void Initialize(IApp app)
{
this.application = app;
}
}
}
MyDownloader.Core/UI/ApplicationSettings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
namespace MyDownloader.Core.UI
{
partial class ApplicationSettings
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(4, 4);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(114, 17);
this.checkBox1.TabIndex = 0;
this.checkBox1.Text = "Start with windows";
this.checkBox1.UseVisualStyleBackColor = true;
//
// checkBox2
//
this.checkBox2.AutoSize = true;
this.checkBox2.Location = new System.Drawing.Point(4, 27);
this.checkBox2.Name = "checkBox2";
this.checkBox2.Size = new System.Drawing.Size(146, 17);
this.checkBox2.TabIndex = 1;
this.checkBox2.Text = "Start downloads at starup";
this.checkBox2.UseVisualStyleBackColor = true;
//
// Application
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.checkBox2);
this.Controls.Add(this.checkBox1);
this.Name = "Application";
this.Size = new System.Drawing.Size(214, 150);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.CheckBox checkBox2;
}
}
MyDownloader.Core/UI/ApplicationSettings.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Core.UI
{
public partial class ApplicationSettings : UserControl
{
public ApplicationSettings()
{
Text = "Application";
InitializeComponent();
}
}
}
MyDownloader.Core/UI/ApplicationSettings.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Core/UI/ClipboardHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Core.UI
{
public static class ClipboardHelper
{
public static string GetURLOnClipboard()
{
string url = string.Empty;
if (Clipboard.ContainsText())
{
string tempUrl = Clipboard.GetText();
if (ResourceLocation.IsURL(tempUrl))
{
url = tempUrl;
}
else
{
tempUrl = null;
}
}
return url;
}
}
}
MyDownloader.Core/UI/Connection.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
namespace MyDownloader.Core.UI
{
partial class Connection
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.numRetryDelay = new System.Windows.Forms.NumericUpDown();
this.label6 = new System.Windows.Forms.Label();
this.numMinSegSize = new System.Windows.Forms.NumericUpDown();
this.numMaxRetries = new System.Windows.Forms.NumericUpDown();
this.label3 = new System.Windows.Forms.Label();
this.lblMinSize = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.numMaxSegments = new System.Windows.Forms.NumericUpDown();
this.chkAutoFileName = new System.Windows.Forms.CheckBox();
this.cmbCookieSource = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numRetryDelay)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numMinSegSize)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numMaxRetries)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numMaxSegments)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(-3, 95);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(65, 13);
this.label1.TabIndex = 5;
this.label1.Text = "Retry Delay:";
//
// numRetryDelay
//
this.numRetryDelay.Location = new System.Drawing.Point(0, 112);
this.numRetryDelay.Name = "numRetryDelay";
this.numRetryDelay.Size = new System.Drawing.Size(96, 20);
this.numRetryDelay.TabIndex = 6;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(-3, 0);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(95, 13);
this.label6.TabIndex = 0;
this.label6.Text = "Min Segment Size:";
//
// numMinSegSize
//
this.numMinSegSize.Location = new System.Drawing.Point(0, 17);
this.numMinSegSize.Maximum = new decimal(new int[] {
2147483647,
0,
0,
0});
this.numMinSegSize.Name = "numMinSegSize";
this.numMinSegSize.Size = new System.Drawing.Size(116, 20);
this.numMinSegSize.TabIndex = 1;
this.numMinSegSize.ValueChanged += new System.EventHandler(this.numMinSegSize_ValueChanged);
//
// numMaxRetries
//
this.numMaxRetries.Location = new System.Drawing.Point(0, 160);
this.numMaxRetries.Name = "numMaxRetries";
this.numMaxRetries.Size = new System.Drawing.Size(96, 20);
this.numMaxRetries.TabIndex = 8;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(-3, 143);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(129, 13);
this.label3.TabIndex = 7;
this.label3.Text = "Max Retries (0 for infinite):";
//
// lblMinSize
//
this.lblMinSize.AutoSize = true;
this.lblMinSize.Location = new System.Drawing.Point(122, 19);
this.lblMinSize.Name = "lblMinSize";
this.lblMinSize.Size = new System.Drawing.Size(54, 13);
this.lblMinSize.TabIndex = 2;
this.lblMinSize.Text = "lblMinSize";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(-3, 48);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(80, 13);
this.label5.TabIndex = 3;
this.label5.Text = "Max Segments:";
//
// numMaxSegments
//
this.numMaxSegments.Location = new System.Drawing.Point(0, 65);
this.numMaxSegments.Maximum = new decimal(new int[] {
2147483647,
0,
0,
0});
this.numMaxSegments.Name = "numMaxSegments";
this.numMaxSegments.Size = new System.Drawing.Size(116, 20);
this.numMaxSegments.TabIndex = 4;
//
// chkAutoFileName
//
this.chkAutoFileName.AutoSize = true;
this.chkAutoFileName.Location = new System.Drawing.Point(3, 198);
this.chkAutoFileName.Name = "chkAutoFileName";
this.chkAutoFileName.Size = new System.Drawing.Size(172, 17);
this.chkAutoFileName.TabIndex = 9;
this.chkAutoFileName.Text = "Automatic File Name Detection";
this.chkAutoFileName.UseVisualStyleBackColor = true;
//
// cmbCookieSource
//
this.cmbCookieSource.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbCookieSource.FormattingEnabled = true;
this.cmbCookieSource.Items.AddRange(new object[] {
"Internet Explorer",
"Chrome",
"Firefox"});
this.cmbCookieSource.Location = new System.Drawing.Point(3, 231);
this.cmbCookieSource.Name = "cmbCookieSource";
this.cmbCookieSource.Size = new System.Drawing.Size(121, 21);
this.cmbCookieSource.TabIndex = 10;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(130, 234);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(93, 13);
this.label2.TabIndex = 11;
this.label2.Text = "Source of cookies";
//
// Connection
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label2);
this.Controls.Add(this.cmbCookieSource);
this.Controls.Add(this.chkAutoFileName);
this.Controls.Add(this.label5);
this.Controls.Add(this.numMaxSegments);
this.Controls.Add(this.numMaxRetries);
this.Controls.Add(this.label3);
this.Controls.Add(this.label1);
this.Controls.Add(this.lblMinSize);
this.Controls.Add(this.numRetryDelay);
this.Controls.Add(this.label6);
this.Controls.Add(this.numMinSegSize);
this.Name = "Connection";
this.Size = new System.Drawing.Size(363, 282);
this.Load += new System.EventHandler(this.Connection_Load);
((System.ComponentModel.ISupportInitialize)(this.numRetryDelay)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numMinSegSize)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numMaxRetries)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numMaxSegments)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown numRetryDelay;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.NumericUpDown numMinSegSize;
private System.Windows.Forms.NumericUpDown numMaxRetries;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label lblMinSize;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.NumericUpDown numMaxSegments;
private System.Windows.Forms.CheckBox chkAutoFileName;
private System.Windows.Forms.ComboBox cmbCookieSource;
private System.Windows.Forms.Label label2;
}
}
MyDownloader.Core/UI/Connection.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core.Common;
namespace MyDownloader.Core.UI
{
public partial class Connection : UserControl
{
public Connection()
{
Text = "Connection";
InitializeComponent();
numRetryDelay.Value = Settings.Default.RetryDelay;
numMaxRetries.Value = Settings.Default.MaxRetries;
numMinSegSize.Value = Settings.Default.MinSegmentSize;
numMaxSegments.Value = Settings.Default.MaxSegments;
chkAutoFileName.Checked = Settings.Default.AutomaticFileName;
cmbCookieSource.SelectedItem = Settings.Default.CookieSource;
UpdateControls();
}
public int RetryDelay
{
get
{
return (int)numRetryDelay.Value;
}
}
public int MaxRetries
{
get
{
return (int)numMaxRetries.Value;
}
}
public int MinSegmentSize
{
get
{
return (int)numMinSegSize.Value;
}
}
public int MaxSegments
{
get
{
return (int)numMaxSegments.Value;
}
}
public bool AutomaticFileName
{
get
{
return (bool)chkAutoFileName.Checked;
}
}
public string CookieSource
{
get
{
return (string)cmbCookieSource.SelectedItem;
}
}
private void numMinSegSize_ValueChanged(object sender, EventArgs e)
{
UpdateControls();
}
private void UpdateControls()
{
lblMinSize.Text = ByteFormatter.ToString((int)numMinSegSize.Value);
}
private void Connection_Load(object sender, EventArgs e)
{
}
}
}
MyDownloader.Core/UI/Connection.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Core/UI/CoreExtention.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
namespace MyDownloader.Core.UI
{
public class CoreExtention : IExtension
{
#region IExtension Members
public string Name
{
get { return "Core"; }
}
public IUIExtension UIExtension
{
get { return new CoreUIExtention(); }
}
#endregion
}
}
MyDownloader.Core/UI/CoreUIExtention.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
namespace MyDownloader.Core.UI
{
public class CoreUIExtention: IUIExtension
{
#region IUIExtension Members
public Control[] CreateSettingsView()
{
return new Control[] { new Connection(), new DownloadFolder() };
}
public void PersistSettings(System.Windows.Forms.Control[] settingsView)
{
Connection connection = (Connection)settingsView[0];
DownloadFolder downloadFolder = (DownloadFolder)settingsView[1];
Settings.Default.MaxRetries = connection.MaxRetries;
Settings.Default.MinSegmentSize = connection.MinSegmentSize;
Settings.Default.RetryDelay = connection.RetryDelay;
Settings.Default.MaxSegments = connection.MaxSegments;
Settings.Default.AutomaticFileName = connection.AutomaticFileName;
Settings.Default.CookieSource = connection.CookieSource;
Settings.Default.DownloadFolder = downloadFolder.Folder;
Settings.Default.Save();
}
#endregion
}
}
MyDownloader.Core/UI/DownloadFolder.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
namespace MyDownloader.Core.UI
{
partial class DownloadFolder
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnSelAV = new System.Windows.Forms.Button();
this.txtSaveTo = new System.Windows.Forms.TextBox();
this.lblText = new System.Windows.Forms.Label();
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
this.SuspendLayout();
//
// btnSelAV
//
this.btnSelAV.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnSelAV.Location = new System.Drawing.Point(321, 19);
this.btnSelAV.Name = "btnSelAV";
this.btnSelAV.Size = new System.Drawing.Size(26, 23);
this.btnSelAV.TabIndex = 2;
this.btnSelAV.Text = "...";
this.btnSelAV.UseVisualStyleBackColor = true;
this.btnSelAV.Click += new System.EventHandler(this.btnSelAV_Click);
//
// txtSaveTo
//
this.txtSaveTo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtSaveTo.Location = new System.Drawing.Point(0, 19);
this.txtSaveTo.Name = "txtSaveTo";
this.txtSaveTo.Size = new System.Drawing.Size(319, 20);
this.txtSaveTo.TabIndex = 1;
//
// lblText
//
this.lblText.AutoSize = true;
this.lblText.Location = new System.Drawing.Point(0, 2);
this.lblText.Name = "lblText";
this.lblText.Size = new System.Drawing.Size(122, 13);
this.lblText.TabIndex = 0;
this.lblText.Text = "Default download folder:";
//
// DownloadFolder
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnSelAV);
this.Controls.Add(this.txtSaveTo);
this.Controls.Add(this.lblText);
this.Name = "DownloadFolder";
this.Size = new System.Drawing.Size(347, 50);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnSelAV;
private System.Windows.Forms.TextBox txtSaveTo;
private System.Windows.Forms.Label lblText;
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
}
}
MyDownloader.Core/UI/DownloadFolder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core.Common;
namespace MyDownloader.Core.UI
{
public partial class DownloadFolder : UserControl
{
public DownloadFolder()
{
InitializeComponent();
Text = "Directory";
if (Settings.Default.DownloadFolder == "")
Settings.Default.DownloadFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
txtSaveTo.Text = Settings.Default.DownloadFolder;
}
public string LabelText
{
get
{
return lblText.Text;
}
set
{
lblText.Text = value;
}
}
public string Folder
{
get { return PathHelper.GetWithBackslash(txtSaveTo.Text); }
set { txtSaveTo.Text = value; }
}
private void btnSelAV_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
txtSaveTo.Text = folderBrowserDialog1.SelectedPath;
}
}
}
}
MyDownloader.Core/UI/DownloadFolder.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="folderBrowserDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
MyDownloader.Core/UI/IApp.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
namespace MyDownloader.App
{
public interface IApp: IDisposable
{
Form MainForm { get; }
NotifyIcon NotifyIcon { get; }
List<IExtension> Extensions { get; }
IExtension GetExtensionByType(Type type);
void Start(string[] args);
}
}
MyDownloader.Core/UI/Location.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
namespace MyDownloader.App.UI
{
partial class Location
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblURL = new System.Windows.Forms.Label();
this.txtURL = new System.Windows.Forms.TextBox();
this.txtPass = new System.Windows.Forms.TextBox();
this.lblPass = new System.Windows.Forms.Label();
this.txtLogin = new System.Windows.Forms.TextBox();
this.lblLogin = new System.Windows.Forms.Label();
this.chkLogin = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// lblURL
//
this.lblURL.AutoSize = true;
this.lblURL.Location = new System.Drawing.Point(0, 3);
this.lblURL.Name = "lblURL";
this.lblURL.Size = new System.Drawing.Size(29, 13);
this.lblURL.TabIndex = 0;
this.lblURL.Text = "URL";
//
// txtURL
//
this.txtURL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtURL.Location = new System.Drawing.Point(0, 19);
this.txtURL.Multiline = true;
this.txtURL.Name = "txtURL";
this.txtURL.Size = new System.Drawing.Size(450, 77);
this.txtURL.TabIndex = 1;
this.txtURL.Text = "http://localhost/servicemodelsamples/Desktop.zip";
this.txtURL.TextChanged += new System.EventHandler(this.txtURL_TextChanged);
//
// txtPass
//
this.txtPass.Location = new System.Drawing.Point(291, 119);
this.txtPass.Name = "txtPass";
this.txtPass.Size = new System.Drawing.Size(157, 20);
this.txtPass.TabIndex = 6;
//
// lblPass
//
this.lblPass.AutoSize = true;
this.lblPass.Location = new System.Drawing.Point(288, 102);
this.lblPass.Name = "lblPass";
this.lblPass.Size = new System.Drawing.Size(56, 13);
this.lblPass.TabIndex = 5;
this.lblPass.Text = "Password:";
//
// txtLogin
//
this.txtLogin.Location = new System.Drawing.Point(124, 119);
this.txtLogin.Name = "txtLogin";
this.txtLogin.Size = new System.Drawing.Size(161, 20);
this.txtLogin.TabIndex = 4;
//
// lblLogin
//
this.lblLogin.AutoSize = true;
this.lblLogin.Location = new System.Drawing.Point(121, 102);
this.lblLogin.Name = "lblLogin";
this.lblLogin.Size = new System.Drawing.Size(36, 13);
this.lblLogin.TabIndex = 3;
this.lblLogin.Text = "Login:";
//
// chkLogin
//
this.chkLogin.AutoSize = true;
this.chkLogin.Location = new System.Drawing.Point(3, 102);
this.chkLogin.Name = "chkLogin";
this.chkLogin.Size = new System.Drawing.Size(96, 17);
this.chkLogin.TabIndex = 2;
this.chkLogin.Text = "Login to server";
this.chkLogin.UseVisualStyleBackColor = true;
this.chkLogin.CheckedChanged += new System.EventHandler(this.chkLogin_CheckedChanged);
//
// Location
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.lblURL);
this.Controls.Add(this.txtURL);
this.Controls.Add(this.txtPass);
this.Controls.Add(this.lblPass);
this.Controls.Add(this.txtLogin);
this.Controls.Add(this.lblLogin);
this.Controls.Add(this.chkLogin);
this.Name = "Location";
this.Size = new System.Drawing.Size(451, 145);
this.Load += new System.EventHandler(this.Location_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label lblURL;
private System.Windows.Forms.TextBox txtURL;
private System.Windows.Forms.TextBox txtPass;
private System.Windows.Forms.Label lblPass;
private System.Windows.Forms.TextBox txtLogin;
private System.Windows.Forms.Label lblLogin;
private System.Windows.Forms.CheckBox chkLogin;
}
}
MyDownloader.Core/UI/Location.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core;
using MyDownloader.Core.UI;
namespace MyDownloader.App.UI
{
public partial class Location : UserControl
{
private bool hasSet = false;
public Location()
{
InitializeComponent();
Clear();
}
public event EventHandler UrlChanged;
public string UrlLabelTitle
{
get
{
return lblURL.Text;
}
set
{
lblURL.Text = value;
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ResourceLocation[] ResourceLocation
{
get
{
string[] Urls = txtURL.Text.Replace("\r","").Split('\n');
ResourceLocation[] ret=new ResourceLocation[Urls.Length];
int cnt = 0;
foreach(string u in Urls)
{
if (u.Trim() != "")
{
ResourceLocation rl = new ResourceLocation();
rl.Authenticate = chkLogin.Checked;
rl.Login = txtLogin.Text;
rl.Password = txtPass.Text;
rl.URL = u;
ret[cnt] = rl;
cnt++;
}
}
return ret;
}
set
{
hasSet = true;
if (value != null)
{
chkLogin.Checked = value[0].Authenticate;
txtLogin.Text = value[0].Login;
txtPass.Text = value[0].Password;
txtURL.Text = value[0].URL;
}
else
{
chkLogin.Checked = false;
txtLogin.Text = String.Empty;
txtPass.Text = String.Empty;
txtURL.Text = String.Empty;
}
}
}
public void Clear()
{
txtURL.Text = string.Empty;
chkLogin.Checked = false;
txtPass.Text = string.Empty;
txtLogin.Text = string.Empty;
UpdateUI();
}
private void chkLogin_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
}
private void UpdateUI()
{
lblLogin.Enabled = chkLogin.Checked;
lblPass.Enabled = chkLogin.Checked;
txtLogin.Enabled = chkLogin.Checked;
txtPass.Enabled = chkLogin.Checked;
}
private void txtURL_TextChanged(object sender, EventArgs e)
{
if (UrlChanged != null)
{
UrlChanged(this, EventArgs.Empty);
}
}
private void Location_Load(object sender, EventArgs e)
{
if (! hasSet)
{
txtURL.Text = ClipboardHelper.GetURLOnClipboard();
}
}
public string Username
{
get { return this.txtLogin.Text; }
set { chkLogin.Checked = true; this.txtLogin.Text = value; }
}
public string Password
{
get { return this.txtPass.Text; }
set { chkLogin.Checked = true; this.txtPass.Text = value; }
}
}
}
MyDownloader.Core/UI/Location.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Core/UI/WaitControl.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
namespace MyDownloader.Core.UI
{
partial class WaitControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WaitControl));
this.label3 = new System.Windows.Forms.Label();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.SuspendLayout();
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(16, 2);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(188, 13);
this.label3.TabIndex = 0;
this.label3.Text = "Downloading site, please wait...";
//
// pictureBox2
//
this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image")));
this.pictureBox2.Location = new System.Drawing.Point(0, 0);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(16, 16);
this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBox2.TabIndex = 39;
this.pictureBox2.TabStop = false;
//
// WaitControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label3);
this.Controls.Add(this.pictureBox2);
this.Name = "WaitControl";
this.Size = new System.Drawing.Size(210, 18);
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label3;
private System.Windows.Forms.PictureBox pictureBox2;
}
}
MyDownloader.Core/UI/WaitControl.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Core.UI
{
public partial class WaitControl : UserControl
{
public WaitControl()
{
InitializeComponent();
}
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get
{
return label3.Text;
}
set
{
label3.Text = value;
}
}
}
}
MyDownloader.Core/UI/WaitControl.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureBox2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
R0lGODlhEAAQAKIFAEJCQgQEBKCgY3R0Y7+/Y/nRY9TQY////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJ
AAAFACwAAAAAEAAQAAADOVi6BEArFjJMASEAqZr2GlcMWSA0gFUIkYFVIgfFkcDSi5DdogGRJppPIRjg
jsgkMcbrqZCEmVKUAAAh+QQJAAAFACwAAAAAEAAQAAADO1i6BmMryhHCKAKISAYplCVUwaYAAUAYw4VW
l0KoUpZ+i1nTUu+vPgYOGCwYcMWkchnU1ZIGCJOAZPoSACH5BAkAAAUALAAAAAAQABAAAAM5WLolwpCJ
EB4ZJqpBBQEBkC2PIgwF12mMwYlsS8TRB8zEqIFhkcc8AE1h0w2PsVJEqTEYaYQZMpYAACH5BAkAAAUA
LAAAAAAQABAAAAM7WLrcroS8ZwwclgknQBgTY3RSqJmNAWAFkT1D8LWvE8+oMYBot/WyQEnxY3hkPEel
IJABio0IcTBEMRIAIfkECQAABQAsAAAAABAAEAAAAzVYutyuhLxnzFRi5su7b8JGWFoQZOM1mFsnDB4x
kBwBBABdiAAgm6fHDWe4ASbDoyH1sOUcCQAh+QQJAAAFACwAAAAAEAAQAAADO1i63K6EvGfMVGLmy7u/
hHUZUhFy5OcIwNaUWBC0LyAWgDwbwGCwgcFCIGsNZD7CAFYQLAvHoMcwEDoSACH5BAkAAAUALAAAAAAQ
ABAAAAM5WLrcroS8Z8xUYubLOyMAIHVAEACXIZVnKoGA5RXEIHPgeU+DGWSCTUFYMJRsAhOxIbD0fjPB
4JEAACH5BAUAAAUALAAAAAAQABAAAAM5WLrcK0AoQpwSIUtjbAFZADjSQmRA5T3pqhjD0LlfNqxGNdi4
GtMNFZAAmNF2rUbJNFBxgBMh1JIAADs=
</value>
</data>
</root>
MyDownloader.Core/app.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="MyDownloader.Core.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<userSettings>
<MyDownloader.Core.Settings>
<setting name="MinSegmentSize" serializeAs="String">
<value>200000</value>
</setting>
<setting name="MinSegmentLeftToStartNewSegment" serializeAs="String">
<value>30</value>
</setting>
<setting name="RetryDelay" serializeAs="String">
<value>5</value>
</setting>
<setting name="MaxRetries" serializeAs="String">
<value>10</value>
</setting>
<setting name="MaxSegments" serializeAs="String">
<value>5</value>
</setting>
<setting name="DownloadFolder" serializeAs="String">
<value />
</setting>
<setting name="AutomaticFileName" serializeAs="String">
<value>True</value>
</setting>
<setting name="CookieSource" serializeAs="String">
<value>Internet Explorer</value>
</setting>
</MyDownloader.Core.Settings>
</userSettings>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
MyDownloader.Extension/AntiVirus/AntiVirusExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.IO;
using System.Diagnostics;
using MyDownloader.Core;
namespace MyDownloader.Extension.AntiVirus
{
public class AntiVirusExtension: IExtension
{
private IAntiVirusParameters parameters;
#region Constructor
public AntiVirusExtension():
this(new AntiVirusParametersSettingsProxy())
{
}
public AntiVirusExtension(IAntiVirusParameters parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
this.parameters = parameters;
DownloadManager.Instance.DownloadEnded += new EventHandler<DownloaderEventArgs>(manager_DownloadEnded);
}
#endregion
#region IExtension Members
public string Name
{
get { return "Anti-virus integration"; }
}
public IUIExtension UIExtension
{
get
{
return new AntiVirusUIExtension();
}
}
#endregion
#region Methods
void manager_DownloadEnded(object sender, MyDownloader.Core.DownloaderEventArgs e)
{
if (parameters.CheckFileWithAV)
{
string fileExtension = Path.GetExtension(e.Downloader.LocalFile).ToUpper();
string[] extensionsToCheck = parameters.FileTypes.ToUpper().Split(';');
int index = Array.IndexOf(extensionsToCheck, fileExtension);
if (index >= 0)
{
Process.Start(parameters.AVFileName,
String.Format(
"{0} {1}",
parameters.AVParameter,
e.Downloader.LocalFile));
}
}
}
#endregion
}
}
MyDownloader.Extension/AntiVirus/AntiVirusParametersSettingsProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.AntiVirus
{
internal class AntiVirusParametersSettingsProxy : IAntiVirusParameters
{
#region IAntiVirusParameters Members
public bool CheckFileWithAV
{
get
{
return Settings.Default.CheckFileWithAV;
}
set
{
Settings.Default.CheckFileWithAV = value;
}
}
public string AVFileName
{
get
{
return Settings.Default.AVFileName;
}
set
{
Settings.Default.AVFileName = value;
}
}
public string FileTypes
{
get
{
return Settings.Default.FileTypes;
}
set
{
Settings.Default.FileTypes = value;
}
}
public string AVParameter
{
get
{
return Settings.Default.AVParameter;
}
set
{
Settings.Default.AVParameter = value;
}
}
#endregion
}
}
MyDownloader.Extension/AntiVirus/AntiVirusUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
using MyDownloader.Extension.AntiVirus.UI;
namespace MyDownloader.Extension.AntiVirus
{
public class AntiVirusUIExtension: IUIExtension
{
#region IUIExtension Members
public Control[] CreateSettingsView()
{
return new Control[] { new AVOptions() };
}
public void PersistSettings(Control[] settingsView)
{
AVOptions options = (AVOptions)settingsView[0];
Settings.Default.AVParameter = options.AVParameter;
Settings.Default.CheckFileWithAV = options.CheckFileWithAV;
Settings.Default.FileTypes = options.FileTypes;
Settings.Default.AVFileName = options.AVFileName;
Settings.Default.Save();
}
#endregion
}
}
MyDownloader.Extension/AntiVirus/IAntiVirusParameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.AntiVirus
{
public interface IAntiVirusParameters
{
bool CheckFileWithAV { get; set; }
string AVFileName { get; set; }
string FileTypes { get; set; }
string AVParameter { get; set; }
}
}
MyDownloader.Extension/AntiVirus/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Extension.AntiVirus {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool CheckFileWithAV {
get {
return ((bool)(this["CheckFileWithAV"]));
}
set {
this["CheckFileWithAV"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string AVFileName {
get {
return ((string)(this["AVFileName"]));
}
set {
this["AVFileName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string FileTypes {
get {
return ((string)(this["FileTypes"]));
}
set {
this["FileTypes"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string AVParameter {
get {
return ((string)(this["AVParameter"]));
}
set {
this["AVParameter"] = value;
}
}
}
}
MyDownloader.Extension/AntiVirus/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Extension.AntiVirus" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="CheckFileWithAV" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="AVFileName" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="FileTypes" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="AVParameter" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Extension/AntiVirus/UI/AVOptions.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
namespace MyDownloader.Extension.AntiVirus.UI
{
partial class AVOptions
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.chkAllowAV = new System.Windows.Forms.CheckBox();
this.txtAVFileName = new System.Windows.Forms.TextBox();
this.btnSelAV = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.txtFileTypes = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.txtParameter = new System.Windows.Forms.TextBox();
this.openFileDlg = new System.Windows.Forms.OpenFileDialog();
this.SuspendLayout();
//
// chkAllowAV
//
this.chkAllowAV.AutoSize = true;
this.chkAllowAV.Location = new System.Drawing.Point(3, 3);
this.chkAllowAV.Name = "chkAllowAV";
this.chkAllowAV.Size = new System.Drawing.Size(233, 17);
this.chkAllowAV.TabIndex = 0;
this.chkAllowAV.Text = "Scan files with AV after finishing downloads:";
this.chkAllowAV.UseVisualStyleBackColor = true;
this.chkAllowAV.CheckedChanged += new System.EventHandler(this.chkAllowAV_CheckedChanged);
//
// txtAVFileName
//
this.txtAVFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtAVFileName.Location = new System.Drawing.Point(4, 21);
this.txtAVFileName.Name = "txtAVFileName";
this.txtAVFileName.Size = new System.Drawing.Size(284, 20);
this.txtAVFileName.TabIndex = 1;
//
// btnSelAV
//
this.btnSelAV.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnSelAV.Location = new System.Drawing.Point(291, 20);
this.btnSelAV.Name = "btnSelAV";
this.btnSelAV.Size = new System.Drawing.Size(26, 23);
this.btnSelAV.TabIndex = 2;
this.btnSelAV.Text = "...";
this.btnSelAV.UseVisualStyleBackColor = true;
this.btnSelAV.Click += new System.EventHandler(this.btnSelAV_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(0, 51);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(93, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Scaning file types:";
//
// txtFileTypes
//
this.txtFileTypes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtFileTypes.Location = new System.Drawing.Point(3, 67);
this.txtFileTypes.Name = "txtFileTypes";
this.txtFileTypes.Size = new System.Drawing.Size(314, 20);
this.txtFileTypes.TabIndex = 4;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(0, 95);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(58, 13);
this.label2.TabIndex = 5;
this.label2.Text = "Parameter:";
//
// txtParameter
//
this.txtParameter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtParameter.Location = new System.Drawing.Point(3, 112);
this.txtParameter.Name = "txtParameter";
this.txtParameter.Size = new System.Drawing.Size(314, 20);
this.txtParameter.TabIndex = 6;
//
// openFileDlg
//
this.openFileDlg.Filter = "Executable|*.exe";
//
// AVOptions
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.txtParameter);
this.Controls.Add(this.label2);
this.Controls.Add(this.txtFileTypes);
this.Controls.Add(this.label1);
this.Controls.Add(this.btnSelAV);
this.Controls.Add(this.txtAVFileName);
this.Controls.Add(this.chkAllowAV);
this.Name = "AVOptions";
this.Size = new System.Drawing.Size(320, 236);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkAllowAV;
private System.Windows.Forms.TextBox txtAVFileName;
private System.Windows.Forms.Button btnSelAV;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtFileTypes;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtParameter;
private System.Windows.Forms.OpenFileDialog openFileDlg;
}
}
MyDownloader.Extension/AntiVirus/UI/AVOptions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.AntiVirus.UI
{
public partial class AVOptions : UserControl
{
public AVOptions()
{
InitializeComponent();
this.Text = "Options";
CheckFileWithAV = Settings.Default.CheckFileWithAV;
AVFileName = Settings.Default.AVFileName;
FileTypes = Settings.Default.FileTypes;
AVParameter = Settings.Default.AVParameter;
UpdateControls();
}
public bool CheckFileWithAV
{
get
{
return chkAllowAV.Checked;
}
set
{
chkAllowAV.Checked = value;
}
}
public string AVFileName
{
get
{
return txtAVFileName.Text;
}
set
{
txtAVFileName.Text = value;
}
}
public string FileTypes
{
get
{
return txtFileTypes.Text;
}
set
{
txtFileTypes.Text = value;
}
}
public string AVParameter
{
get
{
return txtParameter.Text;
}
set
{
txtParameter.Text = value;
}
}
private void chkAllowAV_CheckedChanged(object sender, EventArgs e)
{
UpdateControls();
}
private void UpdateControls()
{
btnSelAV.Enabled = chkAllowAV.Checked;
txtAVFileName.Enabled = chkAllowAV.Checked;
txtFileTypes.Enabled = chkAllowAV.Checked;
txtParameter.Enabled = chkAllowAV.Checked;
}
private void btnSelAV_Click(object sender, EventArgs e)
{
if (openFileDlg.ShowDialog() == DialogResult.OK)
{
txtAVFileName.Text = openFileDlg.FileName;
}
}
}
}
MyDownloader.Extension/AntiVirus/UI/AVOptions.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="openFileDlg.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
MyDownloader.Extension/AutoDownloads/AutoDownloadsExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
using System.Threading;
using MyDownloader.Extension.SpeedLimit;
using MyDownloader.Core.UI;
using System.Diagnostics;
using System.ComponentModel;
namespace MyDownloader.Extension.AutoDownloads
{
public class AutoDownloadsExtension: IExtension, IDisposable
{
DayHourMatrix matrix;
private bool active;
private bool needToRestore;
private System.Threading.Timer timer;
private IAutoDownloadsParameters parameters;
#region IExtension Members
public string Name
{
get { return "Auto-Downloads"; }
}
public IUIExtension UIExtension
{
get { return new AutoDownloadsUIExtension(); }
}
#endregion
#region Properties
public bool Active
{
get { return active; }
set
{
active = value;
if (active)
{
StartJobsIfNeeded();
}
else
{
RestoreIfNecessary();
}
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
RestoreIfNecessary();
if (timer != null)
{
timer.Dispose();
timer = null;
}
}
#endregion
#region Methods
private void PersistList(object state)
{
StartJobsIfNeeded();
}
private void LoadTimes()
{
matrix = new DayHourMatrix(parameters.TimesToWork);
}
void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "TimesToWork")
{
LoadTimes();
}
}
void Instance_DownloadRemoved(object sender, DownloaderEventArgs e)
{
StartJobsIfNeeded();
}
void Instance_DownloadEnded(object sender, DownloaderEventArgs e)
{
StartJobsIfNeeded();
}
void Instance_EndAddBatchDownloads(object sender, EventArgs e)
{
StartJobsIfNeeded();
}
void Instance_DownloadAdded(object sender, DownloaderEventArgs e)
{
if (!e.WillStart)
{
StartJobsIfNeeded();
e.Downloader.StateChanged += delegate(object s, EventArgs ea)
{
if (((Downloader)s).State == DownloaderState.WaitingForReconnect)
{
StartJobsIfNeeded();
}
};
}
}
private int GetActiveJobsCount()
{
int count = 0;
for (int i = 0; i < DownloadManager.Instance.Downloads.Count; i++)
{
if (DownloadManager.Instance.Downloads[i].IsWorking() &&
DownloadManager.Instance.Downloads[i].State != DownloaderState.WaitingForReconnect)
{
count++;
}
}
return count;
}
private void StartJobsIfNeeded()
{
if (!Active || DownloadManager.Instance.AddBatchCount > 0)
{
Debug.WriteLine("Leaving StartJobsIfNeeded");
return;
}
DateTime now = DateTime.Now;
EnableMode em = matrix[now.DayOfWeek, now.Hour];
if (parameters.WorkOnlyOnSpecifiedTimes && em == EnableMode.Disabled)
{
RestoreIfNecessary();
return;
}
if (em == EnableMode.ActiveWithLimit)
{
SpeedLimitExtension limit = (SpeedLimitExtension)AppManager.Instance.Application.GetExtensionByType(typeof(SpeedLimitExtension));
if (limit.Parameters.MaxRate != parameters.MaxRateOnTime)
{
//limit.Parameters.Enabled = true;
//limit.Parameters.MaxRate = parameters.MaxRateOnTime;
limit.SetMaxRateTemp(parameters.MaxRateOnTime);
needToRestore = true;
}
}
else
{
RestoreIfNecessary();
}
int maxJobs = parameters.MaxJobs;
using (DownloadManager.Instance.LockDownloadList(false))
{
int count = GetActiveJobsCount();
if (count < maxJobs)
{
for (int i = 0;
(count < maxJobs) && i < DownloadManager.Instance.Downloads.Count;
i++)
{
Downloader d = DownloadManager.Instance.Downloads[i];
if (d.State != DownloaderState.Ended && ! d.IsWorking())
{
DownloadManager.Instance.Downloads[i].Start();
count ++;
}
}
}
}
}
private void RestoreIfNecessary()
{
if (needToRestore)
{
SpeedLimitExtension limit = (SpeedLimitExtension)AppManager.Instance.Application.GetExtensionByType(typeof(SpeedLimitExtension));
limit.RestoreMaxRateFromParameters();
needToRestore = false;
}
}
#endregion
#region Constructor
public AutoDownloadsExtension():
this(new AutoDownloadsParametersSettingsProxy())
{
}
public AutoDownloadsExtension(IAutoDownloadsParameters parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
this.parameters = parameters;
parameters.ParameterChanged += new PropertyChangedEventHandler(Default_PropertyChanged);
DownloadManager.Instance.EndAddBatchDownloads += new EventHandler(Instance_EndAddBatchDownloads);
DownloadManager.Instance.DownloadAdded += new EventHandler<DownloaderEventArgs>(Instance_DownloadAdded);
DownloadManager.Instance.DownloadEnded += new EventHandler<DownloaderEventArgs>(Instance_DownloadEnded);
//DownloadManager.Instance.DownloadRemoved += new EventHandler<DownloaderEventArgs>(Instance_DownloadRemoved);
LoadTimes();
TimerCallback refreshCallBack = new TimerCallback(PersistList);
TimeSpan refreshInterval = TimeSpan.FromMinutes(1);
timer = new Timer(refreshCallBack, null, new TimeSpan(-1), refreshInterval);
if (parameters.AutoStart)
{
this.Active = true;
}
}
#endregion
}
}
MyDownloader.Extension/AutoDownloads/AutoDownloadsParametersSettingsProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.AutoDownloads
{
internal class AutoDownloadsParametersSettingsProxy : IAutoDownloadsParameters
{
#region IAutoDownloadsParameters Members
public int MaxJobs
{
get
{
return Settings.Default.MaxJobs;
}
set
{
Settings.Default.MaxJobs = value;
OnParameterChanged("MaxJobs");
}
}
public bool WorkOnlyOnSpecifiedTimes
{
get
{
return Settings.Default.WorkOnlyOnSpecifiedTimes;
}
set
{
Settings.Default.WorkOnlyOnSpecifiedTimes = value;
OnParameterChanged("WorkOnlyOnSpecifiedTimes");
}
}
public string TimesToWork
{
get
{
return Settings.Default.TimesToWork;
}
set
{
Settings.Default.TimesToWork = value;
OnParameterChanged("TimesToWork");
}
}
public double MaxRateOnTime
{
get
{
return Settings.Default.MaxRateOnTime;
}
set
{
Settings.Default.MaxRateOnTime = value;
OnParameterChanged("MaxRateOnTime");
}
}
public bool AutoStart
{
get
{
return Settings.Default.AutoStart;
}
set
{
Settings.Default.AutoStart = value;
OnParameterChanged("AutoStart");
}
}
#endregion
#region IExtensionParameters Members
public event System.ComponentModel.PropertyChangedEventHandler ParameterChanged;
#endregion
#region Methods
protected void OnParameterChanged(string propertyname)
{
if (ParameterChanged != null)
{
ParameterChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyname));
}
}
void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
OnParameterChanged(e.PropertyName);
}
#endregion
public AutoDownloadsParametersSettingsProxy()
{
Settings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Default_PropertyChanged);
}
}
}
MyDownloader.Extension/AutoDownloads/AutoDownloadsUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
using MyDownloader.Extension.AutoDownloads.UI;
namespace MyDownloader.Extension.AutoDownloads
{
public class AutoDownloadsUIExtension: IUIExtension
{
#region IUIExtension Members
public Control[] CreateSettingsView()
{
return new Control[] { new Jobs() };
}
public void PersistSettings(Control[] settingsView)
{
Jobs jobs = (Jobs)settingsView[0];
Settings.Default.MaxJobs = jobs.MaxJobs;
Settings.Default.WorkOnlyOnSpecifiedTimes = jobs.WorkOnlyOnSpecifiedTimes;
Settings.Default.TimesToWork = jobs.TimesToWork;
Settings.Default.MaxRateOnTime = jobs.MaxRate;
Settings.Default.AutoStart = jobs.AutoStart;
Settings.Default.Save();
}
#endregion
}
}
MyDownloader.Extension/AutoDownloads/DayHourMatrix.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.AutoDownloads
{
[Serializable]
public enum EnableMode: int
{
Active = 1,
ActiveWithLimit,
Disabled
}
public class DayHourMatrix
{
public const int DAYS = 7;
public const int HOURS = 24;
private EnableMode[,] enabledAt = new EnableMode[DAYS, HOURS];
public DayHourMatrix()
{
}
public DayHourMatrix(string data)
{
if (data == null || (data = data.Trim()).Length == 0)
{
return;
}
string[] days = data.Split('|');
for (int i = 0; i < days.Length; i++)
{
string[] values = days[i].Split(',');
if (values.Length == 3)
{
int day = int.Parse(values[0]);
int hour = int.Parse(values[1]);
EnableMode em = (EnableMode)int.Parse(values[2]);
this[(DayOfWeek)day, hour] = em;
}
}
}
public EnableMode this[DayOfWeek day, int hour]
{
get
{
return enabledAt[(int)day, hour];
}
set
{
enabledAt[(int)day, hour] = value;
}
}
public override string ToString()
{
string selected = String.Empty;
for (int i = 0; i < DayHourMatrix.DAYS; i++)
{
for (int j = 0; j < DayHourMatrix.HOURS; j++)
{
if (this[(DayOfWeek)i, j] != EnableMode.Disabled)
{
if (selected.Length > 0)
{
selected += "|";
}
// day,hour,mode|day,hour,mode....
selected += i + "," + j + "," + (int)this[(DayOfWeek)i, j];
}
}
}
return selected;
}
}
}
MyDownloader.Extension/AutoDownloads/IAutoDownloadsParameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
namespace MyDownloader.Extension.AutoDownloads
{
public interface IAutoDownloadsParameters : IExtensionParameters
{
int MaxJobs { get; set; }
bool WorkOnlyOnSpecifiedTimes { get; set; }
string TimesToWork { get; set; }
double MaxRateOnTime { get; set; }
bool AutoStart { get; set; }
}
}
MyDownloader.Extension/AutoDownloads/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Extension.AutoDownloads {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5")]
public int MaxJobs {
get {
return ((int)(this["MaxJobs"]));
}
set {
this["MaxJobs"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool WorkOnlyOnSpecifiedTimes {
get {
return ((bool)(this["WorkOnlyOnSpecifiedTimes"]));
}
set {
this["WorkOnlyOnSpecifiedTimes"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string TimesToWork {
get {
return ((string)(this["TimesToWork"]));
}
set {
this["TimesToWork"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1")]
public double MaxRateOnTime {
get {
return ((double)(this["MaxRateOnTime"]));
}
set {
this["MaxRateOnTime"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool AutoStart {
get {
return ((bool)(this["AutoStart"]));
}
set {
this["AutoStart"] = value;
}
}
}
}
MyDownloader.Extension/AutoDownloads/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Extension.AutoDownloads" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="MaxJobs" Type="System.Int32" Scope="User">
<Value Profile="(Default)">5</Value>
</Setting>
<Setting Name="WorkOnlyOnSpecifiedTimes" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="TimesToWork" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="MaxRateOnTime" Type="System.Double" Scope="User">
<Value Profile="(Default)">1</Value>
</Setting>
<Setting Name="AutoStart" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Extension/AutoDownloads/UI/Jobs.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
namespace MyDownloader.Extension.AutoDownloads.UI
{
partial class Jobs
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Jobs));
MyDownloader.Extension.AutoDownloads.DayHourMatrix dayHourMatrix1 = new MyDownloader.Extension.AutoDownloads.DayHourMatrix();
this.numMaxJobs = new System.Windows.Forms.NumericUpDown();
this.label2 = new System.Windows.Forms.Label();
this.chkUseTime = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.pnlTime = new System.Windows.Forms.Panel();
this.label5 = new System.Windows.Forms.Label();
this.panel3 = new System.Windows.Forms.Panel();
this.numMaxRate = new System.Windows.Forms.NumericUpDown();
this.lblMaxRate = new System.Windows.Forms.Label();
this.chkAutoStart = new System.Windows.Forms.CheckBox();
this.timeGrid1 = new MyDownloader.Extension.AutoDownloads.UI.TimeGrid();
((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).BeginInit();
this.pnlTime.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).BeginInit();
this.SuspendLayout();
//
// numMaxJobs
//
this.numMaxJobs.Location = new System.Drawing.Point(0, 41);
this.numMaxJobs.Name = "numMaxJobs";
this.numMaxJobs.Size = new System.Drawing.Size(96, 20);
this.numMaxJobs.TabIndex = 2;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(-3, 25);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(55, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Max Jobs:";
//
// chkUseTime
//
this.chkUseTime.AutoSize = true;
this.chkUseTime.Location = new System.Drawing.Point(0, 77);
this.chkUseTime.Name = "chkUseTime";
this.chkUseTime.Size = new System.Drawing.Size(89, 17);
this.chkUseTime.TabIndex = 3;
this.chkUseTime.Text = "Work only at:";
this.chkUseTime.UseVisualStyleBackColor = true;
this.chkUseTime.CheckedChanged += new System.EventHandler(this.chkUseTime_CheckedChanged);
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.label1.Location = new System.Drawing.Point(0, 152);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(400, 75);
this.label1.TabIndex = 20;
this.label1.Text = resources.GetString("label1.Text");
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.Green;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Location = new System.Drawing.Point(8, 8);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(16, 16);
this.panel1.TabIndex = 21;
//
// panel2
//
this.panel2.BackColor = System.Drawing.Color.Gray;
this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel2.Location = new System.Drawing.Point(230, 8);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(16, 16);
this.panel2.TabIndex = 22;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(24, 8);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(55, 13);
this.label3.TabIndex = 23;
this.label3.Text = "Full speed";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(248, 8);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(44, 13);
this.label4.TabIndex = 24;
this.label4.Text = "Turn off";
//
// pnlTime
//
this.pnlTime.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pnlTime.Controls.Add(this.label5);
this.pnlTime.Controls.Add(this.panel3);
this.pnlTime.Controls.Add(this.panel1);
this.pnlTime.Controls.Add(this.label4);
this.pnlTime.Controls.Add(this.timeGrid1);
this.pnlTime.Controls.Add(this.label3);
this.pnlTime.Controls.Add(this.label1);
this.pnlTime.Controls.Add(this.panel2);
this.pnlTime.Location = new System.Drawing.Point(0, 101);
this.pnlTime.Name = "pnlTime";
this.pnlTime.Size = new System.Drawing.Size(400, 227);
this.pnlTime.TabIndex = 4;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(136, 8);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(40, 13);
this.label5.TabIndex = 26;
this.label5.Text = "Limited";
//
// panel3
//
this.panel3.BackColor = System.Drawing.Color.PaleGreen;
this.panel3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel3.Location = new System.Drawing.Point(117, 8);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(16, 16);
this.panel3.TabIndex = 25;
//
// numMaxRate
//
this.numMaxRate.Location = new System.Drawing.Point(3, 344);
this.numMaxRate.Maximum = new decimal(new int[] {
1000,
0,
0,
0});
this.numMaxRate.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numMaxRate.Name = "numMaxRate";
this.numMaxRate.Size = new System.Drawing.Size(96, 20);
this.numMaxRate.TabIndex = 6;
this.numMaxRate.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// lblMaxRate
//
this.lblMaxRate.AutoSize = true;
this.lblMaxRate.Location = new System.Drawing.Point(0, 328);
this.lblMaxRate.Name = "lblMaxRate";
this.lblMaxRate.Size = new System.Drawing.Size(152, 13);
this.lblMaxRate.TabIndex = 5;
this.lblMaxRate.Text = "Limited Download Rate (kbps):";
//
// chkAutoStart
//
this.chkAutoStart.AutoSize = true;
this.chkAutoStart.Location = new System.Drawing.Point(0, 0);
this.chkAutoStart.Name = "chkAutoStart";
this.chkAutoStart.Size = new System.Drawing.Size(196, 17);
this.chkAutoStart.TabIndex = 0;
this.chkAutoStart.Text = "Auto-start auto-downloads at startup";
this.chkAutoStart.UseVisualStyleBackColor = true;
//
// timeGrid1
//
this.timeGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.timeGrid1.Location = new System.Drawing.Point(0, 32);
this.timeGrid1.Name = "timeGrid1";
this.timeGrid1.SelectedTimes = dayHourMatrix1;
this.timeGrid1.Size = new System.Drawing.Size(395, 120);
this.timeGrid1.StartPosition = new System.Drawing.Point(32, 16);
this.timeGrid1.TabIndex = 0;
//
// Jobs
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.chkAutoStart);
this.Controls.Add(this.numMaxRate);
this.Controls.Add(this.lblMaxRate);
this.Controls.Add(this.pnlTime);
this.Controls.Add(this.chkUseTime);
this.Controls.Add(this.numMaxJobs);
this.Controls.Add(this.label2);
this.Name = "Jobs";
this.Size = new System.Drawing.Size(400, 403);
((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).EndInit();
this.pnlTime.ResumeLayout(false);
this.pnlTime.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.NumericUpDown numMaxJobs;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.CheckBox chkUseTime;
private TimeGrid timeGrid1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Panel pnlTime;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.NumericUpDown numMaxRate;
private System.Windows.Forms.Label lblMaxRate;
private System.Windows.Forms.CheckBox chkAutoStart;
}
}
MyDownloader.Extension/AutoDownloads/UI/Jobs.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.AutoDownloads.UI
{
public partial class Jobs : UserControl
{
public Jobs()
{
InitializeComponent();
Text = "Auto-Downloads";
numMaxJobs.Value = Settings.Default.MaxJobs;
chkUseTime.Checked = Settings.Default.WorkOnlyOnSpecifiedTimes;
timeGrid1.SelectedTimes = new DayHourMatrix(Settings.Default.TimesToWork);
numMaxRate.Value = (decimal)(Math.Max(Settings.Default.MaxRateOnTime, 1024) / 1024.0);
chkAutoStart.Checked = Settings.Default.AutoStart;
UpdateUI();
}
private void chkUseTime_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
}
private void UpdateUI()
{
pnlTime.Enabled = chkUseTime.Checked;
}
public int MaxJobs
{
get { return (int)numMaxJobs.Value; }
}
public double MaxRate
{
get { return ((double)numMaxRate.Value) * 1024; }
}
public bool WorkOnlyOnSpecifiedTimes
{
get { return chkUseTime.Checked; }
}
public bool AutoStart
{
get { return chkAutoStart.Checked; }
}
public string TimesToWork
{
get { return timeGrid1.SelectedTimes.ToString(); }
}
}
}
MyDownloader.Extension/AutoDownloads/UI/Jobs.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<data name="label1.Text" xml:space="preserve">
<value>* Left button: hold left button and move to selected the time
* Left button + SHIFT: hold left button and move to selected the time with limited speed
* Right button: hold left button and move to unselected the time</value>
</data>
</root>
MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
namespace MyDownloader.Extension.AutoDownloads.UI
{
partial class ScheduledDownloadEnabler
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ScheduledDownloadEnabler));
this.chkDisableWorkOnlyAt = new System.Windows.Forms.CheckBox();
this.numMaxJobs = new System.Windows.Forms.NumericUpDown();
this.chkOverrideMaxActive = new System.Windows.Forms.CheckBox();
this.chkStartScheduler = new System.Windows.Forms.CheckBox();
this.panel1 = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// chkDisableWorkOnlyAt
//
this.chkDisableWorkOnlyAt.AutoSize = true;
this.chkDisableWorkOnlyAt.Location = new System.Drawing.Point(0, 72);
this.chkDisableWorkOnlyAt.Name = "chkDisableWorkOnlyAt";
this.chkDisableWorkOnlyAt.Size = new System.Drawing.Size(299, 17);
this.chkDisableWorkOnlyAt.TabIndex = 3;
this.chkDisableWorkOnlyAt.Text = "Disable \"Work only at\" configuration and work at any time";
this.chkDisableWorkOnlyAt.UseVisualStyleBackColor = true;
//
// numMaxJobs
//
this.numMaxJobs.Location = new System.Drawing.Point(0, 46);
this.numMaxJobs.Name = "numMaxJobs";
this.numMaxJobs.Size = new System.Drawing.Size(96, 20);
this.numMaxJobs.TabIndex = 2;
//
// chkOverrideMaxActive
//
this.chkOverrideMaxActive.AutoSize = true;
this.chkOverrideMaxActive.Location = new System.Drawing.Point(0, 23);
this.chkOverrideMaxActive.Name = "chkOverrideMaxActive";
this.chkOverrideMaxActive.Size = new System.Drawing.Size(189, 17);
this.chkOverrideMaxActive.TabIndex = 1;
this.chkOverrideMaxActive.Text = "Override max active downloads to:";
this.chkOverrideMaxActive.UseVisualStyleBackColor = true;
this.chkOverrideMaxActive.CheckedChanged += new System.EventHandler(this.chkOverrideMaxActive_CheckedChanged);
//
// chkStartScheduler
//
this.chkStartScheduler.AutoSize = true;
this.chkStartScheduler.Location = new System.Drawing.Point(0, 0);
this.chkStartScheduler.Name = "chkStartScheduler";
this.chkStartScheduler.Size = new System.Drawing.Size(126, 17);
this.chkStartScheduler.TabIndex = 0;
this.chkStartScheduler.Text = "Start auto-downloads";
this.chkStartScheduler.UseVisualStyleBackColor = true;
this.chkStartScheduler.CheckedChanged += new System.EventHandler(this.chkStartScheduler_CheckedChanged);
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.SystemColors.Info;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.label2);
this.panel1.Location = new System.Drawing.Point(0, 95);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(393, 66);
this.panel1.TabIndex = 34;
//
// label2
//
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(0, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(391, 64);
this.label2.TabIndex = 0;
this.label2.Text = resources.GetString("label2.Text");
//
// ScheduledDownloadEnabler
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.chkDisableWorkOnlyAt);
this.Controls.Add(this.numMaxJobs);
this.Controls.Add(this.chkOverrideMaxActive);
this.Controls.Add(this.chkStartScheduler);
this.Controls.Add(this.panel1);
this.Name = "ScheduledDownloadEnabler";
this.Size = new System.Drawing.Size(393, 163);
this.Load += new System.EventHandler(this.ScheduledDownloadEnabler_Load);
((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkDisableWorkOnlyAt;
private System.Windows.Forms.NumericUpDown numMaxJobs;
private System.Windows.Forms.CheckBox chkOverrideMaxActive;
private System.Windows.Forms.CheckBox chkStartScheduler;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label2;
}
}
MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core.UI;
namespace MyDownloader.Extension.AutoDownloads.UI
{
public partial class ScheduledDownloadEnabler : UserControl
{
public ScheduledDownloadEnabler()
{
InitializeComponent();
}
private void ScheduledDownloadEnabler_Load(object sender, EventArgs e)
{
numMaxJobs.Value = Settings.Default.MaxJobs;
UpdateUI();
}
private void chkStartScheduler_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
}
private void chkOverrideMaxActive_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
}
private void UpdateUI()
{
chkDisableWorkOnlyAt.Enabled = chkStartScheduler.Checked && Settings.Default.WorkOnlyOnSpecifiedTimes;
chkOverrideMaxActive.Enabled = chkStartScheduler.Checked;
numMaxJobs.Enabled = chkStartScheduler.Checked && chkOverrideMaxActive.Checked;
panel1.Enabled = chkStartScheduler.Checked;
}
public void ApplySettings()
{
if (chkStartScheduler.Checked)
{
bool needToSave = false;
if (chkOverrideMaxActive.Checked)
{
Settings.Default.MaxJobs = (int)numMaxJobs.Value;
needToSave = true;
}
if (chkDisableWorkOnlyAt.Checked)
{
Settings.Default.WorkOnlyOnSpecifiedTimes = false;
needToSave = true;
}
if (needToSave)
{
Settings.Default.Save();
}
AutoDownloadsExtension scheduler = (AutoDownloadsExtension)AppManager.Instance.
Application.GetExtensionByType(typeof(AutoDownloadsExtension));
scheduler.Active = true;
}
}
}
}
MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<data name="label2.Text" xml:space="preserve">
<value>Starting the "Auto-Downloads" may not necessarily start downloads, downloads only will be started if the number of active is lower than max active downloads and if downloads are allowed at this time (as configured tough options dialog).</value>
</data>
</root>
MyDownloader.Extension/AutoDownloads/UI/TimeGrid.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
namespace MyDownloader.Extension.AutoDownloads.UI
{
partial class TimeGrid
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// TimeGrid
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.DoubleBuffered = true;
this.Name = "TimeGrid";
this.Size = new System.Drawing.Size(532, 258);
this.Layout += new System.Windows.Forms.LayoutEventHandler(this.TimeGrid_Layout);
this.Load += new System.EventHandler(this.TimeGrid_Load);
this.ResumeLayout(false);
}
#endregion
}
}
MyDownloader.Extension/AutoDownloads/UI/TimeGrid.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace MyDownloader.Extension.AutoDownloads.UI
{
public partial class TimeGrid : UserControl
{
object Selected = new object();
object Unselected = new object();
object SelectedWithLimit = new object();
Color UnselectedColor = Color.DarkGray;
Color SelectedColor = Color.Green;
Color SelectedWithLimitColor = Color.PaleGreen;
private Point startPosition;
// days x hours
PictureBox[,] timePanels = new PictureBox[DayHourMatrix.DAYS, DayHourMatrix.HOURS];
Label[] timeLbs = new Label[DayHourMatrix.HOURS];
Label[] dayLbl = new Label[DayHourMatrix.DAYS];
PictureBox lastPanel;
DayHourMatrix matrix = new DayHourMatrix();
public TimeGrid()
{
InitializeComponent();
this.SuspendLayout();
for (int i = 0; i < DayHourMatrix.DAYS; i++)
{
for (int j = 0; j < DayHourMatrix.HOURS; j++)
{
timePanels[i, j] = new PictureBox();
InitPanel(timePanels[i, j]);
}
}
for (int i = 0; i < DayHourMatrix.DAYS; i++)
{
dayLbl[i] = new Label();
dayLbl[i].AutoSize = false;
dayLbl[i].TextAlign = ContentAlignment.MiddleLeft;
dayLbl[i].Text = ((DayOfWeek)i).ToString().Substring(0, 3);
dayLbl[i].Visible = true;
this.Controls.Add(dayLbl[i]);
}
for (int i = 0; i < DayHourMatrix.HOURS; i++)
{
timeLbs[i] = new Label();
timeLbs[i].AutoSize = true;
//timeLbs[i].TextAlign = ContentAlignment.MiddleCenter;
timeLbs[i].Text = i.ToString("0#");
timeLbs[i].Visible = true;
this.Controls.Add(timeLbs[i]);
}
this.ResumeLayout(true);
}
public Point StartPosition
{
get
{
return startPosition;
}
set
{
startPosition = value;
this.layoutPanels();
}
}
public DayHourMatrix SelectedTimes
{
get
{
return matrix;
}
set
{
matrix = value;
// unselect all
for (int i = 0; i < DayHourMatrix.DAYS; i++)
{
for (int j = 0; j < DayHourMatrix.HOURS; j++)
{
object v = Unselected;
if (matrix != null)
{
EnableMode em = matrix[(DayOfWeek)i, j];
if (em == EnableMode.Active)
{
v = Selected;
}
if (em == EnableMode.ActiveWithLimit)
{
v = SelectedWithLimit;
}
}
SetPanel(timePanels[i, j], v);
}
}
}
}
private void InitPanel(PictureBox p)
{
p.BackColor = UnselectedColor;
p.BorderStyle = BorderStyle.FixedSingle;
p.Visible = true;
p.MouseMove += new MouseEventHandler(panel_MouseMove);
p.Tag = Unselected;
this.Controls.Add(p);
}
void panel_MouseMove(object sender, MouseEventArgs e)
{
Point pt = PointToClient(Cursor.Position);
pt.Offset(-this.StartPosition.X, -this.StartPosition.Y);
int hour = Math.Max(0, Math.Min(pt.X / timePanels[0, 0].Width, DayHourMatrix.HOURS - 1));
int day = Math.Max(0, Math.Min(pt.Y / timePanels[0, 0].Height, DayHourMatrix.DAYS - 1));
PictureBox p = timePanels[day, hour];
if (p == lastPanel) return;
if (e.Button == MouseButtons.Left)
{
if ((Control.ModifierKeys == Keys.Shift))
{
SetPanel(p, SelectedWithLimit);
matrix[(DayOfWeek)day, hour] = EnableMode.ActiveWithLimit;
}
else
{
SetPanel(p, Selected);
matrix[(DayOfWeek)day, hour] = EnableMode.Active;
}
}
else if (e.Button == MouseButtons.Right)
{
SetPanel(p, Unselected);
matrix[(DayOfWeek)day, hour] = EnableMode.Disabled;
}
}
private void SetPanel(PictureBox p, object action)
{
if (action == null) action = p.Tag;
if (action == Selected)
{
p.Tag = Selected;
p.BackColor = SelectedColor;
}
else if (action == Unselected)
{
p.Tag = Unselected;
p.BackColor = UnselectedColor;
}
else
{
p.Tag = SelectedWithLimit;
p.BackColor = SelectedWithLimitColor;
}
lastPanel = p;
}
private void layoutPanels()
{
int width = (this.Width - StartPosition.X) / DayHourMatrix.HOURS;
int height = (this.Height - StartPosition.Y) / DayHourMatrix.DAYS;
for (int i = 0; i < DayHourMatrix.DAYS; i++)
{
dayLbl[i].Location = new Point(0, i * height + StartPosition.Y);
dayLbl[i].Size = new Size(StartPosition.X, height);
for (int j = 0; j < DayHourMatrix.HOURS; j++)
{
timePanels[i, j].Location = new Point(j * width + StartPosition.X, i * height + StartPosition.Y);
timePanels[i, j].Size = new Size(width, height);
}
}
for (int j = 0; j < DayHourMatrix.HOURS; j++)
{
timeLbs[j].Location = new Point(j * width + StartPosition.X, 0);
timeLbs[j].Size = new Size(width, StartPosition.Y);
}
}
private void TimeGrid_Layout(object sender, LayoutEventArgs e)
{
layoutPanels();
}
private void TimeGrid_Load(object sender, EventArgs e)
{
layoutPanels();
}
}
}
MyDownloader.Extension/AutoDownloads/UI/TimeGrid.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/MyDownloader.Extension.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FEA18B6C-491F-401A-A06B-AE47888FF288}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyDownloader.Extension</RootNamespace>
<AssemblyName>MyDownloader.Extension</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.85.4.369, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="MyDownloader.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Release\MyDownloader.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AntiVirus\AntiVirusExtension.cs" />
<Compile Include="AntiVirus\AntiVirusParametersSettingsProxy.cs" />
<Compile Include="AntiVirus\UI\AVOptions.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AntiVirus\UI\AVOptions.Designer.cs">
<DependentUpon>AVOptions.cs</DependentUpon>
</Compile>
<Compile Include="AntiVirus\AntiVirusUIExtension.cs" />
<Compile Include="AntiVirus\IAntiVirusParameters.cs" />
<Compile Include="AntiVirus\Settings.Designer.cs">
<DependentUpon>Settings.settings</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="AutoDownloads\AutoDownloadsParametersSettingsProxy.cs" />
<Compile Include="AutoDownloads\IAutoDownloadsParameters.cs" />
<Compile Include="Notifications\INotificationsExtensionParameters.cs" />
<Compile Include="Notifications\NotificationsExtensionParametersSettingsProxy.cs" />
<Compile Include="Notifications\UI\SoundChooser.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Notifications\UI\SoundChooser.Designer.cs">
<DependentUpon>SoundChooser.cs</DependentUpon>
</Compile>
<Compile Include="Protocols\BaseProtocolProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Protocols\FtpProtocolProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Protocols\HttpFtpProtocolExtension.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Protocols\HttpFtpProtocolParametersSettingsProxy.cs" />
<Compile Include="Protocols\HttpFtpProtocolUIExtension.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Protocols\HttpProtocolProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Protocols\IHttpFtpProtocolParameters.cs" />
<Compile Include="Zip\NoCloseSubStream.cs" />
<Compile Include="Zip\PartialInputStream.cs" />
<Compile Include="Zip\StreamHelper.cs" />
<Compile Include="Zip\ZipOutputStream.cs" />
<Compile Include="Zip\ZipRemoteFile.cs" />
<Compile Include="Protocols\UI\Proxy.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Protocols\UI\Proxy.Designer.cs">
<DependentUpon>Proxy.cs</DependentUpon>
</Compile>
<Compile Include="Protocols\Settings.Designer.cs">
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
</Compile>
<Compile Include="Zip\ZipProtocolProvider.cs" />
<Compile Include="SpeedLimit\ISpeedLimitParameters.cs" />
<Compile Include="SpeedLimit\SpeedLimitParametersSettingProxy.cs" />
<Compile Include="Video\VideoDownloadUIExtension.cs" />
<Compile Include="WindowsIntegration\ClipboardMonitor\ClipboardMonitor.cs" />
<Compile Include="WindowsIntegration\ClipboardMonitor\IClipboardDataHandler.cs" />
<Compile Include="Notifications\Helpers\BalloonHelper.cs" />
<Compile Include="Notifications\NotificationsExtension.cs" />
<Compile Include="Notifications\NotificationsUIExtension.cs" />
<Compile Include="Notifications\Settings.Designer.cs">
<DependentUpon>Settings.settings</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Notifications\Helpers\SoundHelper.cs" />
<Compile Include="Notifications\UI\SoundsOptions.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Notifications\UI\SoundsOptions.Designer.cs">
<DependentUpon>SoundsOptions.cs</DependentUpon>
</Compile>
<Compile Include="Notifications\UI\XPBalloonOptions.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Notifications\UI\XPBalloonOptions.Designer.cs">
<DependentUpon>XPBalloonOptions.cs</DependentUpon>
</Compile>
<Compile Include="PersistedList\PersistedListExtension.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AutoDownloads\DayHourMatrix.cs" />
<Compile Include="AutoDownloads\UI\Jobs.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoDownloads\UI\Jobs.Designer.cs">
<DependentUpon>Jobs.cs</DependentUpon>
</Compile>
<Compile Include="AutoDownloads\UI\ScheduledDownloadEnabler.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoDownloads\UI\ScheduledDownloadEnabler.Designer.cs">
<DependentUpon>ScheduledDownloadEnabler.cs</DependentUpon>
</Compile>
<Compile Include="AutoDownloads\AutoDownloadsExtension.cs" />
<Compile Include="AutoDownloads\AutoDownloadsUIExtension.cs" />
<Compile Include="AutoDownloads\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="AutoDownloads\UI\TimeGrid.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoDownloads\UI\TimeGrid.Designer.cs">
<DependentUpon>TimeGrid.cs</DependentUpon>
</Compile>
<Compile Include="PersistedList\SerializableDictionary.cs" />
<Compile Include="SpeedLimit\UI\LimitCfg.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="SpeedLimit\UI\LimitCfg.Designer.cs">
<DependentUpon>LimitCfg.cs</DependentUpon>
</Compile>
<Compile Include="SpeedLimit\LimitedRateStreamProxy.cs" />
<Compile Include="SpeedLimit\ProtocolProviderProxy.cs" />
<Compile Include="SpeedLimit\UI\SetSpeedLimitDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SpeedLimit\UI\SetSpeedLimitDialog.Designer.cs">
<DependentUpon>SetSpeedLimitDialog.cs</DependentUpon>
</Compile>
<Compile Include="SpeedLimit\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="SpeedLimit\SpeedLimitExtension.cs" />
<Compile Include="SpeedLimit\SpeedLimitUIExtension.cs" />
<Compile Include="Video\Impl\BreakVideoDownloader.cs" />
<Compile Include="Video\Impl\GoogleVideoDownloader.cs" />
<Compile Include="Video\Impl\MetaCafeVideoDownloader.cs" />
<Compile Include="Video\Impl\PutfileVideoDownloader.cs" />
<Compile Include="Video\Impl\BaseVideoDownloader.cs" />
<Compile Include="Video\TextUtil.cs" />
<Compile Include="Video\UI\VideoFormatCtrl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Video\UI\VideoFormatCtrl.Designer.cs">
<DependentUpon>VideoFormatCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Video\UI\NewVideoDownload.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Video\UI\NewVideoDownload.Designer.cs">
<DependentUpon>NewVideoDownload.cs</DependentUpon>
</Compile>
<Compile Include="Video\UI\SupportedVideoSitesForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Video\UI\SupportedVideoSitesForm.Designer.cs">
<DependentUpon>SupportedVideoSitesForm.cs</DependentUpon>
</Compile>
<Compile Include="Video\VideoConverter.cs" />
<Compile Include="Video\VideoDownloadExtension.cs" />
<Compile Include="Video\VideoDownloadHandler.cs" />
<Compile Include="Video\Impl\YouTubeDownloader.cs" />
<Compile Include="WindowsIntegration\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="WindowsIntegration\WindowsIntegrationUIExtension.cs" />
<Compile Include="WindowsIntegration\WindowsIntegrationExtension.cs" />
<Compile Include="WindowsIntegration\WindowsIntegrationUI.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="WindowsIntegration\WindowsIntegrationUI.Designer.cs">
<DependentUpon>WindowsIntegrationUI.cs</DependentUpon>
</Compile>
<Compile Include="WindowsIntegration\WindowsStartupUtility.cs" />
</ItemGroup>
<ItemGroup>
<None Include="AntiVirus\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="app.config" />
<None Include="Notifications\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="AutoDownloads\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="Protocols\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="SpeedLimit\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="WindowsIntegration\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="AntiVirus\UI\AVOptions.resx">
<DependentUpon>AVOptions.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Notifications\UI\SoundChooser.resx">
<SubType>Designer</SubType>
<DependentUpon>SoundChooser.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Notifications\UI\SoundsOptions.resx">
<DependentUpon>SoundsOptions.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Notifications\UI\XPBalloonOptions.resx">
<DependentUpon>XPBalloonOptions.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="AutoDownloads\UI\Jobs.resx">
<SubType>Designer</SubType>
<DependentUpon>Jobs.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="AutoDownloads\UI\ScheduledDownloadEnabler.resx">
<DependentUpon>ScheduledDownloadEnabler.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="AutoDownloads\UI\TimeGrid.resx">
<SubType>Designer</SubType>
<DependentUpon>TimeGrid.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Protocols\UI\Proxy.resx">
<DependentUpon>Proxy.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="SpeedLimit\UI\LimitCfg.resx">
<SubType>Designer</SubType>
<DependentUpon>LimitCfg.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="SpeedLimit\UI\SetSpeedLimitDialog.resx">
<SubType>Designer</SubType>
<DependentUpon>SetSpeedLimitDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Video\Impl\Logos\BreakVideoDownloader.png" />
<EmbeddedResource Include="Video\Impl\Logos\GoogleVideoDownloader.png" />
<EmbeddedResource Include="Video\Impl\Logos\MetaCafeVideoDownloader.png" />
<EmbeddedResource Include="Video\Impl\Logos\PutfileVideoDownloader.png" />
<EmbeddedResource Include="Video\Impl\Logos\YouTubeDownloader.png" />
<EmbeddedResource Include="Video\UI\VideoFormatCtrl.resx">
<SubType>Designer</SubType>
<DependentUpon>VideoFormatCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Video\UI\NewVideoDownload.resx">
<DependentUpon>NewVideoDownload.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Video\UI\SupportedVideoSitesForm.resx">
<DependentUpon>SupportedVideoSitesForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="WindowsIntegration\WindowsIntegrationUI.resx">
<DependentUpon>WindowsIntegrationUI.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
MyDownloader.Extension/Notifications/Helpers/BalloonHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using MyDownloader.Core.UI;
using System.Windows.Forms;
namespace MyDownloader.Extension.Notifications.Helpers
{
class BalloonHelper
{
private static INotificationsExtensionParameters parameters;
static void Instance_DownloadEnded(object sender, DownloaderEventArgs e)
{
if (parameters.ShowBallon &&
AppManager.Instance.Application.NotifyIcon.Visible)
{
AppManager.Instance.Application.NotifyIcon.ShowBalloonTip(
parameters.BallonTimeout,
AppManager.Instance.Application.MainForm.Text,
String.Format("Download finished: {0}", e.Downloader.LocalFile),
ToolTipIcon.Info);
}
}
public static void Start(INotificationsExtensionParameters parameters)
{
BalloonHelper.parameters = parameters;
DownloadManager.Instance.DownloadEnded += new EventHandler<DownloaderEventArgs>(Instance_DownloadEnded);
}
}
}
MyDownloader.Extension/Notifications/Helpers/SoundHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
namespace MyDownloader.Extension.Notifications.Helpers
{
class SoundHelper
{
private static INotificationsExtensionParameters parameters;
public static void PlayWav(string fileName)
{
if (!String.IsNullOrEmpty(fileName))
{
new System.Media.SoundPlayer(fileName).Play();
}
}
static void Instance_DownloadRemoved(object sender, DownloaderEventArgs e)
{
PlayWav(parameters.DownloadRemovedSoundPath);
}
static void Instance_DownloadEnded(object sender, DownloaderEventArgs e)
{
PlayWav(parameters.DownloadEndedSoundPath);
}
static void Instance_DownloadAdded(object sender, DownloaderEventArgs e)
{
PlayWav(parameters.DownloadAddedSoundPath);
}
public static void Start(INotificationsExtensionParameters parameters)
{
SoundHelper.parameters = parameters;
DownloadManager.Instance.DownloadAdded += new EventHandler<DownloaderEventArgs>(Instance_DownloadAdded);
DownloadManager.Instance.DownloadEnded += new EventHandler<DownloaderEventArgs>(Instance_DownloadEnded);
DownloadManager.Instance.DownloadRemoved += new EventHandler<DownloaderEventArgs>(Instance_DownloadRemoved);
}
}
}
MyDownloader.Extension/Notifications/INotificationsExtensionParameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.Notifications
{
public interface INotificationsExtensionParameters
{
string DownloadAddedSoundPath { get; set; }
string DownloadRemovedSoundPath { get; set; }
string DownloadEndedSoundPath { get; set; }
bool ShowBallon { get; set; }
int BallonTimeout { get; set; }
}
}
MyDownloader.Extension/Notifications/NotificationsExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
using MyDownloader.Extension.Notifications.Helpers;
namespace MyDownloader.Extension.Notifications
{
public class NotificationsExtension: IExtension
{
#region IExtension Members
public string Name
{
get { return "Notifications"; }
}
public IUIExtension UIExtension
{
get { return new NotificationsUIExtension(); }
}
#endregion
#region Constructor
public NotificationsExtension(INotificationsExtensionParameters parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
SoundHelper.Start(parameters);
BalloonHelper.Start(parameters);
}
public NotificationsExtension():
this(new NotificationsExtensionParametersSettingsProxy())
{
}
#endregion
}
}
MyDownloader.Extension/Notifications/NotificationsExtensionParametersSettingsProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.Notifications
{
internal class NotificationsExtensionParametersSettingsProxy: INotificationsExtensionParameters
{
#region INotificationsExtensionParameters Members
public string DownloadAddedSoundPath
{
get
{
return Settings.Default.DownloadAddedSound;
}
set
{
Settings.Default.DownloadAddedSound = value;
}
}
public string DownloadRemovedSoundPath
{
get
{
return Settings.Default.DownloadRemovedSound;
}
set
{
Settings.Default.DownloadRemovedSound = value;
}
}
public string DownloadEndedSoundPath
{
get
{
return Settings.Default.DownloadEndedSound;
}
set
{
Settings.Default.DownloadEndedSound = value;
}
}
public bool ShowBallon
{
get
{
return Settings.Default.ShowBallon;
}
set
{
Settings.Default.ShowBallon = value;
}
}
public int BallonTimeout
{
get
{
return Settings.Default.BallonTimeout;
}
set
{
Settings.Default.BallonTimeout = value;
}
}
#endregion
}
}
MyDownloader.Extension/Notifications/NotificationsUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
using MyDownloader.Extension.Notifications.UI;
namespace MyDownloader.Extension.Notifications
{
public class NotificationsUIExtension : IUIExtension
{
#region IUIExtension Members
public Control[] CreateSettingsView()
{
return new Control[] { new SoundsOptions(), new XPBalloonOptions() };
}
public void PersistSettings(Control[] settingsView)
{
SoundsOptions sounds = (SoundsOptions)settingsView[0];
XPBalloonOptions ballon = (XPBalloonOptions)settingsView[1];
Settings.Default.DownloadAddedSound = sounds.DownloadAdded;
Settings.Default.DownloadRemovedSound = sounds.DownloadRemoved;
Settings.Default.DownloadEndedSound = sounds.DownloadEnded;
Settings.Default.ShowBallon = ballon.ShowBallon;
Settings.Default.BallonTimeout = ballon.BallonTimeout;
Settings.Default.Save();
}
#endregion
}
}
MyDownloader.Extension/Notifications/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Extension.Notifications {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string DownloadAddedSound {
get {
return ((string)(this["DownloadAddedSound"]));
}
set {
this["DownloadAddedSound"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string DownloadRemovedSound {
get {
return ((string)(this["DownloadRemovedSound"]));
}
set {
this["DownloadRemovedSound"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string DownloadEndedSound {
get {
return ((string)(this["DownloadEndedSound"]));
}
set {
this["DownloadEndedSound"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool ShowBallon {
get {
return ((bool)(this["ShowBallon"]));
}
set {
this["ShowBallon"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3000")]
public int BallonTimeout {
get {
return ((int)(this["BallonTimeout"]));
}
set {
this["BallonTimeout"] = value;
}
}
}
}
MyDownloader.Extension/Notifications/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Extension.Notifications" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="DownloadAddedSound" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="DownloadRemovedSound" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="DownloadEndedSound" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="ShowBallon" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="BallonTimeout" Type="System.Int32" Scope="User">
<Value Profile="(Default)">3000</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Extension/Notifications/UI/SoundChooser.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
namespace MyDownloader.Extension.Notifications.UI
{
partial class SoundChooser
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblText = new System.Windows.Forms.Label();
this.btnPreview = new System.Windows.Forms.Button();
this.txtSound = new System.Windows.Forms.TextBox();
this.btnSelect = new System.Windows.Forms.Button();
this.openFDlg = new System.Windows.Forms.OpenFileDialog();
this.SuspendLayout();
//
// lblText
//
this.lblText.AutoSize = true;
this.lblText.Location = new System.Drawing.Point(-3, 0);
this.lblText.Name = "lblText";
this.lblText.Size = new System.Drawing.Size(35, 13);
this.lblText.TabIndex = 0;
this.lblText.Text = "label1";
//
// btnPreview
//
this.btnPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnPreview.Location = new System.Drawing.Point(264, 14);
this.btnPreview.Name = "btnPreview";
this.btnPreview.Size = new System.Drawing.Size(75, 23);
this.btnPreview.TabIndex = 3;
this.btnPreview.Text = "Preview";
this.btnPreview.UseVisualStyleBackColor = true;
this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click);
//
// txtSound
//
this.txtSound.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtSound.Location = new System.Drawing.Point(0, 16);
this.txtSound.Name = "txtSound";
this.txtSound.Size = new System.Drawing.Size(230, 20);
this.txtSound.TabIndex = 1;
//
// btnSelect
//
this.btnSelect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnSelect.Location = new System.Drawing.Point(234, 14);
this.btnSelect.Name = "btnSelect";
this.btnSelect.Size = new System.Drawing.Size(27, 23);
this.btnSelect.TabIndex = 2;
this.btnSelect.Text = "...";
this.btnSelect.UseVisualStyleBackColor = true;
this.btnSelect.Click += new System.EventHandler(this.btnSelect_Click);
//
// openFDlg
//
this.openFDlg.Filter = "Wav Files (*.wav)|*.wav";
//
// SoundChooser
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnSelect);
this.Controls.Add(this.txtSound);
this.Controls.Add(this.btnPreview);
this.Controls.Add(this.lblText);
this.Name = "SoundChooser";
this.Size = new System.Drawing.Size(341, 41);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label lblText;
private System.Windows.Forms.Button btnPreview;
private System.Windows.Forms.TextBox txtSound;
private System.Windows.Forms.Button btnSelect;
private System.Windows.Forms.OpenFileDialog openFDlg;
}
}
MyDownloader.Extension/Notifications/UI/SoundChooser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Extension.Notifications.Helpers;
namespace MyDownloader.Extension.Notifications.UI
{
public partial class SoundChooser : UserControl
{
public SoundChooser()
{
InitializeComponent();
}
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get
{
return lblText.Text;
}
set
{
lblText.Text = value;
}
}
public string FileName
{
get
{
return txtSound.Text;
}
set
{
txtSound.Text = value;
}
}
private void btnSelect_Click(object sender, EventArgs e)
{
if (openFDlg.ShowDialog() == DialogResult.OK)
{
txtSound.Text = openFDlg.FileName;
}
}
private void btnPreview_Click(object sender, EventArgs e)
{
SoundHelper.PlayWav(txtSound.Text);
}
}
}
MyDownloader.Extension/Notifications/UI/SoundChooser.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="openFDlg.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
MyDownloader.Extension/Notifications/UI/SoundsOptions.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
namespace MyDownloader.Extension.Notifications.UI
{
partial class SoundsOptions
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.openFDlg = new System.Windows.Forms.OpenFileDialog();
this.soundChooserEnded = new MyDownloader.Extension.Notifications.UI.SoundChooser();
this.soundChooserRemoved = new MyDownloader.Extension.Notifications.UI.SoundChooser();
this.soundChooserAdded = new MyDownloader.Extension.Notifications.UI.SoundChooser();
this.SuspendLayout();
//
// openFDlg
//
this.openFDlg.Filter = "Wav Files (*.wav)|*.wav";
//
// soundChooserEnded
//
this.soundChooserEnded.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.soundChooserEnded.FileName = "";
this.soundChooserEnded.Location = new System.Drawing.Point(3, 94);
this.soundChooserEnded.Name = "soundChooserEnded";
this.soundChooserEnded.Size = new System.Drawing.Size(365, 41);
this.soundChooserEnded.TabIndex = 2;
this.soundChooserEnded.Text = "Download Ended";
//
// soundChooserRemoved
//
this.soundChooserRemoved.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.soundChooserRemoved.FileName = "";
this.soundChooserRemoved.Location = new System.Drawing.Point(3, 47);
this.soundChooserRemoved.Name = "soundChooserRemoved";
this.soundChooserRemoved.Size = new System.Drawing.Size(365, 41);
this.soundChooserRemoved.TabIndex = 1;
this.soundChooserRemoved.Text = "Download Removed";
//
// soundChooserAdded
//
this.soundChooserAdded.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.soundChooserAdded.FileName = "";
this.soundChooserAdded.Location = new System.Drawing.Point(3, 0);
this.soundChooserAdded.Name = "soundChooserAdded";
this.soundChooserAdded.Size = new System.Drawing.Size(365, 41);
this.soundChooserAdded.TabIndex = 0;
this.soundChooserAdded.Text = "Download Added";
//
// SoundsOptions
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.soundChooserEnded);
this.Controls.Add(this.soundChooserRemoved);
this.Controls.Add(this.soundChooserAdded);
this.Name = "SoundsOptions";
this.Size = new System.Drawing.Size(369, 226);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.OpenFileDialog openFDlg;
private SoundChooser soundChooserAdded;
private SoundChooser soundChooserRemoved;
private SoundChooser soundChooserEnded;
}
}
MyDownloader.Extension/Notifications/UI/SoundsOptions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.Notifications.UI
{
public partial class SoundsOptions : UserControl
{
public SoundsOptions()
{
this.Text = "Sounds";
InitializeComponent();
soundChooserAdded.FileName = Settings.Default.DownloadAddedSound;
soundChooserRemoved.FileName = Settings.Default.DownloadRemovedSound;
soundChooserEnded.FileName = Settings.Default.DownloadEndedSound;
}
public string DownloadAdded
{
get
{
return soundChooserAdded.FileName;
}
}
public string DownloadRemoved
{
get
{
return soundChooserRemoved.FileName;
}
}
public string DownloadEnded
{
get
{
return soundChooserEnded.FileName;
}
}
}
}
MyDownloader.Extension/Notifications/UI/SoundsOptions.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="openFDlg.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
MyDownloader.Extension/Notifications/UI/XPBalloonOptions.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
namespace MyDownloader.Extension.Notifications.UI
{
partial class XPBalloonOptions
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.chkBallon = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.numDuration = new System.Windows.Forms.NumericUpDown();
((System.ComponentModel.ISupportInitialize)(this.numDuration)).BeginInit();
this.SuspendLayout();
//
// chkBallon
//
this.chkBallon.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.chkBallon.AutoEllipsis = true;
this.chkBallon.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.chkBallon.Location = new System.Drawing.Point(0, 3);
this.chkBallon.Name = "chkBallon";
this.chkBallon.Size = new System.Drawing.Size(294, 19);
this.chkBallon.TabIndex = 0;
this.chkBallon.Text = "Show XP ballon when download finishes";
this.chkBallon.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.chkBallon.UseVisualStyleBackColor = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(-3, 30);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(50, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Duration:";
//
// numDuration
//
this.numDuration.Location = new System.Drawing.Point(0, 46);
this.numDuration.Name = "numDuration";
this.numDuration.Size = new System.Drawing.Size(120, 20);
this.numDuration.TabIndex = 2;
//
// XPBalloonOptions
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.numDuration);
this.Controls.Add(this.label1);
this.Controls.Add(this.chkBallon);
this.Name = "XPBalloonOptions";
this.Size = new System.Drawing.Size(294, 150);
((System.ComponentModel.ISupportInitialize)(this.numDuration)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkBallon;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown numDuration;
}
}
MyDownloader.Extension/Notifications/UI/XPBalloonOptions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.Notifications.UI
{
public partial class XPBalloonOptions : UserControl
{
public XPBalloonOptions()
{
this.Text = "Balloon";
InitializeComponent();
chkBallon.Checked = Settings.Default.ShowBallon;
numDuration.Value = Settings.Default.BallonTimeout / 1000;
}
public bool ShowBallon
{
get { return chkBallon.Checked; }
}
public int BallonTimeout
{
get { return (int)numDuration.Value * 1000; }
}
}
}
MyDownloader.Extension/Notifications/UI/XPBalloonOptions.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/PersistedList/PersistedListExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using MyDownloader.Core.Instrumentation;
using System.Diagnostics;
namespace MyDownloader.Extension.PersistedList
{
public class PersistedListExtension: IExtension, IDisposable
{
[Serializable]
public class DownloadItem
{
public ResourceLocation rl;
public ResourceLocation[] mirrors;
[XmlAttribute("lf")]
public string LocalFile;
public RemoteFileInfo remoteInfo;
[XmlAttribute("segCnt")]
public int requestedSegments;
[XmlAttribute("dt")]
public DateTime createdDateTime;
public SegmentItem[] Segments;
public SerializableDictionary<string, object> extendedProperties;
}
[Serializable]
public class SegmentItem
{
[XmlAttribute("i")]
public int Index;
[XmlAttribute("isp")]
public long InitialStartPositon;
[XmlAttribute("sp")]
public long StartPositon;
[XmlAttribute("ep")]
public long EndPosition;
}
private const int SaveListIntervalInSeconds = 120;
private XmlSerializer serializer;
private System.Threading.Timer timer;
private object SaveFromDispose = new object();
private object SaveFromTimer = new object();
private object SaveFromListChange = new object();
#region IExtension Members
public string Name
{
get { return "Persisted Download List"; }
}
public IUIExtension UIExtension
{
get { return null; }
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (timer != null)
{
timer.Dispose();
timer = null;
}
DownloadManager.Instance.PauseAll();
PersistList(SaveFromDispose);
}
#endregion
#region Methods
private void PersistList(object state)
{
List<DownloadItem> downloadsToSave = new List<DownloadItem>();
using (DownloadManager.Instance.LockDownloadList(false))
{
IList<Downloader> downloads = DownloadManager.Instance.Downloads;
for (int i = 0; i < downloads.Count; i++)
{
if (downloads[i].State == DownloaderState.Ended)
{
continue;
}
Downloader downloader = downloads[i];
DownloadItem di = new DownloadItem();
di.LocalFile = downloader.LocalFile;
di.rl = downloader.ResourceLocation;
di.mirrors = downloader.Mirrors.ToArray();
di.remoteInfo = downloader.RemoteFileInfo;
di.requestedSegments = downloader.RequestedSegments;
di.createdDateTime = downloader.CreatedDateTime;
di.extendedProperties = new SerializableDictionary<string,object>(downloader.ExtendedProperties);
using (downloader.LockSegments())
{
di.Segments = new SegmentItem[downloader.Segments.Count];
for (int j = 0; j < downloader.Segments.Count; j++)
{
SegmentItem si = new SegmentItem();
Segment seg = downloader.Segments[j];
si.Index = seg.Index;
si.InitialStartPositon = seg.InitialStartPosition;
si.StartPositon = seg.StartPosition;
si.EndPosition = seg.EndPosition;
di.Segments[j] = si;
}
}
downloadsToSave.Add(di);
}
}
SaveObjects(downloadsToSave);
}
private string GetDatabaseFile()
{
string file = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\" + "downloads.xml";
return file;
}
private void LoadSavedList()
{
if (File.Exists(GetDatabaseFile()))
{
try
{
using (FileStream fs = new FileStream(GetDatabaseFile(), FileMode.Open))
{
DownloadItem[] downloads = (DownloadItem[])serializer.Deserialize(fs);
LoadPersistedObjects(downloads);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
}
private void SaveObjects(List<DownloadItem> downloadsToSave)
{
using (new MyStopwatch("Saving download list"))
{
try
{
using (FileStream fs = new FileStream(GetDatabaseFile(), FileMode.Create))
{
serializer.Serialize(fs, downloadsToSave.ToArray());
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
}
private static void LoadPersistedObjects(DownloadItem[] downloads)
{
for (int i = 0; i < downloads.Length; i++)
{
List<Segment> segments = new List<Segment>();
for (int j = 0; j < downloads[i].Segments.Length; j++)
{
Segment seg = new Segment();
seg.Index = downloads[i].Segments[j].Index;
seg.InitialStartPosition = downloads[i].Segments[j].InitialStartPositon;
seg.StartPosition = downloads[i].Segments[j].StartPositon;
seg.EndPosition = downloads[i].Segments[j].EndPosition;
segments.Add(seg);
}
Downloader d = DownloadManager.Instance.Add(
downloads[i].rl,
downloads[i].mirrors,
downloads[i].LocalFile,
segments,
downloads[i].remoteInfo,
downloads[i].requestedSegments,
false,
downloads[i].createdDateTime);
if (downloads[i].extendedProperties != null)
{
SerializableDictionary<string, object>.Enumerator e = downloads[i].extendedProperties.GetEnumerator();
while (e.MoveNext())
{
d.ExtendedProperties.Add(e.Current.Key, e.Current.Value);
}
}
}
}
#endregion
#region Constructor
public PersistedListExtension()
{
serializer = new XmlSerializer(typeof(DownloadItem[]));
LoadSavedList();
TimerCallback refreshCallBack = new TimerCallback(PersistList);
TimeSpan refreshInterval = TimeSpan.FromSeconds(SaveListIntervalInSeconds);
timer = new Timer(refreshCallBack, null, new TimeSpan(-1), refreshInterval);
}
#endregion
}
}
MyDownloader.Extension/PersistedList/SerializableDictionary.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace MyDownloader.Extension.PersistedList
{
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>
: Dictionary<TKey, TValue>, IXmlSerializable
{
#region Constructor
public SerializableDictionary()
{
}
public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary)
{
}
#endregion
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
}
MyDownloader.Extension/Properties/AssemblyInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("MyDownloader.Extension")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Programmmers")]
[assembly: AssemblyProduct("MyDownloader.Extension")]
[assembly: AssemblyCopyright("Copyright © Programmmers 2007")]
[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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1d6ed868-3dc7-4db0-a934-7d01165843ae")]
// 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 Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
MyDownloader.Extension/Protocols/BaseProtocolProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace MyDownloader.Extension.Protocols
{
public class BaseProtocolProvider
{
static BaseProtocolProvider()
{
ServicePointManager.DefaultConnectionLimit = int.MaxValue;
}
protected WebRequest GetRequest(ResourceLocation location)
{
WebRequest request = WebRequest.Create(location.URL);
request.Timeout = 30000;
SetProxy(request);
return request;
}
protected void SetProxy(WebRequest request)
{
if (HttpFtpProtocolExtension.parameters.UseProxy)
{
WebProxy proxy = new WebProxy(HttpFtpProtocolExtension.parameters.ProxyAddress, HttpFtpProtocolExtension.parameters.ProxyPort);
proxy.BypassProxyOnLocal = HttpFtpProtocolExtension.parameters.ProxyByPassOnLocal;
request.Proxy = proxy;
if (!String.IsNullOrEmpty(HttpFtpProtocolExtension.parameters.ProxyUserName))
{
request.Proxy.Credentials = new NetworkCredential(
HttpFtpProtocolExtension.parameters.ProxyUserName,
HttpFtpProtocolExtension.parameters.ProxyPassword,
HttpFtpProtocolExtension.parameters.ProxyDomain);
}
}
}
}
}
MyDownloader.Extension/Protocols/FtpProtocolProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using MyDownloader.Core;
namespace MyDownloader.Extension.Protocols
{
public class FtpProtocolProvider: BaseProtocolProvider, IProtocolProvider
{
private void FillCredentials(FtpWebRequest request, ResourceLocation rl)
{
if (rl.Authenticate)
{
string login = rl.Login;
string domain = string.Empty;
int slashIndex = login.IndexOf('\\');
if (slashIndex >= 0)
{
domain = login.Substring(0, slashIndex);
login = login.Substring(slashIndex + 1);
}
NetworkCredential myCred = new NetworkCredential(login, rl.Password);
myCred.Domain = domain;
request.Credentials = myCred;
}
}
#region IProtocolProvider Members
public void Initialize(Downloader downloader)
{
}
public Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition)
{
FtpWebRequest request = (FtpWebRequest)GetRequest(rl);
FillCredentials(request, rl);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.ContentOffset = initialPosition;
WebResponse response = request.GetResponse();
return response.GetResponseStream();
}
public RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream)
{
FtpWebRequest request;
RemoteFileInfo result = new RemoteFileInfo();
result.AcceptRanges = true;
stream = null;
request = (FtpWebRequest)GetRequest(rl);
request.Method = WebRequestMethods.Ftp.GetFileSize;
FillCredentials(request, rl);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result.FileSize = response.ContentLength;
}
request = (FtpWebRequest)GetRequest(rl);
request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
FillCredentials(request, rl);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
result.LastModified = response.LastModified;
}
return result;
}
#endregion
}
}
MyDownloader.Extension/Protocols/HttpFtpProtocolExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
using System.IO;
namespace MyDownloader.Extension.Protocols
{
public class HttpFtpProtocolExtension: IExtension
{
internal static IHttpFtpProtocolParameters parameters;
#region IExtension Members
public string Name
{
get { return "HTTP/FTP"; }
}
public IUIExtension UIExtension
{
get { return new HttpFtpProtocolUIExtension(); }
}
public HttpFtpProtocolExtension():
this(new HttpFtpProtocolParametersSettingsProxy())
{
}
public HttpFtpProtocolExtension(IHttpFtpProtocolParameters parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
if (HttpFtpProtocolExtension.parameters != null)
{
throw new InvalidOperationException("The type HttpFtpProtocolExtension is already initialized.");
}
HttpFtpProtocolExtension.parameters = parameters;
ProtocolProviderFactory.RegisterProtocolHandler("http", typeof(HttpProtocolProvider));
ProtocolProviderFactory.RegisterProtocolHandler("https", typeof(HttpProtocolProvider));
ProtocolProviderFactory.RegisterProtocolHandler("ftp", typeof(FtpProtocolProvider));
}
#endregion
}
}
MyDownloader.Extension/Protocols/HttpFtpProtocolParametersSettingsProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.Protocols
{
class HttpFtpProtocolParametersSettingsProxy : IHttpFtpProtocolParameters
{
#region IHttpFtpProtocolParameters Members
public string ProxyAddress
{
get
{
return Settings.Default.ProxyAddress;
}
set
{
Settings.Default.ProxyAddress = value;
}
}
public string ProxyUserName
{
get
{
return Settings.Default.ProxyUserName;
}
set
{
Settings.Default.ProxyUserName = value;
}
}
public string ProxyPassword
{
get
{
return Settings.Default.ProxyPassword;
}
set
{
Settings.Default.ProxyPassword = value;
}
}
public string ProxyDomain
{
get
{
return Settings.Default.ProxyDomain;
}
set
{
Settings.Default.ProxyDomain = value;
}
}
public bool UseProxy
{
get
{
return Settings.Default.UseProxy;
}
set
{
Settings.Default.UseProxy = value;
}
}
public bool ProxyByPassOnLocal
{
get
{
return Settings.Default.ProxyByPassOnLocal;
}
set
{
Settings.Default.ProxyByPassOnLocal = value;
}
}
public int ProxyPort
{
get
{
return Settings.Default.ProxyPort;
}
set
{
Settings.Default.ProxyPort = value;
}
}
#endregion
}
}
MyDownloader.Extension/Protocols/HttpFtpProtocolUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
using MyDownloader.Extension.Protocols.UI;
namespace MyDownloader.Extension.Protocols
{
public class HttpFtpProtocolUIExtension : IUIExtension
{
#region IUIExtension Members
public System.Windows.Forms.Control[] CreateSettingsView()
{
return new Control[] { new Proxy() };
}
public void PersistSettings(System.Windows.Forms.Control[] settingsView)
{
Proxy proxy = (Proxy)settingsView[0];
Settings.Default.UseProxy = proxy.UseProxy;
Settings.Default.ProxyAddress = proxy.ProxyAddress;
Settings.Default.ProxyPort = proxy.ProxyPort;
Settings.Default.ProxyByPassOnLocal = proxy.ProxyByPassOnLocal;
Settings.Default.ProxyUserName = proxy.ProxyUserName;
Settings.Default.ProxyPassword = proxy.ProxyPassword;
Settings.Default.ProxyDomain = proxy.ProxyDomain;
Settings.Default.Save();
}
#endregion
}
}
MyDownloader.Extension/Protocols/HttpProtocolProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using MyDownloader.Core;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;
using MyDownloader.Core.Common;
namespace MyDownloader.Extension.Protocols
{
public class HttpProtocolProvider : BaseProtocolProvider, IProtocolProvider
{
private Downloader downloader;
static HttpProtocolProvider()
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(certificateCallBack);
}
static bool certificateCallBack(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
return true;
}
private void FillCredentials(HttpWebRequest request, ResourceLocation rl)
{
if (rl.Authenticate)
{
string login = rl.Login;
string domain = string.Empty;
int slashIndex = login.IndexOf('\\');
if (slashIndex >= 0)
{
domain = login.Substring(0, slashIndex );
login = login.Substring(slashIndex + 1);
}
NetworkCredential myCred = new NetworkCredential(login, rl.Password);
myCred.Domain = domain;
request.Credentials = myCred;
}
}
#region IProtocolProvider Members
public virtual void Initialize(Downloader d)
{
downloader = d;
}
private static CookieContainer GetUriCookieContainer(string uri)
{
CookieContainer cookies=new CookieContainer();
foreach (Cookie c in CookieManager.GetCookieCollection(uri))
cookies.SetCookies(new Uri(uri), c.ToString());
return cookies;
}
private HttpWebRequest GetRequest(ResourceLocation rl)
{
HttpWebRequest request = (HttpWebRequest)base.GetRequest(rl);
request.CookieContainer = GetUriCookieContainer(rl.URL);
return request;
}
public virtual Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition)
{
HttpWebRequest request = this.GetRequest(rl);
FillCredentials(request, rl);
if (initialPosition != 0)
{
if (endPosition == 0)
{
request.AddRange((int)initialPosition);
}
else
{
request.AddRange((int)initialPosition, (int)endPosition);
}
}
WebResponse response = request.GetResponse();
return response.GetResponseStream();
}
public virtual RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream)
{
restart:
HttpWebRequest request = this.GetRequest(rl);
FillCredentials(request, rl);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.ResponseUri.AbsoluteUri != rl.URL)
{
rl.URL = response.ResponseUri.AbsoluteUri;
goto restart;
}
RemoteFileInfo result = new RemoteFileInfo();
string filename=response.ResponseUri.LocalPath;
result.FileName = filename.Substring(filename.LastIndexOf("/") + 1);
if ((result.FileName == "") && response.ContentType == "text/html")
result.FileName = "temp.html";
result.MimeType = response.ContentType;
result.LastModified = response.LastModified;
result.FileSize = response.ContentLength;
result.AcceptRanges = String.Compare(response.Headers["Accept-Ranges"], "bytes", true) == 0;
stream = response.GetResponseStream();
return result;
}
#endregion
}
}
MyDownloader.Extension/Protocols/IHttpFtpProtocolParameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.Protocols
{
public interface IHttpFtpProtocolParameters
{
string ProxyAddress { get; set; }
string ProxyUserName { get; set; }
string ProxyPassword { get; set; }
string ProxyDomain { get; set; }
bool UseProxy { get; set; }
bool ProxyByPassOnLocal { get; set; }
int ProxyPort { get; set; }
}
}
MyDownloader.Extension/Protocols/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Extension.Protocols {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ProxyAddress {
get {
return ((string)(this["ProxyAddress"]));
}
set {
this["ProxyAddress"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ProxyUserName {
get {
return ((string)(this["ProxyUserName"]));
}
set {
this["ProxyUserName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ProxyPassword {
get {
return ((string)(this["ProxyPassword"]));
}
set {
this["ProxyPassword"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ProxyDomain {
get {
return ((string)(this["ProxyDomain"]));
}
set {
this["ProxyDomain"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool UseProxy {
get {
return ((bool)(this["UseProxy"]));
}
set {
this["UseProxy"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool ProxyByPassOnLocal {
get {
return ((bool)(this["ProxyByPassOnLocal"]));
}
set {
this["ProxyByPassOnLocal"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("80")]
public int ProxyPort {
get {
return ((int)(this["ProxyPort"]));
}
set {
this["ProxyPort"] = value;
}
}
}
}
MyDownloader.Extension/Protocols/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Extension.Protocols" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="ProxyAddress" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="ProxyUserName" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="ProxyPassword" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="ProxyDomain" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="UseProxy" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="ProxyByPassOnLocal" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="ProxyPort" Type="System.Int32" Scope="User">
<Value Profile="(Default)">80</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Extension/Protocols/UI/Proxy.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
namespace MyDownloader.Extension.Protocols.UI
{
partial class Proxy
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.chkUseProxy = new System.Windows.Forms.CheckBox();
this.txtProxtAddress = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.numProxyPort = new System.Windows.Forms.NumericUpDown();
this.label3 = new System.Windows.Forms.Label();
this.txtUsername = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.txtPassword = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.txtDomain = new System.Windows.Forms.TextBox();
this.chkBypass = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).BeginInit();
this.SuspendLayout();
//
// chkUseProxy
//
this.chkUseProxy.AutoSize = true;
this.chkUseProxy.Location = new System.Drawing.Point(0, 3);
this.chkUseProxy.Name = "chkUseProxy";
this.chkUseProxy.Size = new System.Drawing.Size(73, 17);
this.chkUseProxy.TabIndex = 0;
this.chkUseProxy.Text = "Use proxy";
this.chkUseProxy.UseVisualStyleBackColor = true;
this.chkUseProxy.CheckedChanged += new System.EventHandler(this.chkUseProxy_CheckedChanged);
//
// txtProxtAddress
//
this.txtProxtAddress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtProxtAddress.Location = new System.Drawing.Point(1, 43);
this.txtProxtAddress.Name = "txtProxtAddress";
this.txtProxtAddress.Size = new System.Drawing.Size(306, 20);
this.txtProxtAddress.TabIndex = 2;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(0, 27);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(77, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Proxy Address:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(0, 73);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(58, 13);
this.label2.TabIndex = 3;
this.label2.Text = "Proxy Port:";
//
// numProxyPort
//
this.numProxyPort.Location = new System.Drawing.Point(3, 90);
this.numProxyPort.Maximum = new decimal(new int[] {
65535,
0,
0,
0});
this.numProxyPort.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numProxyPort.Name = "numProxyPort";
this.numProxyPort.Size = new System.Drawing.Size(88, 20);
this.numProxyPort.TabIndex = 4;
this.numProxyPort.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(1, 169);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(63, 13);
this.label3.TabIndex = 6;
this.label3.Text = "User Name:";
//
// txtUsername
//
this.txtUsername.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtUsername.Location = new System.Drawing.Point(2, 185);
this.txtUsername.Name = "txtUsername";
this.txtUsername.Size = new System.Drawing.Size(306, 20);
this.txtUsername.TabIndex = 7;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(0, 211);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(56, 13);
this.label4.TabIndex = 8;
this.label4.Text = "Password:";
//
// txtPassword
//
this.txtPassword.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtPassword.Location = new System.Drawing.Point(2, 227);
this.txtPassword.Name = "txtPassword";
this.txtPassword.Size = new System.Drawing.Size(306, 20);
this.txtPassword.TabIndex = 9;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(0, 258);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(46, 13);
this.label5.TabIndex = 10;
this.label5.Text = "Domain:";
//
// txtDomain
//
this.txtDomain.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtDomain.Location = new System.Drawing.Point(1, 274);
this.txtDomain.Name = "txtDomain";
this.txtDomain.Size = new System.Drawing.Size(306, 20);
this.txtDomain.TabIndex = 11;
//
// chkBypass
//
this.chkBypass.AutoSize = true;
this.chkBypass.Location = new System.Drawing.Point(1, 131);
this.chkBypass.Name = "chkBypass";
this.chkBypass.Size = new System.Drawing.Size(100, 17);
this.chkBypass.TabIndex = 5;
this.chkBypass.Text = "Bypass on local";
this.chkBypass.UseVisualStyleBackColor = true;
//
// Proxy
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.txtDomain);
this.Controls.Add(this.txtPassword);
this.Controls.Add(this.txtUsername);
this.Controls.Add(this.txtProxtAddress);
this.Controls.Add(this.chkBypass);
this.Controls.Add(this.label5);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.numProxyPort);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.chkUseProxy);
this.Name = "Proxy";
this.Size = new System.Drawing.Size(308, 308);
((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkUseProxy;
private System.Windows.Forms.TextBox txtProxtAddress;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown numProxyPort;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtUsername;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox txtDomain;
private System.Windows.Forms.CheckBox chkBypass;
}
}
MyDownloader.Extension/Protocols/UI/Proxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.Protocols.UI
{
public partial class Proxy : UserControl
{
public Proxy()
{
this.Text = "Proxy";
InitializeComponent();
UseProxy = Settings.Default.UseProxy;
ProxyAddress = Settings.Default.ProxyAddress;
ProxyPort = Settings.Default.ProxyPort;
ProxyByPassOnLocal = Settings.Default.ProxyByPassOnLocal;
ProxyUserName = Settings.Default.ProxyUserName;
ProxyPassword = Settings.Default.ProxyPassword;
ProxyDomain = Settings.Default.ProxyDomain;
UpdateControls();
}
public bool UseProxy
{
get
{
return chkUseProxy.Checked;
}
set
{
chkUseProxy.Checked = value;
}
}
public string ProxyAddress
{
get
{
return txtProxtAddress.Text;
}
set
{
txtProxtAddress.Text = value;
}
}
public int ProxyPort
{
get
{
return (int)numProxyPort.Value;
}
set
{
numProxyPort.Value = value;
}
}
public bool ProxyByPassOnLocal
{
get
{
return chkBypass.Checked;
}
set
{
chkBypass.Checked = value;
}
}
public string ProxyUserName
{
get
{
return txtUsername.Text;
}
set
{
txtUsername.Text = value;
}
}
public string ProxyPassword
{
get
{
return txtPassword.Text;
}
set
{
txtPassword.Text = value;
}
}
public string ProxyDomain
{
get
{
return txtDomain.Text;
}
set
{
txtDomain.Text = value;
}
}
private void chkUseProxy_CheckedChanged(object sender, EventArgs e)
{
UpdateControls();
}
private void UpdateControls()
{
for (int i = 0; i < this.Controls.Count; i++)
{
if (this.Controls[i] != chkUseProxy)
{
this.Controls[i].Enabled = chkUseProxy.Checked;
}
}
}
}
}
MyDownloader.Extension/Protocols/UI/Proxy.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/SpeedLimit/ISpeedLimitParameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
namespace MyDownloader.Extension.SpeedLimit
{
public interface ISpeedLimitParameters: IExtensionParameters
{
bool Enabled { get; set; }
double MaxRate { get; set; }
}
}
MyDownloader.Extension/SpeedLimit/LimitedRateStreamProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
namespace MyDownloader.Extension.SpeedLimit
{
public class LimitedRateStreamProxy: Stream
{
private Stream proxy;
private SpeedLimitExtension speedLimit;
#region Stream
public override bool CanRead
{
get { return proxy.CanRead; }
}
public override bool CanSeek
{
get { return proxy.CanSeek; }
}
public override bool CanWrite
{
get { return proxy.CanWrite; }
}
public override void Flush()
{
proxy.Flush();
}
public override long Length
{
get { return proxy.Length; }
}
public override long Position
{
get
{
return proxy.Position;
}
set
{
proxy.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
speedLimit.WaitFor();
return proxy.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return proxy.Seek(offset, origin);
}
public override void SetLength(long value)
{
proxy.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
proxy.Write(buffer, offset, count);
}
#endregion
public LimitedRateStreamProxy(Stream proxy, SpeedLimitExtension speedLimit)
{
this.speedLimit = speedLimit;
this.proxy = proxy;
}
}
}
MyDownloader.Extension/SpeedLimit/ProtocolProviderProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
namespace MyDownloader.Extension.SpeedLimit
{
public class ProtocolProviderProxy: IProtocolProvider
{
private IProtocolProvider proxy;
private SpeedLimitExtension speedLimit;
#region IProtocolProvider Members
public void Initialize(Downloader downloader)
{
proxy.Initialize(downloader);
}
public System.IO.Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition)
{
return new LimitedRateStreamProxy(proxy.CreateStream(rl, initialPosition, endPosition), speedLimit);
}
public RemoteFileInfo GetFileInfo(ResourceLocation rl, out System.IO.Stream stream)
{
RemoteFileInfo result = proxy.GetFileInfo(rl, out stream);
if (stream != null)
{
stream = new LimitedRateStreamProxy(stream, speedLimit);
}
return result;
}
#endregion
public ProtocolProviderProxy(IProtocolProvider proxy, SpeedLimitExtension speedLimit)
{
this.proxy = proxy;
this.speedLimit = speedLimit;
}
}
}
MyDownloader.Extension/SpeedLimit/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Extension.SpeedLimit {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool EnabledLimit {
get {
return ((bool)(this["EnabledLimit"]));
}
set {
this["EnabledLimit"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1024")]
public double MaxRate {
get {
return ((double)(this["MaxRate"]));
}
set {
this["MaxRate"] = value;
}
}
}
}
MyDownloader.Extension/SpeedLimit/Settings.settings
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Extension.SpeedLimit" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="EnabledLimit" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="MaxRate" Type="System.Double" Scope="User">
<Value Profile="(Default)">1024</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Extension/SpeedLimit/SpeedLimitExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using System.ComponentModel;
namespace MyDownloader.Extension.SpeedLimit
{
public class SpeedLimitExtension: IExtension, IDisposable
{
private const int BalancerUp = 50;
private const int BalancerDown = -75;
private double currentWait;
private bool enabled;
private double maxLimit;
private ISpeedLimitParameters parameters;
#region IExtension Members
public string Name
{
get { return "Speed Limit"; }
}
public IUIExtension UIExtension
{
get { return new SpeedLimitUIExtension(); }
}
#endregion
#region Properties
public ISpeedLimitParameters Parameters
{
get { return parameters; }
}
public bool CurrentEnabled
{
get { return enabled; }
}
public double CurrentMaxRate
{
get { return maxLimit; }
}
#endregion
#region Methods
public void SetMaxRateTemp(double max)
{
this.enabled = true;
this.maxLimit = max;
}
public void RestoreMaxRateFromParameters()
{
ReadSettings();
}
private void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
ReadSettings();
}
private void ReadSettings()
{
currentWait = 0;
maxLimit = Parameters.MaxRate;
enabled = Parameters.Enabled;
}
private void ProtocolProviderFactory_ResolvingProtocolProvider(object sender, ResolvingProtocolProviderEventArgs e)
{
e.ProtocolProvider = new ProtocolProviderProxy(e.ProtocolProvider, this);
}
internal void WaitFor()
{
if (enabled)
{
double totalRate = DownloadManager.Instance.TotalDownloadRate;
if (totalRate > maxLimit)
{
currentWait += BalancerUp;
}
else
{
currentWait = Math.Max(currentWait + BalancerDown, 0);
}
Thread.Sleep(TimeSpan.FromMilliseconds(currentWait));
Debug.WriteLine("TotalDownloadRate = " + totalRate);
Debug.WriteLine("maxLimit = " + maxLimit);
Debug.WriteLine("currentWait = " + currentWait);
}
}
#endregion
#region Constructor
public SpeedLimitExtension()
:
this(new SpeedLimitParametersSettingProxy())
{
}
public SpeedLimitExtension(ISpeedLimitParameters parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
this.parameters = parameters;
ReadSettings();
ProtocolProviderFactory.ResolvingProtocolProvider += new EventHandler<ResolvingProtocolProviderEventArgs>(ProtocolProviderFactory_ResolvingProtocolProvider);
this.parameters.ParameterChanged += new PropertyChangedEventHandler(Default_PropertyChanged);
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (this.parameters is IDisposable)
{
(this.parameters as IDisposable).Dispose();
}
}
#endregion
}
}
MyDownloader.Extension/SpeedLimit/SpeedLimitParametersSettingProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.SpeedLimit
{
internal class SpeedLimitParametersSettingProxy : ISpeedLimitParameters, IDisposable
{
#region ISpeedLimitParameters Members
public bool Enabled
{
get
{
return Settings.Default.EnabledLimit;
}
set
{
Settings.Default.EnabledLimit = value;
OnParameterChanged("Enabled");
}
}
public double MaxRate
{
get
{
return Settings.Default.MaxRate;
}
set
{
Settings.Default.MaxRate = value;
OnParameterChanged("MaxRate");
}
}
#endregion
#region IExtensionParameters Members
public event System.ComponentModel.PropertyChangedEventHandler ParameterChanged;
#endregion
#region Methods
protected void OnParameterChanged(string propertyname)
{
if (ParameterChanged != null)
{
ParameterChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyname));
}
}
void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
OnParameterChanged(e.PropertyName);
}
#endregion
#region IDisposable Members
public void Dispose()
{
Settings.Default.Save();
}
#endregion
public SpeedLimitParametersSettingProxy()
{
Settings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Default_PropertyChanged);
}
}
}
MyDownloader.Extension/SpeedLimit/SpeedLimitUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
using MyDownloader.Extension.SpeedLimit.UI;
namespace MyDownloader.Extension.SpeedLimit
{
public class SpeedLimitUIExtension: IUIExtension
{
#region IUIExtension Members
public Control[] CreateSettingsView()
{
return new Control[] { new LimitCfg() };
}
public void PersistSettings(Control[] settingsView)
{
LimitCfg lmt = (LimitCfg)settingsView[0];
Settings.Default.MaxRate = lmt.MaxRate;
Settings.Default.EnabledLimit = lmt.EnableLimit;
Settings.Default.Save();
}
#endregion
public void ShowSpeedLimitDialog()
{
using (SetSpeedLimitDialog sld = new SetSpeedLimitDialog())
{
if (sld.ShowDialog() == DialogResult.OK)
{
PersistSettings(new Control[] { sld.limitCfg1 });
}
}
}
}
}
MyDownloader.Extension/SpeedLimit/UI/LimitCfg.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
namespace MyDownloader.Extension.SpeedLimit.UI
{
partial class LimitCfg
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.chkEnableLimit = new System.Windows.Forms.CheckBox();
this.numMaxRate = new System.Windows.Forms.NumericUpDown();
this.lblMaxRate = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).BeginInit();
this.SuspendLayout();
//
// chkEnableLimit
//
this.chkEnableLimit.AutoSize = true;
this.chkEnableLimit.Location = new System.Drawing.Point(0, 0);
this.chkEnableLimit.Name = "chkEnableLimit";
this.chkEnableLimit.Size = new System.Drawing.Size(111, 17);
this.chkEnableLimit.TabIndex = 0;
this.chkEnableLimit.Text = "Enable speed limit";
this.chkEnableLimit.UseVisualStyleBackColor = true;
this.chkEnableLimit.CheckedChanged += new System.EventHandler(this.chkEnableLimit_CheckedChanged);
//
// numMaxRate
//
this.numMaxRate.Location = new System.Drawing.Point(0, 48);
this.numMaxRate.Maximum = new decimal(new int[] {
1000,
0,
0,
0});
this.numMaxRate.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numMaxRate.Name = "numMaxRate";
this.numMaxRate.Size = new System.Drawing.Size(96, 20);
this.numMaxRate.TabIndex = 2;
this.numMaxRate.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// lblMaxRate
//
this.lblMaxRate.AutoSize = true;
this.lblMaxRate.Location = new System.Drawing.Point(-3, 32);
this.lblMaxRate.Name = "lblMaxRate";
this.lblMaxRate.Size = new System.Drawing.Size(88, 13);
this.lblMaxRate.TabIndex = 1;
this.lblMaxRate.Text = "Max Rate (kbps):";
//
// LimitCfg
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.numMaxRate);
this.Controls.Add(this.lblMaxRate);
this.Controls.Add(this.chkEnableLimit);
this.Name = "LimitCfg";
this.Size = new System.Drawing.Size(192, 71);
((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkEnableLimit;
private System.Windows.Forms.NumericUpDown numMaxRate;
private System.Windows.Forms.Label lblMaxRate;
}
}
MyDownloader.Extension/SpeedLimit/UI/LimitCfg.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.SpeedLimit.UI
{
public partial class LimitCfg : UserControl
{
public LimitCfg()
{
InitializeComponent();
Text = "Speed Limit";
chkEnableLimit.Checked = Settings.Default.EnabledLimit;
numMaxRate.Value = (decimal)(Math.Max(Settings.Default.MaxRate, 1024) / 1024.0);
UpdateUI();
}
private void chkEnableLimit_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
}
public double MaxRate
{
get { return ((double)numMaxRate.Value) * 1024; }
}
public bool EnableLimit
{
get { return chkEnableLimit.Checked; }
}
private void UpdateUI()
{
lblMaxRate.Enabled = chkEnableLimit.Checked;
numMaxRate.Enabled = chkEnableLimit.Checked;
}
}
}
MyDownloader.Extension/SpeedLimit/UI/LimitCfg.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
namespace MyDownloader.Extension.SpeedLimit.UI
{
partial class SetSpeedLimitDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnCancel = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.limitCfg1 = new MyDownloader.Extension.SpeedLimit.UI.LimitCfg();
this.SuspendLayout();
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(105, 88);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// btnOK
//
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(24, 88);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 1;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
//
// limitCfg1
//
this.limitCfg1.Location = new System.Drawing.Point(8, 8);
this.limitCfg1.Name = "limitCfg1";
this.limitCfg1.Size = new System.Drawing.Size(168, 71);
this.limitCfg1.TabIndex = 0;
//
// SetSpeedLimitDialog
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(186, 117);
this.Controls.Add(this.limitCfg1);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SetSpeedLimitDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Set download limit";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
internal LimitCfg limitCfg1;
}
}
MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.SpeedLimit.UI
{
public partial class SetSpeedLimitDialog : Form
{
public SetSpeedLimitDialog()
{
InitializeComponent();
}
}
}
MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/Video/Impl/BaseVideoDownloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Extension.Protocols;
using MyDownloader.Core;
using System.IO;
using System.Net;
namespace MyDownloader.Extension.Video.Impl
{
public abstract class BaseVideoDownloader : HttpProtocolProvider
{
private ResourceLocation mappedUrl;
void downloader_Ending(object sender, EventArgs e)
{
Downloader d = (Downloader)sender;
VideoConverter.ConvertIfNecessary(d);
}
protected abstract ResourceLocation ResolveVideoURL(string url, string pageData, out string videoTitle);
public override void Initialize(Downloader downloader)
{
base.Initialize(downloader);
downloader.Ending += new EventHandler(downloader_Ending);
}
public override Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition)
{
return base.CreateStream(mappedUrl ?? rl, initialPosition, endPosition);
}
public override RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream)
{
stream = null;
mappedUrl = null;
String title;
String pageData = GetPageData(rl);
mappedUrl = ResolveVideoURL(rl.URL, pageData, out title);
WebRequest request = this.GetRequest(mappedUrl);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
RemoteFileInfo result = new RemoteFileInfo();
result.FileSize = response.ContentLength;
result.AcceptRanges = String.Compare(response.Headers["Accept-Ranges"], "bytes", true) == 0;
if (response.ResponseUri != null)
{
mappedUrl.URL = response.ResponseUri.OriginalString;
}
else
{
stream = response.GetResponseStream();
}
return result;
}
}
private String GetPageData(ResourceLocation rl)
{
String pageData;
using (StreamReader sr = new StreamReader(this.CreateStream(rl, 0, 0)))
{
pageData = sr.ReadToEnd();
}
return pageData;
}
public string GetTitle(ResourceLocation rl)
{
String pageData = GetPageData(rl);
string title;
mappedUrl = ResolveVideoURL(rl.URL, pageData, out title);
return title;
}
}
}
MyDownloader.Extension/Video/Impl/BreakVideoDownloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using System.Diagnostics;
namespace MyDownloader.Extension.Video.Impl
{
public class BreakVideoDownloader: BaseVideoDownloader
{
public const string SiteName = "Break";
//http://my.break.com/content/view.aspx?ContentID=393301
//http://www.break.com/canon/canon-battle-of-viral-video-super-stars.html
//http://www.break.com/index/tomorrow-is-spank-it-saturday.html
public const string UrlPattern = @"(?:[Bb][Rr][Ee][Aa][Kk]\.[Cc][Oo][Mm]/)(\w[\w|-]*)";
protected override ResourceLocation ResolveVideoURL(string url, string pageData,
out string videoTitle)
{
string sGlobalFileName = TextUtil.JustAfter(pageData, "sGlobalFileName='", "';");
string sGlobalContentFilePath = TextUtil.JustAfter(pageData, "sGlobalContentFilePath='", "';");
string flvUrl = TextUtil.JustAfter(pageData, "so.addVariable('videoPath', '", "');")
.Replace("'+sGlobalContentFilePath+'", sGlobalContentFilePath)
.Replace("'+sGlobalFileName+'", sGlobalFileName);
string wmvUrl = TextUtil.JustAfter(pageData, "<param name=\"fileName\" value=\"", " />")
.Replace("'+sGlobalContentFilePath+'", sGlobalContentFilePath)
.Replace("'+sGlobalFileName+'", sGlobalFileName);
Debug.WriteLine(wmvUrl);
videoTitle = TextUtil.JustAfter(pageData, "<meta name=\"embed_video_title\" content=\"", "\" />");
return ResourceLocation.FromURL(flvUrl);
}
}
}
MyDownloader.Extension/Video/Impl/GoogleVideoDownloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Extension.Protocols;
using MyDownloader.Core;
using System.IO;
using System.Net;
using System.Web;
namespace MyDownloader.Extension.Video.Impl
{
public class GoogleVideoDownloader : BaseVideoDownloader
{
public const string SiteName = "Google Video";
//http://video.google.com/videoplay?docid=6527966434248029824
//http://video.google.com/videoplay?docid=-3840236067834151894
public const string UrlPattern = @"(?:[Vv][Ii][Dd][Ee][Oo]\.[Gg][Oo][Oo][Gg][Ll][Ee]\.[Cc][Oo][Mm]/videoplay\?docid=)-?(\w[\w|-]*)";
protected override ResourceLocation ResolveVideoURL(string url, string pageData,
out string videoTitle)
{
videoTitle = TextUtil.JustAfter(pageData, "<title>", "</title>");
url = TextUtil.JustAfter(pageData, "src=\"/googleplayer.swf?&videoUrl=", "&thumbnailUrl=");
return ResourceLocation.FromURL(HttpUtility.UrlDecode(url));
}
}
}
MyDownloader.Extension/Video/Impl/MetaCafeVideoDownloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using MyDownloader.Core;
namespace MyDownloader.Extension.Video.Impl
{
public class MetaCafeVideoDownloader: BaseVideoDownloader
{
public const string SiteName = "Meta Cafe";
//http://www.metacafe.com/watch/851582/village_idiots/
public const string UrlPattern = @"(?:[Mm][Ee][Ta][Aa][Cc][Aa][Ff][Ee]\.[Cc][Oo][Mm]/watch/)(\w[\w|-]*)/(\w[\w|-]*)";
protected override ResourceLocation ResolveVideoURL(string url,
string pageData, out string videoTitle)
{
url = TextUtil.JustAfter(pageData, "mediaURL=", "&");
videoTitle = TextUtil.JustAfter(pageData, "<title>", "</title>");
return ResourceLocation.FromURL(HttpUtility.UrlDecode(url));
}
}
}
MyDownloader.Extension/Video/Impl/PutfileVideoDownloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
namespace MyDownloader.Extension.Video.Impl
{
public class PutfileVideoDownloader: BaseVideoDownloader
{
public const string SiteName = "PutFile";
//http://media.putfile.com/kilo-the-amazing-pitt
public const string UrlPattern = @"(?:[Mm][Ee][Dd][Ii][Aa]\.[Pp][Uu][Tt][Ff][Ii][Ll][Ee]\.[Cc][Oo][Mm]/)(\w[\w|-]*)";
protected override ResourceLocation ResolveVideoURL(string url, string pageData,
out string videoTitle)
{
url = TextUtil.JustAfter(pageData, "so1.addVariable(\"flv\", \"", "\");");
videoTitle = TextUtil.JustAfter(pageData, "<meta name=\"title\" content=\"", "\" />");
return ResourceLocation.FromURL(url);
}
}
}
MyDownloader.Extension/Video/Impl/YouTubeDownloader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using System.IO;
using MyDownloader.Extension.Protocols;
using System.Net;
namespace MyDownloader.Extension.Video.Impl
{
public class YouTubeDownloader: BaseVideoDownloader
{
public const string SiteName = "You Tube";
//http://www.youtube.com/watch?v=5zOevLN3Tic
public const string UrlPattern = @"(?:[Yy][Oo][Uu][Tt][Uu][Bb][Ee]\.[Cc][Oo][Mm]/watch\?v=)(\w[\w|-]*)";
protected override ResourceLocation ResolveVideoURL(string url, string pageData,
out string videoTitle)
{
videoTitle = TextUtil.JustAfter(pageData, "<meta name=\"title\" content=\"", "\">");
return ResourceLocation.FromURL(String.Format("{0}/get_video?video_id={1}&t={2}", TextUtil.GetDomain(url),
TextUtil.JustAfter(url, "v=", "&"), TextUtil.JustAfter(pageData, "&t=", "&hl=")));
}
}
}
MyDownloader.Extension/Video/TextUtil.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Extension.Video
{
internal static class TextUtil
{
internal static string JustBefore(string Str, string Seq)
{
string Orgi = Str;
try
{
Str = Str.ToLower();
Seq = Seq.ToLower();
return Orgi.Substring(0, Str.Length - (Str.Length - Str.IndexOf(Seq)));
}
catch (Exception)
{
return "";
}
}
internal static string GetDomain(String URL)
{
return URL.Substring(0, URL.LastIndexOf("/"));
}
internal static string GetFilename(String URL)
{
string Filename = URL.Substring(URL.LastIndexOf("/") + 2, URL.Length - URL.LastIndexOf("/") - 2);
if (Filename.IndexOf("&") != -1)
Filename = JustBefore(Filename, "&");
return Filename;
}
internal static string JustAfter(string Str, string Seq, string SeqEnd)
{
string Orgi = Str;
try
{
Str = Str.ToLower();
Seq = Seq.ToLower();
int i = Str.IndexOf(Seq);
if (i < 0)
return null;
i = i + Seq.Length;
int j = Str.IndexOf(SeqEnd, i);
int end;
if (j > 0) end = j - i;
else end = Str.Length - i;
return Orgi.Substring(i, end);
}
catch (Exception)
{
return "";
}
}
internal static string JustAfter(string Str, string Seq)
{
string Orgi = Str;
try
{
Str = Str.ToLower();
Seq = Seq.ToLower();
int i = Str.IndexOf(Seq);
if (i < 0)
return null;
i = i + Seq.Length;
return Orgi.Substring(i, Str.Length - i);
}
catch (Exception)
{
return "";
}
}
}
}
MyDownloader.Extension/Video/UI/NewVideoDownload.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
namespace MyDownloader.Extension.Video.UI
{
partial class NewVideoDownload
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnCancel = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.txtFilename = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label9 = new System.Windows.Forms.Label();
this.chkStartNow = new System.Windows.Forms.CheckBox();
this.txtURL = new System.Windows.Forms.TextBox();
this.numSegments = new System.Windows.Forms.NumericUpDown();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.lblSites = new System.Windows.Forms.LinkLabel();
this.videoFormatCtrl1 = new MyDownloader.Extension.Video.UI.VideoFormatCtrl();
this.downloadFolder1 = new MyDownloader.Core.UI.DownloadFolder();
this.waitControl1 = new MyDownloader.Core.UI.WaitControl();
((System.ComponentModel.ISupportInitialize)(this.numSegments)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(392, 246);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 12;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// btnOK
//
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Enabled = false;
this.btnOK.Location = new System.Drawing.Point(312, 246);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 11;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// txtFilename
//
this.txtFilename.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtFilename.Location = new System.Drawing.Point(8, 171);
this.txtFilename.Name = "txtFilename";
this.txtFilename.Size = new System.Drawing.Size(456, 20);
this.txtFilename.TabIndex = 8;
this.txtFilename.Leave += new System.EventHandler(this.txtFilename_Leave);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(8, 155);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(55, 13);
this.label4.TabIndex = 7;
this.label4.Text = "File name:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(5, 56);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(54, 13);
this.label2.TabIndex = 3;
this.label2.Text = "Segments";
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(8, 8);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(311, 13);
this.label9.TabIndex = 0;
this.label9.Text = "URL (e.g: http://www.youtube.com/watch?v=AdPWWDkKS8s)";
//
// chkStartNow
//
this.chkStartNow.AutoSize = true;
this.chkStartNow.Location = new System.Drawing.Point(116, 74);
this.chkStartNow.Name = "chkStartNow";
this.chkStartNow.Size = new System.Drawing.Size(73, 17);
this.chkStartNow.TabIndex = 5;
this.chkStartNow.Text = "Start Now";
this.chkStartNow.UseVisualStyleBackColor = true;
//
// txtURL
//
this.txtURL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtURL.Location = new System.Drawing.Point(8, 24);
this.txtURL.Name = "txtURL";
this.txtURL.Size = new System.Drawing.Size(456, 20);
this.txtURL.TabIndex = 1;
this.txtURL.TextChanged += new System.EventHandler(this.txtURL_TextChanged);
//
// numSegments
//
this.numSegments.Location = new System.Drawing.Point(8, 72);
this.numSegments.Name = "numSegments";
this.numSegments.Size = new System.Drawing.Size(75, 20);
this.numSegments.TabIndex = 4;
this.numSegments.Value = new decimal(new int[] {
2,
0,
0,
0});
//
// pictureBox1
//
this.pictureBox1.InitialImage = null;
this.pictureBox1.Location = new System.Drawing.Point(192, 46);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(272, 72);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.pictureBox1.TabIndex = 36;
this.pictureBox1.TabStop = false;
//
// lblSites
//
this.lblSites.AutoSize = true;
this.lblSites.Location = new System.Drawing.Point(384, 8);
this.lblSites.Name = "lblSites";
this.lblSites.Size = new System.Drawing.Size(80, 13);
this.lblSites.TabIndex = 2;
this.lblSites.TabStop = true;
this.lblSites.Text = "Supported sites";
this.lblSites.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblSites_LinkClicked);
//
// videoFormatCtrl1
//
this.videoFormatCtrl1.Location = new System.Drawing.Point(8, 112);
this.videoFormatCtrl1.Name = "videoFormatCtrl1";
this.videoFormatCtrl1.Size = new System.Drawing.Size(208, 40);
this.videoFormatCtrl1.TabIndex = 6;
this.videoFormatCtrl1.VideoFormat = MyDownloader.Extension.Video.VideoFormat.None;
//
// downloadFolder1
//
this.downloadFolder1.LabelText = "Save to:";
this.downloadFolder1.Location = new System.Drawing.Point(8, 197);
this.downloadFolder1.Name = "downloadFolder1";
this.downloadFolder1.Size = new System.Drawing.Size(456, 43);
this.downloadFolder1.TabIndex = 9;
//
// waitControl1
//
this.waitControl1.Location = new System.Drawing.Point(8, 248);
this.waitControl1.Name = "waitControl1";
this.waitControl1.Size = new System.Drawing.Size(288, 16);
this.waitControl1.TabIndex = 37;
this.waitControl1.Text = "Getting video title...";
this.waitControl1.Visible = false;
//
// NewVideoDownload
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(471, 273);
this.Controls.Add(this.waitControl1);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.videoFormatCtrl1);
this.Controls.Add(this.lblSites);
this.Controls.Add(this.txtFilename);
this.Controls.Add(this.label4);
this.Controls.Add(this.label2);
this.Controls.Add(this.label9);
this.Controls.Add(this.chkStartNow);
this.Controls.Add(this.txtURL);
this.Controls.Add(this.numSegments);
this.Controls.Add(this.btnOK);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.downloadFolder1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "NewVideoDownload";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "New Video Download";
this.Load += new System.EventHandler(this.NewVideoDownload_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NewVideoDownload_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.numSegments)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.TextBox txtFilename;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.CheckBox chkStartNow;
private System.Windows.Forms.TextBox txtURL;
private System.Windows.Forms.NumericUpDown numSegments;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.LinkLabel lblSites;
private VideoFormatCtrl videoFormatCtrl1;
private MyDownloader.Core.UI.DownloadFolder downloadFolder1;
private MyDownloader.Core.UI.WaitControl waitControl1;
}
}
MyDownloader.Extension/Video/UI/NewVideoDownload.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Core;
using MyDownloader.Extension.Video;
using System.Diagnostics;
using System.IO;
using MyDownloader.Core.Common;
using MyDownloader.Core.UI;
using MyDownloader.Extension.Video.Impl;
using System.Threading;
namespace MyDownloader.Extension.Video.UI
{
public partial class NewVideoDownload : Form
{
bool hasSet = false;
VideoDownloadHandler handler;
VideoDownloadExtension extension;
Thread videoTitleReaderThread;
public NewVideoDownload()
{
InitializeComponent();
extension = (VideoDownloadExtension)AppManager.Instance.Application.GetExtensionByType(typeof(VideoDownloadExtension));
videoFormatCtrl1.Change += new EventHandler(videoFormatCtrl1_Change);
}
void videoFormatCtrl1_Change(object sender, EventArgs e)
{
UpdateFileExt();
}
private void UpdateFileExt()
{
string file = txtFilename.Text;
if (!string.IsNullOrEmpty(file))
{
if (videoFormatCtrl1.VideoFormat != VideoFormat.None)
{
file = Path.ChangeExtension(file, "." + videoFormatCtrl1.VideoFormat.ToString().ToLower());
}
else
{
file = Path.ChangeExtension(file, ".flv");
}
txtFilename.Text = file;
}
}
private void txtURL_TextChanged(object sender, EventArgs e)
{
ReleaseVideoThread();
handler = extension.GetHandlerByURL(txtURL.Text);
if (handler == null)
{
btnOK.Enabled = false;
pictureBox1.Image = null;
return;
}
btnOK.Enabled = true;
Type typeHandler = handler.Type;
DisplayLogo(typeHandler);
videoTitleReaderThread = new Thread(
delegate(object state)
{
object[] parms = (object[])state;
Type type = (Type)parms[0];
string url = (string)parms[1];
BaseVideoDownloader videoDownloader = (BaseVideoDownloader)Activator.CreateInstance(type);
string titile = videoDownloader.GetTitle(ResourceLocation.FromURL(url));
this.BeginInvoke((MethodInvoker)delegate() { txtFilename.Text = titile; UpdateFileExt(); waitControl1.Visible = false; });
}
);
waitControl1.Visible = true;
videoTitleReaderThread.Start(new object[] { typeHandler, txtURL.Text });
}
private void ReleaseVideoThread()
{
if (videoTitleReaderThread != null)
{
if (videoTitleReaderThread.IsAlive)
{
videoTitleReaderThread.Abort();
videoTitleReaderThread = null;
}
}
waitControl1.Visible = false;
}
private void DisplayLogo(Type typeHandler)
{
string logoName = typeHandler.Namespace + ".Logos." + typeHandler.Name + ".png";
using (Stream s = handler.Type.Assembly.GetManifestResourceStream(logoName))
{
pictureBox1.Image = Image.FromStream(s);
}
//Debug.WriteLine(logoName);
}
private void lblSites_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
using (SupportedVideoSitesForm sites = new SupportedVideoSitesForm())
{
sites.ShowDialog();
}
}
public ResourceLocation DownloadLocation
{
get
{
ResourceLocation rl = ResourceLocation.FromURL(txtURL.Text);
rl.ProtocolProviderType = handler.Type.AssemblyQualifiedName;
return rl;
}
set
{
hasSet = true;
if (value == null)
{
txtURL.Clear();
}
else
{
txtURL.Text = value.URL;
}
}
}
public string LocalFile
{
get
{
return PathHelper.GetWithBackslash(downloadFolder1.Folder) + txtFilename.Text;
}
}
public int Segments
{
get
{
return (int)numSegments.Value;
}
}
public bool StartNow
{
get
{
return chkStartNow.Checked;
}
}
public VideoFormat VideoFormat
{
get { return videoFormatCtrl1.VideoFormat; }
}
private void txtFilename_Leave(object sender, EventArgs e)
{
UpdateFileExt();
}
private void btnOK_Click(object sender, EventArgs e)
{
UpdateFileExt();
AddDownloadToList();
Close();
}
private void AddDownloadToList()
{
Downloader download = DownloadManager.Instance.Add(
this.DownloadLocation,
null,
this.LocalFile,
this.Segments,
false);
VideoConverter.SetConvertOption(download, this.VideoFormat);
if (this.StartNow)
{
download.Start();
}
}
private void NewVideoDownload_FormClosing(object sender, FormClosingEventArgs e)
{
ReleaseVideoThread();
}
private void NewVideoDownload_Load(object sender, EventArgs e)
{
if (!hasSet)
{
txtURL.Text = ClipboardHelper.GetURLOnClipboard();
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
Close();
}
}
}
MyDownloader.Extension/Video/UI/NewVideoDownload.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>64</value>
</metadata>
</root>
MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
namespace MyDownloader.Extension.Video.UI
{
partial class SupportedVideoSitesForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.lstSites = new System.Windows.Forms.ListBox();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(9, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(33, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Sites:";
//
// lstSites
//
this.lstSites.FormattingEnabled = true;
this.lstSites.Location = new System.Drawing.Point(12, 25);
this.lstSites.Name = "lstSites";
this.lstSites.Size = new System.Drawing.Size(272, 160);
this.lstSites.TabIndex = 1;
this.lstSites.SelectedIndexChanged += new System.EventHandler(this.lstSites_SelectedIndexChanged);
//
// pictureBox1
//
this.pictureBox1.InitialImage = null;
this.pictureBox1.Location = new System.Drawing.Point(12, 191);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(272, 72);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.pictureBox1.TabIndex = 37;
this.pictureBox1.TabStop = false;
//
// button1
//
this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button1.Location = new System.Drawing.Point(208, 269);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 2;
this.button1.Text = "Close";
this.button1.UseVisualStyleBackColor = true;
//
// SupportedVideoSitesForm
//
this.AcceptButton = this.button1;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.button1;
this.ClientSize = new System.Drawing.Size(296, 299);
this.Controls.Add(this.button1);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.lstSites);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SupportedVideoSitesForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Supported Video Sites";
this.Load += new System.EventHandler(this.SupportedVideoSitesForm_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ListBox lstSites;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button button1;
}
}
MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Extension.Video;
using System.IO;
using MyDownloader.Core.UI;
namespace MyDownloader.Extension.Video.UI
{
public partial class SupportedVideoSitesForm : Form
{
VideoDownloadExtension extension;
public SupportedVideoSitesForm()
{
InitializeComponent();
}
private void SupportedVideoSitesForm_Load(object sender, EventArgs e)
{
extension = (VideoDownloadExtension)AppManager.Instance.Application.GetExtensionByType(typeof(VideoDownloadExtension));
for (int i = 0; i < extension.Handlers.Count; i++)
{
this.lstSites.Items.Add(extension.Handlers[i]);
}
if (this.lstSites.Items.Count > 0)
{
this.lstSites.SelectedIndex = 0;
}
}
private void lstSites_SelectedIndexChanged(object sender, EventArgs e)
{
VideoDownloadHandler handler = (VideoDownloadHandler)lstSites.Items[lstSites.SelectedIndex];
Type t = handler.Type;
string logoName = t.Namespace + ".Logos." + t.Name + ".png";
using (Stream s = t.Assembly.GetManifestResourceStream(logoName))
{
pictureBox1.Image = Image.FromStream(s);
}
}
}
}
MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/Video/UI/VideoFormatCtrl.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
namespace MyDownloader.Extension.Video.UI
{
partial class VideoFormatCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.chkConvert = new System.Windows.Forms.CheckBox();
this.cboTypes = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// chkConvert
//
this.chkConvert.AutoSize = true;
this.chkConvert.Dock = System.Windows.Forms.DockStyle.Top;
this.chkConvert.Location = new System.Drawing.Point(0, 0);
this.chkConvert.Name = "chkConvert";
this.chkConvert.Size = new System.Drawing.Size(202, 17);
this.chkConvert.TabIndex = 0;
this.chkConvert.Text = "Convert when done:";
this.chkConvert.UseVisualStyleBackColor = true;
this.chkConvert.CheckedChanged += new System.EventHandler(this.chkConvert_CheckedChanged);
//
// cboTypes
//
this.cboTypes.Dock = System.Windows.Forms.DockStyle.Top;
this.cboTypes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboTypes.Items.AddRange(new object[] {
"AVI",
"MPEG",
"MP3 (Audio Only)"});
this.cboTypes.Location = new System.Drawing.Point(0, 17);
this.cboTypes.Name = "cboTypes";
this.cboTypes.Size = new System.Drawing.Size(202, 21);
this.cboTypes.TabIndex = 1;
this.cboTypes.SelectedIndexChanged += new System.EventHandler(this.cboTypes_SelectedIndexChanged);
//
// VideoFormatCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.cboTypes);
this.Controls.Add(this.chkConvert);
this.Name = "VideoFormatCtrl";
this.Size = new System.Drawing.Size(202, 52);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkConvert;
private System.Windows.Forms.ComboBox cboTypes;
}
}
MyDownloader.Extension/Video/UI/VideoFormatCtrl.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.Video.UI
{
public partial class VideoFormatCtrl : UserControl
{
public VideoFormatCtrl()
{
InitializeComponent();
UpdateUI();
cboTypes.SelectedIndex = 0;
}
public event EventHandler Change;
public VideoFormat VideoFormat
{
get
{
if (chkConvert.Checked)
{
if (cboTypes.SelectedIndex == 0) return VideoFormat.AVI;
if (cboTypes.SelectedIndex == 1) return VideoFormat.MPEG;
return VideoFormat.MP3;
}
return VideoFormat.None;
}
set
{
chkConvert.Checked = value != VideoFormat.None;
switch (value)
{
case VideoFormat.AVI:
cboTypes.SelectedIndex = 0;
break;
case VideoFormat.MPEG:
cboTypes.SelectedIndex = 1;
break;
case VideoFormat.MP3:
cboTypes.SelectedIndex = 2;
break;
}
}
}
protected virtual void OnChange()
{
if (Change != null)
{
Change(this, EventArgs.Empty);
}
}
private void chkConvert_CheckedChanged(object sender, EventArgs e)
{
UpdateUI();
OnChange();
}
private void UpdateUI()
{
cboTypes.Enabled = chkConvert.Checked;
}
private void cboTypes_SelectedIndexChanged(object sender, EventArgs e)
{
OnChange();
}
}
}
MyDownloader.Extension/Video/UI/VideoFormatCtrl.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/Video/VideoConverter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace MyDownloader.Extension.Video
{
[Serializable]
public enum VideoFormat: int
{
None,
AVI,
MPEG,
MP3
}
public static class VideoConverter
{
private const string VideoConverterFormatProperty = "VideoConverterFormatProperty";
private const string ffmpeg = "ffmpeg.exe";
private const string ToAVICmdLine = "-y -i \"{0}\" -vcodec msmpeg4v2 -acodec mp3 -sameq -ab 128 \"{1}\"";
private const string ToMPEGCmdLine = "-y -i \"{0}\" -vcodec mpeg1video -acodec mp3 -sameq -ab 64 \"{1}\"";
private const string ToMP3CmdLine = "-y -i \"{0}\" -f mp3 -vn -acodec copy \"{1}\"";
public static void Convert(string fileName, VideoFormat fmt)
{
if (fmt == VideoFormat.None) throw new ArgumentException("Invalid argmument.", "fmt");
string cmd = String.Empty;
if (fmt == VideoFormat.AVI) cmd = ToAVICmdLine;
if (fmt == VideoFormat.MPEG) cmd = ToMPEGCmdLine;
if (fmt == VideoFormat.MP3) cmd = ToMP3CmdLine;
string directory = Path.GetDirectoryName(fileName);
// the original file name ends with 'AVI', 'MPEG', 'MP3'....new we rename the file to .FLV
string flvPath = Path.Combine(directory, String.Concat(Guid.NewGuid().ToString("N"), ".flv"));
try
{
File.Move(fileName, flvPath);
string sourceFile = Path.GetFileName(flvPath);
string targetFile = Path.GetFileName(fileName);
cmd = String.Format(cmd, sourceFile, targetFile);
string toolPath = Path.GetDirectoryName(Application.ExecutablePath);
//toolPath = @"C:\Documents and Settings\guilherme.labigalini\Desktop\MyDownloader\MyDownloader\MyDownloader.App\bin\Debug\";
ProcessStartInfo psi = new ProcessStartInfo(toolPath + "\\" + ffmpeg, cmd);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.WorkingDirectory = directory;
using (Process p = Process.Start(psi))
{
p.WaitForExit();
}
}
finally
{
File.Delete(flvPath);
}
}
public static void ConvertIfNecessary(Downloader d)
{
VideoFormat fmt = GetConvertOption(d);
if (fmt == VideoFormat.None)
{
return;
}
try
{
d.StatusMessage = "converting video";
Convert(d.LocalFile, fmt);
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
d.LastError = new Exception("error converting video: " + ex.Message, ex);
}
finally
{
d.StatusMessage = null;
}
}
public static VideoFormat GetConvertOption(Downloader d)
{
if (! d.ExtendedProperties.ContainsKey(VideoConverterFormatProperty))
{
return VideoFormat.None;
}
object objFmt = d.ExtendedProperties[VideoConverterFormatProperty];
if (objFmt == null)
{
return VideoFormat.None;
}
return (VideoFormat)objFmt;
}
public static void SetConvertOption(Downloader d, VideoFormat format)
{
if (format == VideoFormat.None)
{
if (d.ExtendedProperties.ContainsKey(VideoConverterFormatProperty))
{
d.ExtendedProperties.Remove(VideoConverterFormatProperty);
}
}
d.ExtendedProperties[VideoConverterFormatProperty] = format;
}
}
}
MyDownloader.Extension/Video/VideoDownloadExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
using MyDownloader.Extension.Video.Impl;
using System.Windows.Forms;
namespace MyDownloader.Extension.Video
{
public class VideoDownloadExtension: IExtension
{
List<VideoDownloadHandler> handlers;
#region IExtension Members
public string Name
{
get { return "Video Downloader"; }
}
public IUIExtension UIExtension
{
get { return new VideoDownloadUIExtension(); }
}
#endregion
#region Methods
public VideoDownloadHandler GetHandlerByURL(string url)
{
for (int i = 0; i < handlers.Count; i++)
{
if (handlers[i].Matchs(url))
{
return handlers[i];
}
}
return null;
}
#endregion
public List<VideoDownloadHandler> Handlers
{
get
{
return handlers;
}
}
public VideoDownloadExtension()
{
handlers = new List<VideoDownloadHandler>();
handlers.Add(new VideoDownloadHandler(YouTubeDownloader.SiteName, YouTubeDownloader.UrlPattern, typeof(YouTubeDownloader)));
handlers.Add(new VideoDownloadHandler(GoogleVideoDownloader.SiteName, GoogleVideoDownloader.UrlPattern, typeof(GoogleVideoDownloader)));
handlers.Add(new VideoDownloadHandler(PutfileVideoDownloader.SiteName, PutfileVideoDownloader.UrlPattern, typeof(PutfileVideoDownloader)));
handlers.Add(new VideoDownloadHandler(MetaCafeVideoDownloader.SiteName, MetaCafeVideoDownloader.UrlPattern, typeof(MetaCafeVideoDownloader)));
handlers.Add(new VideoDownloadHandler(BreakVideoDownloader.SiteName, BreakVideoDownloader.UrlPattern, typeof(BreakVideoDownloader)));
//ProtocolProviderFactory.ResolvingProtocolProvider += new EventHandler<ResolvingProtocolProviderEventArgs>(resolvingProtocolProviderEvent);
}
}
}
MyDownloader.Extension/Video/VideoDownloadHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using MyDownloader.Core;
namespace MyDownloader.Extension.Video
{
public class VideoDownloadHandler
{
#region Fields
private string urlRegExpr;
private string name;
private Type type;
private Regex reg;
#endregion
#region Constructor
public VideoDownloadHandler(string name, string regExp, Type type)
{
this.Name = name;
this.UrlRegExpr = regExp;
this.Type = type;
RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline)
| RegexOptions.IgnoreCase);
reg = new Regex(this.UrlRegExpr, options);
}
#endregion
#region Properties
public string Name
{
get { return name; }
set { name = value; }
}
public string UrlRegExpr
{
get { return urlRegExpr; }
set { urlRegExpr = value; }
}
public Type Type
{
get { return type; }
set { type = value; }
}
#endregion
#region Methods
public bool Matchs(string url)
{
return reg.IsMatch(url);
}
public override string ToString()
{
return this.Name;
}
#endregion
}
}
MyDownloader.Extension/Video/VideoDownloadUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using MyDownloader.Core;
namespace MyDownloader.Extension.Video
{
public class VideoDownloadUIExtension: IUIExtension
{
#region IUIExtension Members
public System.Windows.Forms.Control[] CreateSettingsView()
{
return null;
}
public void PersistSettings(System.Windows.Forms.Control[] settingsView)
{
}
#endregion
public void ShowNewVideoDialog(string url, bool modal)
{
if (modal)
{
using (UI.NewVideoDownload videoDownload = new UI.NewVideoDownload())
{
if (!String.IsNullOrEmpty(url))
{
videoDownload.DownloadLocation = ResourceLocation.FromURL(url);
}
videoDownload.ShowDialog();
}
}
else
{
UI.NewVideoDownload videoDownload = new UI.NewVideoDownload();
if (!String.IsNullOrEmpty(url))
{
videoDownload.DownloadLocation = ResourceLocation.FromURL(url);
}
videoDownload.ShowInTaskbar = true;
videoDownload.MinimizeBox = true;
videoDownload.Show();
videoDownload.Focus();
videoDownload.TopMost = true;
}
}
}
}
MyDownloader.Extension/WindowsIntegration/ClipboardMonitor/ClipboardMonitor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using MyDownloader.Core;
using MyDownloader.Core.UI;
using System.Security.Permissions;
using System.ComponentModel;
//http://radsoftware.com.au/articles/clipboardmonitor.aspx
namespace MyDownloader.Extension.WindowsIntegration.ClipboardMonitor
{
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public class ClipboardMonitor : IDisposable
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern bool ChangeClipboardChain(
IntPtr hWndRemove, // handle to window to remove
IntPtr hWndNewNext // handle to next window
);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
private const int WM_DRAWCLIPBOARD = 0x0308;
private const int WM_CHANGECBCHAIN = 0x030D;
private IntPtr handle;
private IntPtr clipboardViewerNext;
private IClipboardDataHandler dataHandler;
private bool enabled;
#region Methods
public bool FilterMessage(ref Message m)
{
if (!enabled)
{
return false;
}
switch (m.Msg)
{
//
// The WM_DRAWCLIPBOARD message is sent to the first window
// in the clipboard viewer chain when the content of the
// clipboard changes. This enables a clipboard viewer
// window to display the new content of the clipboard.
//
case WM_DRAWCLIPBOARD:
Debug.WriteLine("WindowProc DRAWCLIPBOARD: " + m.Msg, "WndProc");
if (dataHandler != null)
{
try
{
IDataObject iData = Clipboard.GetDataObject();
dataHandler.HandleClipboardData(iData);
}
catch
{
}
}
//
// Each window that receives the WM_DRAWCLIPBOARD message
// must call the SendMessage function to pass the message
// on to the next window in the clipboard viewer chain.
//
SendMessage(clipboardViewerNext, m.Msg, m.WParam, m.LParam);
return true;
//
// The WM_CHANGECBCHAIN message is sent to the first window
// in the clipboard viewer chain when a window is being
// removed from the chain.
//
case WM_CHANGECBCHAIN:
Debug.WriteLine("WM_CHANGECBCHAIN: lParam: " + m.LParam, "WndProc");
// When a clipboard viewer window receives the WM_CHANGECBCHAIN message,
// it should call the SendMessage function to pass the message to the
// next window in the chain, unless the next window is the window
// being removed. In this case, the clipboard viewer should save
// the handle specified by the lParam parameter as the next window in the chain.
//
// wParam is the Handle to the window being removed from
// the clipboard viewer chain
// lParam is the Handle to the next window in the chain
// following the window being removed.
if (m.WParam == clipboardViewerNext)
{
//
// If wParam is the next clipboard viewer then it
// is being removed so update pointer to the next
// window in the clipboard chain
//
clipboardViewerNext = m.LParam;
}
else
{
SendMessage(clipboardViewerNext, m.Msg, m.WParam, m.LParam);
}
return true;
default:
return false;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
ChangeClipboardChain(handle, clipboardViewerNext);
handle = IntPtr.Zero;
clipboardViewerNext = IntPtr.Zero;
dataHandler = null;
}
#endregion
#region Properties
public bool Enabled
{
get
{
return enabled;
}
set
{
Settings.Default.MonitorClipboard = value;
Settings.Default.Save();
}
}
#endregion
public ClipboardMonitor(IClipboardDataHandler handler, IntPtr winHandle)
{
enabled = Settings.Default.MonitorClipboard;
Settings.Default.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
{
enabled = Settings.Default.MonitorClipboard;
};
handle = winHandle;
clipboardViewerNext = SetClipboardViewer(handle);
this.dataHandler = handler;
}
}
}
MyDownloader.Extension/WindowsIntegration/ClipboardMonitor/IClipboardDataHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.WindowsIntegration.ClipboardMonitor
{
public interface IClipboardDataHandler
{
void HandleClipboardData(IDataObject data);
}
}
MyDownloader.Extension/WindowsIntegration/Settings.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyDownloader.Extension.WindowsIntegration {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool MonitorClipboard {
get {
return ((bool)(this["MonitorClipboard"]));
}
set {
this["MonitorClipboard"] = value;
}
}
}
}
MyDownloader.Extension/WindowsIntegration/Settings.settings
1
2
3
4
5
6
7
8
9
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MyDownloader.Extension.WindowsIntegration" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="MonitorClipboard" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>
MyDownloader.Extension/WindowsIntegration/WindowsIntegrationExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
namespace MyDownloader.Extension.WindowsIntegration
{
public class WindowsIntegrationExtension: IExtension
{
#region IExtension Members
public string Name
{
get { return ("Windows Integration"); }
}
public IUIExtension UIExtension
{
get { return new WindowsIntegrationUIExtension(); }
}
#endregion
}
}
MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
namespace MyDownloader.Extension.WindowsIntegration
{
partial class WindowsIntegrationUI
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.chkStartWithWindows = new System.Windows.Forms.CheckBox();
this.chkMonitorWindowsClipboard = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// chkStartWithWindows
//
this.chkStartWithWindows.AutoSize = true;
this.chkStartWithWindows.Location = new System.Drawing.Point(0, 0);
this.chkStartWithWindows.Name = "chkStartWithWindows";
this.chkStartWithWindows.Size = new System.Drawing.Size(191, 17);
this.chkStartWithWindows.TabIndex = 0;
this.chkStartWithWindows.Text = "Start MyDownloader with Windows";
this.chkStartWithWindows.UseVisualStyleBackColor = true;
//
// chkMonitorWindowsClipboard
//
this.chkMonitorWindowsClipboard.AutoSize = true;
this.chkMonitorWindowsClipboard.Location = new System.Drawing.Point(0, 16);
this.chkMonitorWindowsClipboard.Name = "chkMonitorWindowsClipboard";
this.chkMonitorWindowsClipboard.Size = new System.Drawing.Size(155, 17);
this.chkMonitorWindowsClipboard.TabIndex = 1;
this.chkMonitorWindowsClipboard.Text = "Monitor Windows Clipboard";
this.chkMonitorWindowsClipboard.UseVisualStyleBackColor = true;
//
// WindowsIntegrationUI
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.chkMonitorWindowsClipboard);
this.Controls.Add(this.chkStartWithWindows);
this.Name = "WindowsIntegrationUI";
this.Size = new System.Drawing.Size(429, 111);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox chkStartWithWindows;
private System.Windows.Forms.CheckBox chkMonitorWindowsClipboard;
}
}
MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MyDownloader.Extension.WindowsIntegration
{
public partial class WindowsIntegrationUI : UserControl
{
public WindowsIntegrationUI()
{
InitializeComponent();
this.Text = "Windows Integration";
chkStartWithWindows.Checked = WindowsStartupUtility.IsRegistered();
chkMonitorWindowsClipboard.Checked = Settings.Default.MonitorClipboard;
}
public bool MonitorClipboard
{
get
{
return chkMonitorWindowsClipboard.Checked;
}
}
public bool StartWithWindows
{
get
{
return chkStartWithWindows.Checked;
}
}
}
}
MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUIExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core.Extensions;
namespace MyDownloader.Extension.WindowsIntegration
{
public class WindowsIntegrationUIExtension : IUIExtension
{
#region IUIExtension Members
public System.Windows.Forms.Control[] CreateSettingsView()
{
return new System.Windows.Forms.Control[] { new WindowsIntegrationUI() };
}
public void PersistSettings(System.Windows.Forms.Control[] settingsView)
{
WindowsIntegrationUI windowsIntegration = (WindowsIntegrationUI)settingsView[0];
Settings.Default.MonitorClipboard = windowsIntegration.MonitorClipboard;
Settings.Default.Save();
WindowsStartupUtility.Register(windowsIntegration.StartWithWindows);
}
#endregion
}
}
MyDownloader.Extension/WindowsIntegration/WindowsStartupUtility.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Windows.Forms;
using System.IO;
using System.Security.Permissions;
using System.Security.AccessControl;
namespace MyDownloader.Extension.WindowsIntegration
{
[RegistryPermission(SecurityAction.LinkDemand,
Read = "Software\\Microsoft\\Windows\\CurrentVersion\\Run",
Write = "Software\\Microsoft\\Windows\\CurrentVersion\\Run")]
internal class WindowsStartupUtility
{
private static string GetKeyName()
{
return Path.GetFileNameWithoutExtension(Application.ExecutablePath);
}
private static string GetKeyValue()
{
return String.Format("\"{0}\" /as", Application.ExecutablePath);
}
private static RegistryKey GetRegistryKey()
{
// Create a security context for a new key that we will use to store our data.
// The security context will restrict access to only our user.
string user = Environment.UserDomainName + "\\" + Environment.UserName;
RegistrySecurity security = new RegistrySecurity();
RegistryAccessRule rule = new RegistryAccessRule(user,
RegistryRights.FullControl,
InheritanceFlags.ContainerInherit,
PropagationFlags.None,
AccessControlType.Allow);
security.AddAccessRule(rule);
RegistryKey key = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run",
RegistryKeyPermissionCheck.ReadWriteSubTree, security);
return key;
}
public static bool IsRegistered()
{
using (RegistryKey key = GetRegistryKey())
{
string value = key.GetValue(GetKeyName(), null) as string;
return value != null && value.Equals(GetKeyValue(), StringComparison.OrdinalIgnoreCase);
}
}
public static void Register(bool register)
{
using (RegistryKey key = GetRegistryKey())
{
if (register)
{
key.SetValue(GetKeyName(), GetKeyValue(), RegistryValueKind.String);
}
else
{
key.DeleteValue(GetKeyName(), false);
}
}
}
}
}
MyDownloader.Extension/Zip/NoCloseSubStream.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.Extension.Zip
{
/// <summary>
/// Stream without
/// </summary>
internal class NoCloseSubStream : Stream
{
Stream baseStream;
public NoCloseSubStream(Stream b)
{
baseStream = b;
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override bool CanRead
{
get
{
return baseStream.CanRead;
}
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override bool CanSeek
{
get
{
return baseStream.CanSeek;
}
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override bool CanWrite
{
get
{
return baseStream.CanWrite;
}
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override long Length
{
get
{
return baseStream.Length;
}
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override long Position
{
get
{
return baseStream.Position;
}
set
{
baseStream.Position = value;
}
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override long Seek(long offset, SeekOrigin origin)
{
return baseStream.Seek(offset, origin);
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override void SetLength(long val)
{
baseStream.SetLength(val);
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override int ReadByte()
{
return baseStream.ReadByte();
}
/// <summary>
/// I needed to implement the abstract member.
/// </summary>
public override int Read(byte[] b, int off, int len)
{
return baseStream.Read(b, off, len);
}
public override void Write(byte[] buf, int off, int len)
{
baseStream.Write(buf, off, len);
}
public override void WriteByte(byte bv)
{
baseStream.WriteByte(bv);
}
public override void Close()
{
baseStream = null;
}
public override void Flush()
{
baseStream.Flush();
}
}
}
MyDownloader.Extension/Zip/PartialInputStream.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
namespace MyDownloader.Extension.Zip
{
internal class PartialInputStream : InflaterInputStream
{
Stream baseStream;
long filepos;
long end;
public PartialInputStream(Stream baseStream, long len)
: base(baseStream)
{
this.baseStream = baseStream;
filepos = 0;
end = len;
}
public override int Available
{
get
{
long amount = end - filepos;
if (amount > Int32.MaxValue)
{
return Int32.MaxValue;
}
return (int)amount;
}
}
public override int ReadByte()
{
if (filepos == end)
{
return -1;
}
lock (baseStream)
{
filepos++;
return baseStream.ReadByte();
}
}
public override int Read(byte[] b, int off, int len)
{
if (len > end - filepos)
{
len = (int)(end - filepos);
if (len == 0)
{
return 0;
}
}
lock (baseStream)
{
int count = StreamHelper.ReadAll(b, off, len, baseStream);
if (count > 0)
{
filepos += len;
}
return count;
}
}
public long SkipBytes(long amount)
{
if (amount < 0)
{
throw new ArgumentOutOfRangeException();
}
if (amount > end - filepos)
{
amount = end - filepos;
}
filepos += amount;
for (int i = 0; i < amount; i++)
baseStream.ReadByte();
return amount;
}
public override void Close()
{
baseStream.Close();
}
}
}
MyDownloader.Extension/Zip/StreamHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.Extension.Zip
{
internal static class StreamHelper
{
internal static int ReadAll(byte[] bb, int p, int sst, Stream s)
{
int ss = 0;
while (ss < sst)
{
int r = s.Read(bb, p, sst - ss);
if (r <= 0)
return ss;
ss += r;
p += r;
}
return ss;
}
}
}
MyDownloader.Extension/Zip/ZipOutputStream.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.BZip2;
namespace MyDownloader.Extension.Zip
{
/// <summary>
/// This is a FilterOutputStream that writes the files into a zip
/// archive one after another. It has a special method to start a new
/// zip entry. The zip entries contains information about the file name
/// size, compressed size, CRC, etc.
///
/// It includes support for STORED and DEFLATED and BZIP2 entries.
/// This class is not thread safe.
///
/// author of the original java version : Jochen Hoenicke
/// </summary>
/// <example> This sample shows how to create a zip file
/// <code>
/// using System;
/// using System.IO;
///
/// using NZlib.Zip;
///
/// class MainClass
/// {
/// public static void Main(string[] args)
/// {
/// string[] filenames = Directory.GetFiles(args[0]);
///
/// ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
///
/// s.SetLevel(5); // 0 - store only to 9 - means best compression
///
/// foreach (string file in filenames) {
/// FileStream fs = File.OpenRead(file);
///
/// byte[] buffer = new byte[fs.Length];
/// fs.Read(buffer, 0, buffer.Length);
///
/// ZipEntry entry = new ZipEntry(file);
///
/// s.PutNextEntry(entry);
///
/// s.Write(buffer, 0, buffer.Length);
///
/// }
///
/// s.Finish();
/// s.Close();
/// }
/// }
/// </code>
/// </example>
internal class ZipOutputStream : DeflaterOutputStream
{
private ArrayList entries = new ArrayList();
private Crc32 crc = new Crc32();
private ZipEntry curEntry = null;
private long startPosition = 0;
private Stream additionalStream = null;
private CompressionMethod curMethod;
private int size;
private int offset = 0;
private byte[] zipComment = new byte[0];
private int defaultMethod = DEFLATED;
/// <summary>
/// Our Zip version is hard coded to 1.0 resp. 2.0
/// </summary>
private const int ZIP_STORED_VERSION = 10;
private const int ZIP_DEFLATED_VERSION = 20;
/// <summary>
/// Compression method. This method doesn't compress at all.
/// </summary>
public const int STORED = 0;
/// <summary>
/// Compression method. This method uses the Deflater.
/// </summary>
public const int DEFLATED = 8;
public const int BZIP2 = 12;
/// <summary>
/// Creates a new Zip output stream, writing a zip archive.
/// </summary>
/// <param name="baseOutputStream">
/// the output stream to which the zip archive is written.
/// </param>
public ZipOutputStream(Stream baseOutputStream)
: base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true))
{
}
/// <summary>
/// Set the zip file comment.
/// </summary>
/// <param name="comment">
/// the comment.
/// </param>
/// <exception name ="ArgumentException">
/// if UTF8 encoding of comment is longer than 0xffff bytes.
/// </exception>
public void SetComment(string comment)
{
byte[] commentBytes = ZipConstants.ConvertToArray(comment);
if (commentBytes.Length > 0xffff)
{
throw new ArgumentException("Comment too long.");
}
zipComment = commentBytes;
}
/// <summary>
/// Sets default compression method. If the Zip entry specifies
/// another method its method takes precedence.
/// </summary>
/// <param name = "method">
/// the method.
/// </param>
/// <exception name = "ArgumentException">
/// if method is not supported.
/// </exception>
public void SetMethod(int method)
{
if (method != STORED && method != DEFLATED && method != BZIP2)
{
throw new ArgumentException("Method not supported.");
}
defaultMethod = method;
}
/// <summary>
/// Sets default compression level. The new level will be activated
/// immediately.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if level is not supported.
/// </exception>
/// <see cref="Deflater"/>
public void SetLevel(int level)
{
deflater_.SetLevel(level);
}
/// <summary>
/// Write an unsigned short in little endian byte order.
/// </summary>
private void WriteLeShort(int value)
{
baseOutputStream_.WriteByte((byte)value);
baseOutputStream_.WriteByte((byte)(value >> 8));
}
/// <summary>
/// Write an int in little endian byte order.
/// </summary>
private void WriteLeInt(int value)
{
WriteLeShort(value);
WriteLeShort(value >> 16);
}
/// <summary>
/// Write an int in little endian byte order.
/// </summary>
private void WriteLeLong(long value)
{
WriteLeInt((int)value);
WriteLeInt((int)(value >> 32));
}
bool shouldWriteBack = false;
long seekPos = -1;
/// <summary>
/// Starts a new Zip entry. It automatically closes the previous
/// entry if present. If the compression method is stored, the entry
/// must have a valid size and crc, otherwise all elements (except
/// name) are optional, but must be correct if present. If the time
/// is not set in the entry, the current time is used.
/// </summary>
/// <param name="entry">
/// the entry.
/// </param>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// if stream was finished
/// </exception>
public void PutNextEntry(ZipEntry entry)
{
if (entries == null)
{
throw new InvalidOperationException("ZipOutputStream was finished");
}
if (curEntry != null)
{
CloseEntry();
}
CompressionMethod method = entry.CompressionMethod;
int flags = 0;
switch (method)
{
case CompressionMethod.Stored:
if (entry.CompressedSize >= 0)
{
if (entry.Size < 0)
{
entry.Size = entry.CompressedSize;
}
else if (entry.Size != entry.CompressedSize)
{
throw new ZipException("Method STORED, but compressed size != size");
}
}
else
{
entry.CompressedSize = entry.Size;
}
if (entry.Size < 0)
{
throw new ZipException("Method STORED, but size not set");
}
else if (entry.Crc < 0)
{
throw new ZipException("Method STORED, but crc not set");
}
break;
case (CompressionMethod)12:
startPosition = baseOutputStream_.Position;
additionalStream = new BZip2OutputStream(new NoCloseSubStream(baseOutputStream_));
if (entry.CompressedSize < 0 || entry.Size < 0 || entry.Crc < 0)
{
flags |= 8;
}
break;
case CompressionMethod.Deflated:
if (entry.CompressedSize < 0 || entry.Size < 0 || entry.Crc < 0)
{
flags |= 8;
}
break;
}
//if (entry.DosTime < 0) {
//entry.Time = System.Environment.TickCount;
//}
entry.Flags = flags;
entry.Offset = offset;
entry.CompressionMethod = (CompressionMethod)method;
curMethod = method;
// Write the local file header
WriteLeInt(ZipConstants.LocalHeaderSignature);
// write ZIP version
WriteLeShort(method == CompressionMethod.Stored ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
if ((flags & 8) == 0)
{
WriteLeShort(flags);
WriteLeShort((byte)method);
WriteLeInt((int)entry.DosTime);
WriteLeInt((int)entry.Crc);
WriteLeInt((int)entry.CompressedSize);
WriteLeInt((int)entry.Size);
}
else
{
if (baseOutputStream_.CanSeek)
{
shouldWriteBack = true;
WriteLeShort((short)(flags & ~8));
}
else
{
shouldWriteBack = false;
WriteLeShort(flags);
}
WriteLeShort((byte)method);
WriteLeInt((int)entry.DosTime);
seekPos = baseOutputStream_.Position;
WriteLeInt(0);
WriteLeInt(0);
WriteLeInt(0);
}
byte[] name = ZipConstants.ConvertToArray(entry.Name);
if (name.Length > 0xFFFF)
{
throw new ZipException("Name too long.");
}
byte[] extra = entry.ExtraData;
if (extra == null)
{
extra = new byte[0];
}
if (extra.Length > 0xFFFF)
{
throw new ZipException("Extra data too long.");
}
WriteLeShort(name.Length);
WriteLeShort(extra.Length);
baseOutputStream_.Write(name, 0, name.Length);
baseOutputStream_.Write(extra, 0, extra.Length);
offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length;
/* Activate the entry. */
curEntry = entry;
crc.Reset();
if (method == CompressionMethod.Deflated)
{
deflater_.Reset();
}
size = 0;
}
/// <summary>
/// Closes the current entry.
/// </summary>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// if no entry is active.
/// </exception>
public void CloseEntry()
{
if (curEntry == null)
{
throw new InvalidOperationException("No open entry");
}
/* First finish the deflater, if appropriate */
int csize = 0;
if (curMethod == CompressionMethod.Deflated)
{
base.Finish();
csize = (int)deflater_.TotalOut;
}
else if (curMethod == (CompressionMethod)12)
{
// close the sub stream, no problem because the substream has a fake
// close
additionalStream.Close();
additionalStream = null;
csize = (int)(baseOutputStream_.Position - startPosition);
}
else
csize = size;
if (curEntry.Size < 0)
{
curEntry.Size = size;
}
else if (curEntry.Size != size)
{
throw new ZipException("size was " + size + ", but I expected " + curEntry.Size);
}
if (curEntry.CompressedSize < 0)
{
curEntry.CompressedSize = csize;
}
else if (curEntry.CompressedSize != csize)
{
throw new ZipException("compressed size was " + csize + ", but I expected " + curEntry.CompressedSize);
}
if (curEntry.Crc < 0)
{
curEntry.Crc = crc.Value;
}
else if (curEntry.Crc != crc.Value)
{
throw new ZipException("crc was " + crc.Value +
", but I expected " +
curEntry.Crc);
}
offset += csize;
/* Now write the data descriptor entry if needed. */
if (curMethod != CompressionMethod.Stored && (curEntry.Flags & 8) != 0)
{
if (shouldWriteBack)
{
curEntry.Flags &= ~8;
long curPos = baseOutputStream_.Position;
baseOutputStream_.Seek(seekPos, SeekOrigin.Begin);
WriteLeInt((int)curEntry.Crc);
WriteLeInt((int)curEntry.CompressedSize);
WriteLeInt((int)curEntry.Size);
baseOutputStream_.Seek(curPos, SeekOrigin.Begin);
shouldWriteBack = false;
}
else
{
WriteLeInt(ZipConstants.DataDescriptorSignature);
WriteLeInt((int)curEntry.Crc);
WriteLeInt((int)curEntry.CompressedSize);
WriteLeInt((int)curEntry.Size);
offset += ZipConstants.DataDescriptorSize;
}
}
entries.Add(curEntry);
curEntry = null;
}
/// <summary>
/// Writes the given buffer to the current entry.
/// </summary>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// if no entry is active.
/// </exception>
public override void Write(byte[] b, int off, int len)
{
if (curEntry == null)
{
throw new InvalidOperationException("No open entry.");
}
switch (curMethod)
{
case (CompressionMethod)12:
additionalStream.Write(b, off, len);
break;
case CompressionMethod.Deflated:
base.Write(b, off, len);
break;
case CompressionMethod.Stored:
baseOutputStream_.Write(b, off, len);
break;
}
crc.Update(b, off, len);
size += len;
}
/// <summary>
/// Finishes the stream. This will write the central directory at the
/// end of the zip file and flush the stream.
/// </summary>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
public override void Finish()
{
if (entries == null)
{
return;
}
if (curEntry != null)
{
CloseEntry();
}
int numEntries = 0;
int sizeEntries = 0;
foreach (ZipEntry entry in entries)
{
// TODO : check the appnote file for compilance with the central directory standard
CompressionMethod method = entry.CompressionMethod;
WriteLeInt(ZipConstants.CentralHeaderSignature);
WriteLeShort(method == CompressionMethod.Stored ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
WriteLeShort(method == CompressionMethod.Stored ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
if (entry.IsCrypted)
{
entry.Flags |= 1;
}
WriteLeShort(entry.Flags);
WriteLeShort((short)method);
WriteLeInt((int)entry.DosTime);
WriteLeInt((int)entry.Crc);
WriteLeInt((int)entry.CompressedSize);
WriteLeInt((int)entry.Size);
byte[] name = ZipConstants.ConvertToArray(entry.Name);
if (name.Length > 0xffff)
{
throw new ZipException("Name too long.");
}
byte[] extra = entry.ExtraData;
if (extra == null)
{
extra = new byte[0];
}
string strComment = entry.Comment;
byte[] comment = strComment != null ? ZipConstants.ConvertToArray(strComment) : new byte[0];
if (comment.Length > 0xffff)
{
throw new ZipException("Comment too long.");
}
WriteLeShort(name.Length);
WriteLeShort(extra.Length);
WriteLeShort(comment.Length);
WriteLeShort(0); // disk number
WriteLeShort(0); // internal file attr
WriteLeInt(0); // external file attr
WriteLeInt((int)entry.Offset);
baseOutputStream_.Write(name, 0, name.Length);
baseOutputStream_.Write(extra, 0, extra.Length);
baseOutputStream_.Write(comment, 0, comment.Length);
++numEntries;
sizeEntries += ZipConstants.CentralHeaderBaseSize + name.Length + extra.Length + comment.Length;
}
WriteLeInt(ZipConstants.EndOfCentralDirectorySignature);
WriteLeShort(0); // disk number
WriteLeShort(0); // disk with start of central dir
WriteLeShort(numEntries);
WriteLeShort(numEntries);
WriteLeInt(sizeEntries);
WriteLeInt(offset);
WriteLeShort(zipComment.Length);
baseOutputStream_.Write(zipComment, 0, zipComment.Length);
baseOutputStream_.Flush();
entries = null;
}
}
}
MyDownloader.Extension/Zip/ZipProtocolProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
namespace MyDownloader.Extension.Zip
{
public class ZipProtocolProvider: IProtocolProvider
{
private const string ZipEntryNameProperty = "ZipEntryNameProperty";
#region Helper Methods
public static void SetZipEntryNameProperty(Downloader downloader, string entryName)
{
downloader.ExtendedProperties[ZipEntryNameProperty] = entryName;
}
public static string GetZipEntryNameProperty(Downloader downloader)
{
return downloader.ExtendedProperties[ZipEntryNameProperty] as string;
}
#endregion
private Downloader downloader;
private ZipRemoteFile remoteZipFile;
private ZipEntry entry;
#region IProtocolProvider Members
public void Initialize(Downloader downloader)
{
this.downloader = downloader;
}
public Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition)
{
/*
* a chamada desse metodo nao sera apos o GetFileInfo se o download for resumeable
* sendo assim, preciso ter algum repositorio comum para guardas os "remoteZipFile"
* assim evita-se de ficar carregando as entries a cada segmento/arquivo.
*
* nenhum outro download vinculado a este "remoteZipFile"
*/
return remoteZipFile.GetInputStream(entry);
}
public RemoteFileInfo GetFileInfo(ResourceLocation rl, out System.IO.Stream stream)
{
stream = null;
remoteZipFile = new ZipRemoteFile(rl);
remoteZipFile.Load();
string entryName = GetZipEntryNameProperty(this.downloader);
entry = remoteZipFile[entryName];
RemoteFileInfo result = new RemoteFileInfo();
result.AcceptRanges = false; // TODO make resumeable
result.FileSize = entry.Size;
result.LastModified = entry.DateTime;
result.MimeType = "application/zip";
return result;
}
#endregion
}
}
MyDownloader.Extension/Zip/ZipRemoteFile.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
// RemoteZipFile.cs
// Copyright (C) 2003 Emanuele Ruffaldi
//
// ZipEntry parsing code taken from ZipFile.cs in SharpLibZip
// Copyright (C) 2001 Mike Krueger
//
// The original SharpLibZip code was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.
using System;
using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.BZip2;
using System.Collections;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.Checksums;
using MyDownloader.Core;
namespace MyDownloader.Extension.Zip
{
public class ZipRemoteFile : IEnumerable
{
private ZipEntry[] entries;
private ResourceLocation url;
private int MaxFileOffset;
private IProtocolProvider protocolProvider;
public ZipRemoteFile(ResourceLocation url) :
this(url, ProtocolProviderFactory.GetProvider(url.URL))
{
}
public ZipRemoteFile(ResourceLocation url, IProtocolProvider protocolProvider)
{
if (protocolProvider == null)
{
throw new ArgumentNullException("protocolProvider");
}
this.url = url;
this.protocolProvider = protocolProvider;
}
/*
end of central dir signature 4 bytes (0x06054b50)
number of this disk 2 bytes
number of the disk with the start of the central directory 2 bytes
total number of entries in the central directory on this disk 2 bytes
total number of entries in the central directory 2 bytes
size of the central directory 4 bytes
offset of start of central directory
with respect to the starting disk number 4 bytes
.ZIP file comment length 2 bytes
.ZIP file comment (variable size)
*/
/// <summary>
/// TODO: case when the whole file is smaller than 64K
/// TODO: handle non HTTP case
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public bool Load()
{
int CentralOffset, CentralSize;
int TotalEntries;
if(!FindCentralDirectory(out CentralOffset, out CentralSize, out TotalEntries))
return false;
MaxFileOffset = CentralOffset;
// now retrieve the Central Directory
entries = new ZipEntry[TotalEntries];
//HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
//req.AddRange(CentralOffset, CentralOffset+CentralSize);
//HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (Stream s = protocolProvider.CreateStream(this.url,
CentralOffset, CentralOffset + CentralSize))
{
// code taken from SharpZipLib with modification for not seekable stream
// and adjustement for Central Directory entry
for (int i = 0; i < TotalEntries; i++)
{
if (ReadLeInt(s) != ZipConstants.CentralHeaderSignature)
{
throw new ZipException("Wrong Central Directory signature");
}
// skip 6 bytes: version made (W), version ext (W), flags (W)
ReadLeInt(s);
ReadLeShort(s);
int method = ReadLeShort(s);
int dostime = ReadLeInt(s);
int crc = ReadLeInt(s);
int csize = ReadLeInt(s);
int size = ReadLeInt(s);
int nameLen = ReadLeShort(s);
int extraLen = ReadLeShort(s);
int commentLen = ReadLeShort(s);
// skip 8 bytes: disk number start, internal file attribs, external file attribs (DW)
ReadLeInt(s);
ReadLeInt(s);
int offset = ReadLeInt(s);
byte[] buffer = new byte[Math.Max(nameLen, commentLen)];
StreamHelper.ReadAll(buffer, 0, nameLen, s);
string name = ZipConstants.ConvertToString(buffer);
ZipEntry entry = new ZipEntry(name);
entry.CompressionMethod = (CompressionMethod)method;
entry.Crc = crc & 0xffffffffL;
entry.Size = size & 0xffffffffL;
entry.CompressedSize = csize & 0xffffffffL;
entry.DosTime = (uint)dostime;
if (extraLen > 0)
{
byte[] extra = new byte[extraLen];
StreamHelper.ReadAll(extra, 0, extraLen, s);
entry.ExtraData = extra;
}
if (commentLen > 0)
{
StreamHelper.ReadAll(buffer, 0, commentLen, s);
entry.Comment = ZipConstants.ConvertToString(buffer);
}
entry.ZipFileIndex = i;
entry.Offset = offset;
entries[i] = entry;
OnProgress((i*100)/TotalEntries);
}
}
OnProgress(100);
return true;
}
/// <summary>
/// OnProgress during Central Header loading
/// </summary>
/// <param name="pct"></param>
public virtual void OnProgress(int pct)
{
}
/// <summary>
/// Checks if there is a local header at the current position in the stream and skips it
/// </summary>
/// <param name="baseStream"></param>
/// <param name="entry"></param>
void SkipLocalHeader(Stream baseStream, ZipEntry entry)
{
lock(baseStream)
{
if (ReadLeInt(baseStream) != ZipConstants.LocalHeaderSignature)
{
throw new ZipException("Wrong Local header signature");
}
Skip(baseStream, 10+12);
int namelen = ReadLeShort(baseStream);
int extralen = ReadLeShort(baseStream);
Skip(baseStream, namelen+extralen);
}
}
/// <summary>
/// Finds the Central Header in the Zip file. We can minimize the number of requests and
/// the bytes taken
///
/// Actually we do: 256, 1024, 65536
/// </summary>
/// <param name="baseurl"></param>
/// <returns></returns>
bool FindCentralDirectory(out int Offset, out int Size, out int Entries)
{
int currentLength = 256;
Entries = 0;
Size = 0;
Offset = -1;
while(true)
{
//HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
//req.AddRange(-(currentLength+22));
//HttpWebResponse res = (HttpWebResponse)req.GetResponse();
// bb = new byte[res.ContentLength];
// endSize = StreamHelper.ReadAll(bb, 0, (int)res.ContentLength, res.getResponseStream());
int endSize;
byte[] bb;
using (BinaryReader headerStream = new BinaryReader(protocolProvider.CreateStream(
this.url, -(currentLength + 22), 0)))
{
using (MemoryStream data = new MemoryStream())
{
int count = 256;
byte[] buffer = new byte[count];
do
{
int readCount = headerStream.Read(buffer, 0, count);
if (readCount == 0)
{
break;
}
data.Write(buffer, 0, readCount);
}
while (count > 0);
bb = data.ToArray();
endSize = (int)data.Length;
}
}
// scan for the central block. The position of the central block
// is end-comment-22
//<
// 50 4B 05 06
int pos = endSize-22;
//int state = 0;
while(pos >= 0)
{
if(bb[pos] == 0x50)
{
if(bb[pos+1] == 0x4b && bb[pos+2] == 0x05 && bb[pos+3] == 0x06)
break; // found!!
pos -= 4;
}
else
pos --;
}
if(pos < 0)
{
if(currentLength == 65536)
break;
if(currentLength == 1024)
currentLength = 65536;
else if(currentLength == 256)
currentLength = 1024;
else
break;
}
else
{
// found it!! so at offset pos+3*4 there is Size, and pos+4*4
// BinaryReader is so elegant but now it's too much
Size = MakeInt(bb, pos+12);
Offset = MakeInt(bb, pos+16);
Entries = MakeShort(bb, pos+10);
return true;
}
}
return false;
}
/// <summary>
/// Get a Stream for reading the specified entry
/// </summary>
/// <param name="entry"></param>
/// <returns></returns>
public Stream GetInputStream(ZipEntry entry)
{
if(entry.Size == 0)
return null;
if (entries == null)
{
throw new InvalidOperationException("ZipFile has closed");
}
int index = (int)entry.ZipFileIndex;
if (index < 0 || index >= entries.Length || entries[index].Name != entry.Name)
{
throw new IndexOutOfRangeException();
}
// WARNING
// should parse the Local Header to get the data address
// Maximum Size of the Local Header is ... 16+64K*2
//
// So the HTTP request should ask for the big local header, but actually the
// additional data is not downloaded.
// Optionally use an additional Request to be really precise
//HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl);
int limit = (int)(entry.Offset+entry.CompressedSize+16+65536*2);
if(limit >= MaxFileOffset)
limit = MaxFileOffset-1;
//req.AddRange((int)entry.Offset, limit);
//HttpWebResponse res = (HttpWebResponse)req.GetResponse();
//Stream baseStream = res.GetResponseStream();
Stream baseStream = protocolProvider.CreateStream(this.url, (int)entry.Offset, limit);
// skips all the header
SkipLocalHeader(baseStream, entries[index]);
CompressionMethod method = entries[index].CompressionMethod;
Stream istr = new PartialInputStream(baseStream, entries[index].CompressedSize);
switch (method)
{
case CompressionMethod.Stored:
return istr;
case CompressionMethod.Deflated:
return new InflaterInputStream(istr, new Inflater(true));
case (CompressionMethod)12:
return new BZip2InputStream(istr);
default:
throw new ZipException("Unknown compression method " + method);
}
}
#region Helper methods
/// <summary>
/// Read an unsigned short in little endian byte order.
/// </summary>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="System.IO.EndOfStreamException">
/// if the file ends prematurely
/// </exception>
private static int ReadLeShort(Stream s)
{
return s.ReadByte() | s.ReadByte() << 8;
}
/// <summary>
/// Read an int in little endian byte order.
/// </summary>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="System.IO.EndOfStreamException">
/// if the file ends prematurely
/// </exception>
private static int ReadLeInt(Stream s)
{
return ReadLeShort(s) | ReadLeShort(s) << 16;
}
private static void Skip(Stream s, int n)
{
for(int i = 0; i < n; i++)
s.ReadByte();
}
private static int MakeInt(byte [] bb, int pos)
{
return bb[pos+0]|(bb[pos+1]<<8)|(bb[pos+2]<<16)|(bb[pos+3]<<24);
}
private static int MakeShort(byte[] bb, int pos)
{
return bb[pos+0]|(bb[pos+1]<<8);
}
#endregion
public int Size
{
get { return entries == null ? 0 : entries.Length; }
}
public ZipEntry this[string entryName]
{
get
{
for (int i = 0; i < entries.Length; i++)
{
if (entries[i].Name == entryName)
{
return entries[i];
}
}
throw new ArgumentException("entryName");
}
}
public ZipEntry this[int index]
{
get { return entries[index]; }
}
/// <summary>
/// Returns an IEnumerator of all Zip entries in this Zip file.
/// </summary>
public IEnumerator GetEnumerator()
{
if (entries == null)
{
throw new InvalidOperationException("ZipFile has closed");
}
return new ZipEntryEnumeration(entries);
}
class ZipEntryEnumeration : IEnumerator
{
ZipEntry[] array;
int ptr = -1;
public ZipEntryEnumeration(ZipEntry[] arr)
{
array = arr;
}
public object Current
{
get
{
return array[ptr];
}
}
public void Reset()
{
ptr = -1;
}
public bool MoveNext()
{
return (++ptr < array.Length);
}
}
}
}
MyDownloader.Extension/app.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyDownloader.Extension.WindowsIntegration.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.AutoDownloads.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.SpeedLimit.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.Scheduler.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.Protocols.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.AntiVirus.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="MyDownloader.Extension.Notifications.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<MyDownloader.Extension.WindowsIntegration.Settings>
<setting name="MonitorClipboard" serializeAs="String">
<value>False</value>
</setting>
</MyDownloader.Extension.WindowsIntegration.Settings>
<MyDownloader.Extension.AutoDownloads.Settings>
<setting name="MaxJobs" serializeAs="String">
<value>5</value>
</setting>
<setting name="WorkOnlyOnSpecifiedTimes" serializeAs="String">
<value>False</value>
</setting>
<setting name="TimesToWork" serializeAs="String">
<value />
</setting>
<setting name="MaxRateOnTime" serializeAs="String">
<value>1</value>
</setting>
<setting name="AutoStart" serializeAs="String">
<value>False</value>
</setting>
</MyDownloader.Extension.AutoDownloads.Settings>
<MyDownloader.Extension.Notifications.Settings>
<setting name="DownloadAddedSound" serializeAs="String">
<value />
</setting>
<setting name="DownloadRemovedSound" serializeAs="String">
<value />
</setting>
<setting name="DownloadEndedSound" serializeAs="String">
<value />
</setting>
<setting name="ShowBallon" serializeAs="String">
<value>True</value>
</setting>
<setting name="BallonTimeout" serializeAs="String">
<value>3000</value>
</setting>
</MyDownloader.Extension.Notifications.Settings>
<MyDownloader.Extension.AntiVirus.Settings>
<setting name="CheckFileWithAV" serializeAs="String">
<value>True</value>
</setting>
<setting name="AVFileName" serializeAs="String">
<value />
</setting>
<setting name="FileTypes" serializeAs="String">
<value />
</setting>
<setting name="AVParameter" serializeAs="String">
<value />
</setting>
</MyDownloader.Extension.AntiVirus.Settings>
<MyDownloader.Extension.SpeedLimit.Settings>
<setting name="EnabledLimit" serializeAs="String">
<value>False</value>
</setting>
<setting name="MaxRate" serializeAs="String">
<value>1024</value>
</setting>
</MyDownloader.Extension.SpeedLimit.Settings>
<MyDownloader.Extension.Scheduler.Settings>
<setting name="MaxJobs" serializeAs="String">
<value>5</value>
</setting>
<setting name="WorkOnlyOnSpecifiedTimes" serializeAs="String">
<value>False</value>
</setting>
<setting name="TimesToWork" serializeAs="String">
<value />
</setting>
<setting name="MaxRateOnTime" serializeAs="String">
<value>1</value>
</setting>
</MyDownloader.Extension.Scheduler.Settings>
<MyDownloader.Extension.Protocols.Settings>
<setting name="ProxyAddress" serializeAs="String">
<value />
</setting>
<setting name="ProxyUserName" serializeAs="String">
<value />
</setting>
<setting name="ProxyPassword" serializeAs="String">
<value />
</setting>
<setting name="ProxyDomain" serializeAs="String">
<value />
</setting>
<setting name="UseProxy" serializeAs="String">
<value>False</value>
</setting>
<setting name="ProxyByPassOnLocal" serializeAs="String">
<value>True</value>
</setting>
<setting name="ProxyPort" serializeAs="String">
<value>80</value>
</setting>
</MyDownloader.Extension.Protocols.Settings>
</userSettings>
</configuration>
MyDownloader.IEPlugin/BandObjectLib/Attributes.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//Copyright Pavel Zolnikov, 2002
//
// http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx
using System;
using System.Runtime.InteropServices;
using System.Reflection;
namespace BandObjectLib
{
/// <summary>
/// Represents different styles of a band object.
/// </summary>
[Flags]
[Serializable]
public enum BandObjectStyle : uint
{
Vertical = 1,
Horizontal = 2,
ExplorerToolbar = 4,
TaskbarToolBar = 8,
ExplorerBar = 16
}
/// <summary>
/// Specifies Style of the band object, its Name(displayed in explorer menu) and HelpText(displayed in status bar when menu command selected).
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class BandObjectAttribute : System.Attribute
{
public BandObjectAttribute() { }
public BandObjectAttribute(string name, BandObjectStyle style)
{
Name = name;
Style = style;
}
public BandObjectStyle Style;
public string Name;
public string HelpText;
}
}
MyDownloader.IEPlugin/BandObjectLib/BandObject.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
//Copyright Pavel Zolnikov, 2002
//
//BandObject - implements generic Band Object functionality.
// http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using SHDocVw;
using System.Reflection;
using System.Diagnostics;
using System.Drawing;
using System.ComponentModel;
using Microsoft.Win32;
namespace BandObjectLib
{
/// <summary>
/// Implements generic Band Object functionality.
/// </summary>
/// <example>
/// [Guid("YOURGUID-GOES-HERE-YOUR-GUIDGOESHERE")]
/// [BandObject("Hello World Bar", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar , HelpText = "Shows bar that says hello.")]
/// public class HelloWorldBar : BandObject
/// { /*...*/ }
/// </example>
public class BandObject : UserControl, IObjectWithSite, IDeskBand, IDockingWindow, IOleWindow, IInputObject
{
/// <summary>
/// Reference to the host explorer.
/// </summary>
protected WebBrowserClass Explorer;
protected IInputObjectSite BandObjectSite;
/// <summary>
/// This event is fired after reference to hosting explorer is retreived and stored in Explorer property.
/// </summary>
public event EventHandler ExplorerAttached;
public BandObject()
{
InitializeComponent();
}
private void InitializeComponent()
{
//
// ExplorerBar
//
this.Name = "BandObject";
}
/// <summary>
/// Title of band object. Displayed at the left or on top of the band object.
/// </summary>
[Browsable(true)]
[DefaultValue("")]
public String Title
{
get
{
return _title;
}
set
{
_title = value;
}
}String _title;
/// <summary>
/// Minimum size of the band object. Default value of -1 sets no minimum constraint.
/// </summary>
[Browsable(true)]
[DefaultValue(typeof(Size), "-1,-1")]
public Size MinSize
{
get
{
return _minSize;
}
set
{
_minSize = value;
}
}Size _minSize = new Size(-1, -1);
/// <summary>
/// Maximum size of the band object. Default value of -1 sets no maximum constraint.
/// </summary>
[Browsable(true)]
[DefaultValue(typeof(Size), "-1,-1")]
public Size MaxSize
{
get
{
return _maxSize;
}
set
{
_maxSize = value;
}
}Size _maxSize = new Size(-1, -1);
/// <summary>
/// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint.
/// </summary>
[Browsable(true)]
[DefaultValue(typeof(Size), "-1,-1")]
public Size IntegralSize
{
get
{
return _integralSize;
}
set
{
_integralSize = value;
}
}Size _integralSize = new Size(-1, -1);
public virtual void GetBandInfo(
UInt32 dwBandID,
UInt32 dwViewMode,
ref DESKBANDINFO dbi)
{
dbi.wszTitle = this.Title;
dbi.ptActual.X = this.Size.Width;
dbi.ptActual.Y = this.Size.Height;
dbi.ptMaxSize.X = this.MaxSize.Width;
dbi.ptMaxSize.Y = this.MaxSize.Height;
dbi.ptMinSize.X = this.MinSize.Width;
dbi.ptMinSize.Y = this.MinSize.Height;
dbi.ptIntegral.X = this.IntegralSize.Width;
dbi.ptIntegral.Y = this.IntegralSize.Height;
dbi.dwModeFlags = DBIM.TITLE | DBIM.ACTUAL | DBIM.MAXSIZE | DBIM.MINSIZE | DBIM.INTEGRAL;
}
/// <summary>
/// Called by explorer when band object needs to be showed or hidden.
/// </summary>
/// <param name="fShow"></param>
public virtual void ShowDW(bool fShow)
{
if (fShow)
Show();
else
Hide();
}
/// <summary>
/// Called by explorer when window is about to close.
/// </summary>
public virtual void CloseDW(UInt32 dwReserved)
{
Dispose(true);
}
/// <summary>
/// Not used.
/// </summary>
public virtual void ResizeBorderDW(IntPtr prcBorder, Object punkToolbarSite, bool fReserved) { }
public virtual void GetWindow(out System.IntPtr phwnd)
{
phwnd = Handle;
}
public virtual void ContextSensitiveHelp(bool fEnterMode) { }
public virtual void SetSite(Object pUnkSite)
{
if (BandObjectSite != null)
Marshal.ReleaseComObject(BandObjectSite);
if (Explorer != null)
{
Marshal.ReleaseComObject(Explorer);
Explorer = null;
}
BandObjectSite = (IInputObjectSite)pUnkSite;
if (BandObjectSite != null)
{
//pUnkSite is a pointer to object that implements IOleWindowSite or something similar
//we need to get access to the top level object - explorer itself
//to allows this explorer objects also implement IServiceProvider interface
//(don't mix it with System.IServiceProvider!)
//we get this interface and ask it to find WebBrowserApp
_IServiceProvider sp = BandObjectSite as _IServiceProvider;
Guid guid = ExplorerGUIDs.IID_IWebBrowserApp;
Guid riid = ExplorerGUIDs.IID_IUnknown;
try
{
object w;
sp.QueryService(
ref guid,
ref riid,
out w);
//once we have interface to the COM object we can create RCW from it
Explorer = (WebBrowserClass)Marshal.CreateWrapperOfType(
w as IWebBrowser,
typeof(WebBrowserClass)
);
OnExplorerAttached(EventArgs.Empty);
}
catch (COMException)
{
//we anticipate this exception in case our object instantiated
//as a Desk Band. There is no web browser service available.
}
}
}
public virtual void GetSite(ref Guid riid, out Object ppvSite)
{
ppvSite = BandObjectSite;
}
/// <summary>
/// Called explorer when focus has to be chenged.
/// </summary>
public virtual void UIActivateIO(Int32 fActivate, ref MSG Msg)
{
if (fActivate != 0)
{
Control ctrl = GetNextControl(this, true);//first
if (ModifierKeys == Keys.Shift)
ctrl = GetNextControl(ctrl, false);//last
if (ctrl != null) ctrl.Select();
this.Focus();
}
}
public virtual Int32 HasFocusIO()
{
return this.ContainsFocus ? 0 : 1; //S_OK : S_FALSE;
}
/// <summary>
/// Called by explorer to process keyboard events. Undersatands Tab and F6.
/// </summary>
/// <param name="msg"></param>
/// <returns>S_OK if message was processed, S_FALSE otherwise.</returns>
public virtual Int32 TranslateAcceleratorIO(ref MSG msg)
{
if (msg.message == 0x100)//WM_KEYDOWN
if (msg.wParam == (uint)Keys.Tab || msg.wParam == (uint)Keys.F6)//keys used by explorer to navigate from control to control
if (SelectNextControl(
ActiveControl,
ModifierKeys == Keys.Shift ? false : true,
true,
true,
false)
)
return 0;//S_OK
return 1;//S_FALSE
}
/// <summary>
/// Override this method to handle ExplorerAttached event.
/// </summary>
/// <param name="ea"></param>
protected virtual void OnExplorerAttached(EventArgs ea)
{
if (ExplorerAttached != null)
ExplorerAttached(this, ea);
}
/// <summary>
/// Notifies explorer of focus change.
/// </summary>
protected override void OnGotFocus(System.EventArgs e)
{
base.OnGotFocus(e);
BandObjectSite.OnFocusChangeIS(this as IInputObject, 1);
}
/// <summary>
/// Notifies explorer of focus change.
/// </summary>
protected override void OnLostFocus(System.EventArgs e)
{
base.OnLostFocus(e);
if (ActiveControl == null)
BandObjectSite.OnFocusChangeIS(this as IInputObject, 0);
}
/// <summary>
/// Called when derived class is registered as a COM server.
/// </summary>
[ComRegisterFunctionAttribute]
public static void Register(Type t)
{
string guid = t.GUID.ToString("B");
RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid);
RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories");
BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes(
typeof(BandObjectAttribute),
false);
string name = t.Name;
string help = t.Name;
BandObjectStyle style = 0;
if (boa.Length == 1)
{
if (boa[0].Name != null)
name = boa[0].Name;
if (boa[0].HelpText != null)
help = boa[0].HelpText;
style = boa[0].Style;
}
rkClass.SetValue(null, name);
rkClass.SetValue("MenuText", name);
rkClass.SetValue("HelpText", help);
if (0 != (style & BandObjectStyle.Vertical))
rkCat.CreateSubKey("{00021493-0000-0000-C000-000000000046}");
else
if (rkCat.OpenSubKey("{00021493-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021493-0000-0000-C000-000000000046}");
if (0 != (style & BandObjectStyle.Horizontal))
rkCat.CreateSubKey("{00021494-0000-0000-C000-000000000046}");
else
if (rkCat.OpenSubKey("{00021494-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021494-0000-0000-C000-000000000046}");
if (0 != (style & BandObjectStyle.TaskbarToolBar))
rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}");
else
if (rkCat.OpenSubKey("{00021492-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021492-0000-0000-C000-000000000046}");
if (0 != (style & BandObjectStyle.ExplorerToolbar))
Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").SetValue(guid, name);
if (0 != (style & BandObjectStyle.ExplorerBar))
Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").CreateSubKey(guid);
else
if (Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").OpenSubKey(guid) != null) Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").DeleteSubKey(guid);
}
/// <summary>
/// Called when derived class is unregistered as a COM server.
/// </summary>
[ComUnregisterFunctionAttribute]
public static void Unregister(Type t)
{
string guid = t.GUID.ToString("B");
BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes(
typeof(BandObjectAttribute),
false);
BandObjectStyle style = 0;
if (boa.Length == 1) style = boa[0].Style;
if (0 != (style & BandObjectStyle.ExplorerToolbar))
Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").DeleteValue(guid, false);
Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid);
}
}
}
MyDownloader.IEPlugin/BandObjectLib/ComInterop.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//This file is a part of the Command Prompt Explorer Bar project.
//
//Copyright Pavel Zolnikov, 2002
//
//declarations of some COM interfaces and structues
// http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace BandObjectLib
{
abstract class ExplorerGUIDs
{
public static readonly Guid IID_IWebBrowserApp = new Guid("{0002DF05-0000-0000-C000-000000000046}");
public static readonly Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
}
[Flags]
public enum DBIM : uint
{
MINSIZE = 0x0001,
MAXSIZE = 0x0002,
INTEGRAL = 0x0004,
ACTUAL = 0x0008,
TITLE = 0x0010,
MODEFLAGS = 0x0020,
BKCOLOR = 0x0040
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DESKBANDINFO
{
public UInt32 dwMask;
public Point ptMinSize;
public Point ptMaxSize;
public Point ptIntegral;
public Point ptActual;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
public String wszTitle;
public DBIM dwModeFlags;
public Int32 crBkgnd;
};
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite);
void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00000114-0000-0000-C000-000000000046")]
public interface IOleWindow
{
void GetWindow(out System.IntPtr phwnd);
void ContextSensitiveHelp([In] bool fEnterMode);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("012dd920-7b26-11d0-8ca9-00a0c92dbfe8")]
public interface IDockingWindow
{
void GetWindow(out System.IntPtr phwnd);
void ContextSensitiveHelp([In] bool fEnterMode);
void ShowDW([In] bool fShow);
void CloseDW([In] UInt32 dwReserved);
void ResizeBorderDW(
IntPtr prcBorder,
[In, MarshalAs(UnmanagedType.IUnknown)] Object punkToolbarSite,
bool fReserved);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("EB0FE172-1A3A-11D0-89B3-00A0C90A90AC")]
public interface IDeskBand
{
void GetWindow(out System.IntPtr phwnd);
void ContextSensitiveHelp([In] bool fEnterMode);
void ShowDW([In] bool fShow);
void CloseDW([In] UInt32 dwReserved);
void ResizeBorderDW(
IntPtr prcBorder,
[In, MarshalAs(UnmanagedType.IUnknown)] Object punkToolbarSite,
bool fReserved);
void GetBandInfo(
UInt32 dwBandID,
UInt32 dwViewMode,
ref DESKBANDINFO pdbi);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("0000010c-0000-0000-C000-000000000046")]
public interface IPersist
{
void GetClassID(out Guid pClassID);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00000109-0000-0000-C000-000000000046")]
public interface IPersistStream
{
void GetClassID(out Guid pClassID);
void IsDirty();
void Load([In, MarshalAs(UnmanagedType.Interface)] Object pStm);
void Save([In, MarshalAs(UnmanagedType.Interface)] Object pStm,
[In] bool fClearDirty);
void GetSizeMax([Out] out UInt64 pcbSize);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
public interface _IServiceProvider
{
void QueryService(
ref Guid guid,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out Object Obj);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("68284faa-6a48-11d0-8c78-00c04fd918b4")]
public interface IInputObject
{
void UIActivateIO(Int32 fActivate, ref MSG msg);
[PreserveSig]
//[return:MarshalAs(UnmanagedType.Error)]
Int32 HasFocusIO();
[PreserveSig]
Int32 TranslateAcceleratorIO(ref MSG msg);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("f1db8392-7331-11d0-8c99-00a0c92dbfe8")]
public interface IInputObjectSite
{
[PreserveSig]
Int32 OnFocusChangeIS([MarshalAs(UnmanagedType.IUnknown)] Object punkObj, Int32 fSetFocus);
}
public struct POINT
{
public Int32 x;
public Int32 y;
}
public struct MSG
{
public IntPtr hwnd;
public UInt32 message;
public UInt32 wParam;
public Int32 lParam;
public UInt32 time;
public POINT pt;
}
}
MyDownloader.IEPlugin/IEMD.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using BandObjectLib;
using System.Runtime.InteropServices;
using SHDocVw;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Threading;
namespace MyDownloader.IEPlugin
{
[Guid("3F93D37D-54B8-4d5d-92CB-6F5644E7A65F")]
[BandObject("MyDownloader", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar | BandObjectStyle.TaskbarToolBar)]
public class IEMD : BandObject
{
private System.Windows.Forms.Button btnDownload;
private IContainer components;
private const int IE_TRUE = 1;
private const int IE_FALSE = 0;
private ToolTip toolTips;
VideoSitesRepository videoSites;
DateTime lastDownload = DateTime.Now;
private Button btnOpenDownloader;
string lastUrl = "";
public IEMD()
{
InitializeComponent();
btnDownload.Enabled = false;
videoSites = new VideoSitesRepository();
}
#region Component Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IEMD));
this.btnDownload = new System.Windows.Forms.Button();
this.toolTips = new System.Windows.Forms.ToolTip(this.components);
this.btnOpenDownloader = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnDownload
//
this.btnDownload.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.btnDownload.ForeColor = System.Drawing.SystemColors.ControlDark;
this.btnDownload.Image = ((System.Drawing.Image)(resources.GetObject("btnDownload.Image")));
this.btnDownload.Location = new System.Drawing.Point(0, 0);
this.btnDownload.Name = "btnDownload";
this.btnDownload.Size = new System.Drawing.Size(24, 21);
this.btnDownload.TabIndex = 1;
this.toolTips.SetToolTip(this.btnDownload, "Download video using MyDownloader");
this.btnDownload.Click += new System.EventHandler(this.btnDownload_Click);
//
// btnOpenDownloader
//
this.btnOpenDownloader.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.btnOpenDownloader.ForeColor = System.Drawing.SystemColors.ControlDark;
this.btnOpenDownloader.Image = ((System.Drawing.Image)(resources.GetObject("btnOpenDownloader.Image")));
this.btnOpenDownloader.Location = new System.Drawing.Point(26, 0);
this.btnOpenDownloader.Name = "btnOpenDownloader";
this.btnOpenDownloader.Size = new System.Drawing.Size(24, 21);
this.btnOpenDownloader.TabIndex = 2;
this.toolTips.SetToolTip(this.btnOpenDownloader, "Lauch MyDownloader");
this.btnOpenDownloader.Click += new System.EventHandler(this.btnOpenDownloader_Click);
//
// IEMD
//
this.Controls.Add(this.btnOpenDownloader);
this.Controls.Add(this.btnDownload);
this.MinSize = new System.Drawing.Size(52, 21);
this.Name = "IEMD";
this.Size = new System.Drawing.Size(52, 21);
this.Title = "";
this.ResumeLayout(false);
}
#endregion
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
public SHDocVw.WebBrowser GetIEDocument()
{
return (SHDocVw.WebBrowser) this.Explorer;
}
protected override void OnExplorerAttached(EventArgs ea)
{
SHDocVw.WebBrowser IEDocument = this.GetIEDocument();
IEDocument.BeforeNavigate2 +=new DWebBrowserEvents2_BeforeNavigate2EventHandler(BeforeNavigate);
IEDocument.NavigateComplete2 +=new DWebBrowserEvents2_NavigateComplete2EventHandler(AfterNavigate);
IEDocument.FileDownload += new DWebBrowserEvents2_FileDownloadEventHandler(IEDocument_FileDownload);
base.OnExplorerAttached (ea);
}
void IEDocument_FileDownload(bool ActiveDocument, ref bool Cancel)
{
if (!ActiveDocument)
{
if ((Control.ModifierKeys & Keys.Alt) == Keys.Alt)
{
Cancel = true;
if ((DateTime.Now - lastDownload).TotalSeconds >= 1.9)
{
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
DownloadURL(lastUrl);
});
lastDownload = DateTime.Now;
}
}
}
}
private void DownloadURL(string url)
{
try
{
Process p;
if (url != null)
{
p = Process.Start(Settings.MyDownloaderPath, String.Format("/sw {0}", url));
}
else
{
p = Process.Start(Settings.MyDownloaderPath);
}
p.WaitForInputIdle(5000);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void MakeVisible()
{
if(GetIEDocument().ToolBar == IE_FALSE)
//if(Configuration.AlwaysShow)
{
this.Visible = true;
GetIEDocument().ToolBar = IE_TRUE;
}
}
public void AfterNavigate(object iDisp, ref object URL)
{
SHDocVw.WebBrowser IEDocument = GetIEDocument();
MakeVisible();
mshtml.HTMLDocument HTML = (mshtml.HTMLDocument) IEDocument.Document;
// save cookies
//StreamWriter sw=new StreamWriter(Settings.MyDownloaderPath + "_cookie");
//sw.Write(HTML.cookie);
//sw.Close();
//HTML.cookie
//HTML.attachEvent(iDisp)
btnDownload.Enabled = videoSites.IsVideoSite(IEDocument.LocationURL);
}
public void BeforeNavigate(object iDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
{
lastUrl = URL.ToString();
}
private void btnDownload_Click(object sender, System.EventArgs e)
{
try
{
SHDocVw.WebBrowser IEDocument = GetIEDocument();
DownloadURL(IEDocument.LocationURL);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnOpenDownloader_Click(object sender, EventArgs e)
{
DownloadURL(null);
}
}
}
MyDownloader.IEPlugin/IEMD.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="btnDownload.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
R0lGODlhCQAMAPMAAJieqydPokFuxlaI7Gua91+F0Yev/pe5/P///wAAAAAAAAAAAAAAAAAAAAAAAAAA
ACH5BAEAAAgALAAAAAAJAAwAAAQvECFCS5GSnGMCRgU3eFhIjJ+JlsZJSoUxrJU8BgEgUIMg5AhAoPcD
YITFTxAoiQAAOw==
</value>
</data>
<metadata name="toolTips.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>4, 31</value>
</metadata>
<data name="btnOpenDownloader.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAFVJREFUOE9jYKAU
NDQ0/KcEM4A0HzhwgGQM0gd0/H+4AQwM+4ECxGOiDfgPBCCb0GkMA8gJBxQvgK0gAWC4gAS9YKWjBlA7
DMhJA/BYACcGyjBl+RkAj+eF6Chu5VQAAAAASUVORK5CYII=
</value>
</data>
</root>
MyDownloader.IEPlugin/IEManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using BandObjectLib;
using System.Runtime.InteropServices;
using SHDocVw;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Threading;
namespace MyDownloader.IEPlugin
{
//http://msdn.microsoft.com/en-us/library/aa753588.aspx
//http://msdn.microsoft.com/en-us/library/aa753590.aspx
[Guid("3F93D37D-54B8-4d5d-92CB-6F5644E7A65A")]
[BandObject("MyDownloader_List", BandObjectStyle.Vertical | BandObjectStyle.ExplorerBar )]
public class IEManager : BandObject
{
public IEManager()
{
//InitializeComponent();
}
}
}
MyDownloader.IEPlugin/IEManager.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.IEPlugin/MyDownloader.IEPlugin.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{91BB212C-D158-4B83-A3BC-1A41BBDC8463}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyDownloader.IEPlugin</RootNamespace>
<AssemblyName>MyDownloader.IEPlugin</AssemblyName>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>MyDownloader.IEPlugin.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=4b827ebe229d539f">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Interop.SHDocVw.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BandObjectLib\Attributes.cs" />
<Compile Include="BandObjectLib\BandObject.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="BandObjectLib\ComInterop.cs" />
<EmbeddedResource Include="VideoSitesURLPatterns.txt" />
<Compile Include="IEManager.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="IEMD.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Settings.cs" />
<Compile Include="VideoSitesRepository.cs" />
</ItemGroup>
<ItemGroup>
<None Include="unregister.reg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="register.reg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="unregister.bat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="MyDownloader.IEPlugin.snk" />
<None Include="register.bat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="IEManager.resx">
<DependentUpon>IEManager.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="IEMD.resx">
<SubType>Designer</SubType>
<DependentUpon>IEMD.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Content Include="READ-ME.txt" />
</ItemGroup>
<ItemGroup>
<COMReference Include="MSHTML">
<Guid>{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}</Guid>
<VersionMajor>4</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
</COMReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>
MyDownloader.IEPlugin/READ-ME.txt
1
2
3
4
5
To install MyDownloader toolbar:
1) Edit 'register.reg' setting the correct MyDownloader filename
2) Run register.reg.
3) Run register.bat inside Visual Studio command prompt.
MyDownloader.IEPlugin/Settings.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
namespace MyDownloader.IEPlugin
{
internal static class Settings
{
private const string ROOTREG = "SOFTWARE\\MyDownloader";
public static string MyDownloaderPath
{
get
{
return GetValue("MyDownloaderPath");
}
}
private static string GetValue(string Key)
{
using (RegistryKey RKey = Registry.LocalMachine.CreateSubKey(ROOTREG))
{
return RKey.GetValue(Key, "").ToString();
}
}
}
}
MyDownloader.IEPlugin/VideoSitesRepository.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace MyDownloader.IEPlugin
{
internal class VideoSitesRepository
{
private List<Regex> videoSites = new List<Regex>();
#region Constructor
public VideoSitesRepository()
{
LoadVideoSites();
}
#endregion
#region Methods
public bool IsVideoSite(string url)
{
for (int i = 0; i < videoSites.Count; i++)
{
if (videoSites[i].IsMatch(url))
{
return true;
}
}
return false;
}
private void LoadVideoSites()
{
try
{
using (StreamReader urlsStream = new StreamReader(this.GetType().Assembly.GetManifestResourceStream("MyDownloader.IEPlugin.VideoSitesURLPatterns.txt")))
{
string line = urlsStream.ReadLine();
while (line != null || line.Length == 0)
{
RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline)
| RegexOptions.IgnoreCase);
Regex reg = new Regex(line, options);
videoSites.Add(reg);
line = urlsStream.ReadLine();
}
}
}
catch (Exception)
{
}
}
#endregion
}
}
MyDownloader.IEPlugin/VideoSitesURLPatterns.txt
1
2
3
4
5
(?:[Bb][Rr][Ee][Aa][Kk]\.[Cc][Oo][Mm]/)(\w[\w|-]*)
(?:[Vv][Ii][Dd][Ee][Oo]\.[Gg][Oo][Oo][Gg][Ll][Ee]\.[Cc][Oo][Mm]/videoplay\?docid=)-?(\w[\w|-]*)
(?:[Mm][Ee][Ta][Aa][Cc][Aa][Ff][Ee]\.[Cc][Oo][Mm]/watch/)(\w[\w|-]*)/(\w[\w|-]*)
(?:[Mm][Ee][Dd][Ii][Aa]\.[Pp][Uu][Tt][Ff][Ii][Ll][Ee]\.[Cc][Oo][Mm]/)(\w[\w|-]*)
(?:[Yy][Oo][Uu][Tt][Uu][Bb][Ee]\.[Cc][Oo][Mm]/watch\?v=)(\w[\w|-]*)
MyDownloader.IEPlugin/bin/Release/register.bat
1
2
3
gacutil /if Interop.SHDocVw.dll
gacutil /if MyDownloader.IEPlugin.dll
regasm MyDownloader.IEPlugin.dll
MyDownloader.IEPlugin/bin/Release/unregister.bat
1
2
3
regasm /unregister MyDownloader.IEPlugin.dll
gacutil /u Interop.SHDocVw.dll
gacutil /u MyDownloader.IEPlugin.dll
MyDownloader.IEPlugin/register.bat
1
2
3
gacutil /if Interop.SHDocVw.dll
gacutil /if MyDownloader.IEPlugin.dll
regasm MyDownloader.IEPlugin.dll
MyDownloader.IEPlugin/unregister.bat
1
2
3
regasm /unregister MyDownloader.IEPlugin.dll
gacutil /u Interop.SHDocVw.dll
gacutil /u MyDownloader.IEPlugin.dll
MyDownloader.Spider/IAsyncRetriver.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider
{
public interface IAsyncRetriver
{
ISpiderResource Resource { get; }
bool IsCompleted { get; }
}
}
MyDownloader.Spider/INamingRule.cs
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider
{
public interface INamingRule
{
bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider);
}
}
MyDownloader.Spider/ISpiderResource.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
using System.Text.RegularExpressions;
using System.Net.Mime;
using System.IO;
using System.Threading;
namespace MyDownloader.Spider
{
public interface ISpiderResource
{
string Location { get; }
int Depth { get; }
ISpiderResource ParentResource { get; }
List<ISpiderResource> NextResources { get; }
IAsyncRetriver BeginReceive();
void EndReceive();
}
}
MyDownloader.Spider/ISpiderResourceFactory.cs
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider
{
public interface ISpiderResourceFactory
{
ISpiderResource CreateSpider(SpiderContext cntx, ISpiderResource parent, string location);
}
}
MyDownloader.Spider/MyDownloader.Spider.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{69C99442-953E-4559-96D3-C82CC57A3C87}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyDownloader.Spider</RootNamespace>
<AssemblyName>MyDownloader.Spider</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="MyDownloader.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Release\MyDownloader.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="TabStrip, Version=2.0.2523.29272, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\TabStrip.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="IAsyncRetriver.cs" />
<Compile Include="ISpiderResource.cs" />
<Compile Include="ISpiderResourceFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Web\Rules\BaseLocationNamingRule.cs" />
<Compile Include="Web\Rules\ExcludeExtensionNamingRule.cs" />
<Compile Include="Web\Rules\ExcludeNameNamingRule.cs" />
<Compile Include="INamingRule.cs" />
<Compile Include="Spider.cs" />
<Compile Include="SpiderContext.cs" />
<Compile Include="UI\StartAutoDownloadsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\StartAutoDownloadsForm.Designer.cs">
<DependentUpon>StartAutoDownloadsForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\WebSpider.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\WebSpider.Designer.cs">
<DependentUpon>WebSpider.cs</DependentUpon>
</Compile>
<Compile Include="Web\DownloaderAsyncRetrive.cs" />
<Compile Include="Parsers\Html\HtmlParser.cs" />
<Compile Include="Parsers\Html\UrlType.cs" />
<Compile Include="Web\Rules\MaxDepthNamingRule.cs" />
<Compile Include="Web\WebSpiderResource.cs" />
<Compile Include="Web\WebSpiderResourceFactory.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyDownloader.Extension\MyDownloader.Extension.csproj">
<Project>{FEA18B6C-491F-401A-A06B-AE47888FF288}</Project>
<Name>MyDownloader.Extension</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="UI\StartAutoDownloadsForm.resx">
<SubType>Designer</SubType>
<DependentUpon>StartAutoDownloadsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\WebSpider.resx">
<DependentUpon>WebSpider.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
MyDownloader.Spider/Parsers/Html/HtmlParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
namespace MyDownloader.Spider.Parsers.Html
{
public class HtmlParser: IDisposable
{
private static string RegExprHREF = @"(?<=a\s+([^>]+\s+)?href\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])";
//private static string RegExprIMG = @"<img\s+([^>]+\s+)?src\s*=\s*(?:""(?<1>[/\a-z0-9_][^""\/]*)""|'(?<1>[/\a-z0-9_][^'']*)''|(?<1>[/\a-z0-9_]\S*))(\s?[^>]*/)?>";
private static string RegExprIMG = @"(?<=img\s+([^>]+\s+)?src\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])";
private static string RegExprIFrame = @"(?<=iframe\s+src\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])";
private static string RegExprFrame = @"(?<=frame\s+src\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])";
private static Regex RegExFindHref = new Regex(RegExprHREF, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static Regex RegExFindImg = new Regex(RegExprIMG, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static Regex RegExFindIFrame = new Regex(RegExprIFrame, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static Regex RegExFindFrame = new Regex(RegExprFrame, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static Regex[] regs = { RegExFindHref, RegExFindImg, RegExFindIFrame, RegExFindFrame };
private string htmlData;
public HtmlParser(Stream htmlStream)
{
using (StreamReader sw = new StreamReader(htmlStream))
{
htmlData = sw.ReadToEnd();
}
}
public IEnumerable<Uri> GetResources(UrlType urlType, string baseUri)
{
return GetEnumerator(regs[(int)urlType], baseUri, this.htmlData);
}
public IEnumerable<Uri> GetHrefs(string baseUri)
{
return GetEnumerator(RegExFindHref, baseUri, this.htmlData);
}
public IEnumerable<Uri> GetImages(string baseUri)
{
return GetEnumerator(RegExFindImg, baseUri, this.htmlData);
}
public IEnumerable<Uri> GetFrames(string baseUri)
{
return GetEnumerator(RegExFindFrame, baseUri, this.htmlData);
}
public IEnumerable<Uri> GetIFrames(string baseUri)
{
return GetEnumerator(RegExFindIFrame, baseUri, this.htmlData);
}
private static IEnumerable<Uri> GetEnumerator(Regex regExpr, string baseUrl, string html)
{
for (Match m = regExpr.Match(html); m.Success; m = m.NextMatch())
{
string href = m.Groups[1].ToString();
// filter non-real relation urls:
if (String.IsNullOrEmpty(href) ||
href.StartsWith("#") ||
href.StartsWith("mailto:") ||
href.StartsWith("javascript:"))
{
continue;
}
href = System.Web.HttpUtility.HtmlDecode(href);
Uri uri = null;
try
{
uri = ConvertToAbsoluteUrl(href, baseUrl);
}
catch (Exception)
{
}
if (uri != null)
{
yield return uri;
}
}
}
private static Uri ConvertToAbsoluteUrl(string url, string baseUrl)
{
// we try to prevent the exception caused in the case the url is relative
// (no scheme info) just for speed
if (url.IndexOf(Uri.SchemeDelimiter) < 0 && baseUrl != null)
{
try
{
Uri baseUri = new Uri(baseUrl);
return new Uri(baseUri, url);
}
catch
{
return null;
}
}
try
{
Uri uri = new Uri(url);
return uri;
}
catch (Exception)
{
if (baseUrl != null)
{
try
{
Uri baseUri = new Uri(baseUrl);
return new Uri(baseUri, url);
}
catch (Exception)
{
return null;
}
}
else
{
return null;
}
}
}
#region IDisposable Members
public void Dispose()
{
this.htmlData = null;
}
#endregion
}
}
MyDownloader.Spider/Parsers/Html/UrlType.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider.Parsers.Html
{
public enum UrlType : int
{
Href = 0,
Img = 1,
IFrame = 2,
Frame = 3,
}
}
MyDownloader.Spider/Properties/AssemblyInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("MyDownloader.Spider")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Programmmers")]
[assembly: AssemblyProduct("MyDownloader.Spider")]
[assembly: AssemblyCopyright("Copyright © Programmmers 2007")]
[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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("71b21d39-e11d-477c-bcc9-228a0407187f")]
// 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 Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
MyDownloader.Spider/Spider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Spider.Web;
using MyDownloader.Spider.Parsers.Html;
namespace MyDownloader.Spider
{
public class Spider
{
private SpiderContext context;
private ISpiderResourceFactory factory;
public Spider(SpiderContext context,
ISpiderResourceFactory factory)
{
this.context = context;
this.factory = factory;
}
#region Events
public event EventHandler Aborted;
public event CompletedEventHandler Completed
{
add
{
context.Completed += value;
}
remove
{
context.Completed -= value;
}
}
protected virtual void OnAborted()
{
if (Aborted != null)
{
Aborted(this, EventArgs.Empty);
}
}
#endregion
#region Properties
public SpiderContext Context
{
get
{
return context;
}
}
#endregion
#region Methods
public virtual IAsyncRetriver BeginLookup()
{
ISpiderResource resourceSpider = factory.CreateSpider(this.context, null, this.context.BaseLocation);
context.AddURIToVisit(new Uri(this.context.BaseLocation), resourceSpider);
return resourceSpider.BeginReceive();
}
public virtual void Abort()
{
context.Abort();
OnAborted();
}
#endregion
}
}
MyDownloader.Spider/SpiderContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Spider.Parsers.Html;
namespace MyDownloader.Spider
{
public delegate void ResourceCompletedEventHandler(SpiderContext context, ISpiderResource resource);
public delegate void CompletedEventHandler(SpiderContext context);
public class SpiderContext
{
private bool aborted;
private string baseDirectory;
private string baseLocation;
private List<INamingRule> namingRules = new List<INamingRule>();
private List<Uri> visitedLocations = new List<Uri>();
private List<ISpiderResource> completedResources = new List<ISpiderResource>();
public SpiderContext()
{
}
public SpiderContext(string baseDirectory, string baseLocation)
{
this.baseDirectory = baseDirectory;
this.baseLocation = baseLocation;
}
#region Properties
public string BaseLocation
{
get
{
return baseLocation;
}
set
{
baseLocation = value;
}
}
public string BaseDirectory
{
get
{
return baseDirectory;
}
set
{
baseDirectory = value;
}
}
public List<INamingRule> NamingRules
{
get
{
return namingRules;
}
}
public List<Uri> VisitedLocations
{
get
{
return visitedLocations;
}
}
public List<ISpiderResource> CompletedResources
{
get
{
return completedResources;
}
}
#endregion
#region Events
public event ResourceCompletedEventHandler ResourceCompleted;
public event CompletedEventHandler Completed;
protected internal virtual void OnResourceCompleted(ISpiderResource spider)
{
if (ResourceCompleted != null)
{
ResourceCompleted(this, spider);
}
}
protected internal virtual void OnCompleted()
{
if (Completed != null)
{
Completed(this);
}
}
#endregion
private bool ShouldAdd(Uri location, ISpiderResource parentSpider)
{
#region Aborted
if (aborted)
{
return false;
}
#endregion
#region Naming rules
for (int j = 0; j < namingRules.Count; j++)
{
if (!namingRules[j].Accept(location, this, parentSpider)) return false;
}
#endregion
return true;
}
public void Abort()
{
aborted = true;
}
public void NotifyCompletion(ISpiderResource spider)
{
lock (completedResources)
{
if (!completedResources.Contains(spider))
{
completedResources.Add(spider);
}
}
OnResourceCompleted(spider);
if (completedResources.Count == VisitedLocations.Count)
{
OnCompleted();
}
}
public bool AddURIToVisit(Uri uri, ISpiderResource parentSpider)
{
if (ShouldAdd(uri, parentSpider))
{
lock (visitedLocations)
{
if (visitedLocations.Contains(uri))
{
return false;
}
visitedLocations.Add(uri);
return true;
}
}
else
{
return false;
}
}
}
}
MyDownloader.Spider/UI/StartAutoDownloadsForm.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
namespace MyDownloader.Spider.UI
{
partial class StartAutoDownloadsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.scheduledDownloadEnabler1 = new MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler();
this.label1 = new System.Windows.Forms.Label();
this.btnNo = new System.Windows.Forms.Button();
this.btnYes = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// scheduledDownloadEnabler1
//
this.scheduledDownloadEnabler1.Location = new System.Drawing.Point(8, 56);
this.scheduledDownloadEnabler1.Name = "scheduledDownloadEnabler1";
this.scheduledDownloadEnabler1.Size = new System.Drawing.Size(346, 163);
this.scheduledDownloadEnabler1.TabIndex = 1;
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(344, 48);
this.label1.TabIndex = 0;
this.label1.Text = "The auto-downloads mode is not enabled. To Web Spider work correcly the auto-down" +
"loads mode must to be enabled. Do you want to enable it now?";
//
// btnNo
//
this.btnNo.DialogResult = System.Windows.Forms.DialogResult.No;
this.btnNo.Location = new System.Drawing.Point(280, 224);
this.btnNo.Name = "btnNo";
this.btnNo.Size = new System.Drawing.Size(75, 23);
this.btnNo.TabIndex = 3;
this.btnNo.Text = "No";
this.btnNo.UseVisualStyleBackColor = true;
//
// btnYes
//
this.btnYes.DialogResult = System.Windows.Forms.DialogResult.Yes;
this.btnYes.Location = new System.Drawing.Point(200, 224);
this.btnYes.Name = "btnYes";
this.btnYes.Size = new System.Drawing.Size(75, 23);
this.btnYes.TabIndex = 2;
this.btnYes.Text = "Yes";
this.btnYes.UseVisualStyleBackColor = true;
//
// StartAutoDownloadsForm
//
this.AcceptButton = this.btnYes;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnNo;
this.ClientSize = new System.Drawing.Size(360, 252);
this.Controls.Add(this.btnYes);
this.Controls.Add(this.btnNo);
this.Controls.Add(this.label1);
this.Controls.Add(this.scheduledDownloadEnabler1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "StartAutoDownloadsForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Start Auto-downloads?";
this.ResumeLayout(false);
}
#endregion
private MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler scheduledDownloadEnabler1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnNo;
private System.Windows.Forms.Button btnYes;
}
}
MyDownloader.Spider/UI/StartAutoDownloadsForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Extension.AutoDownloads;
using MyDownloader.Extension.AutoDownloads.UI;
namespace MyDownloader.Spider.UI
{
public partial class StartAutoDownloadsForm : Form
{
public StartAutoDownloadsForm()
{
InitializeComponent();
}
public ScheduledDownloadEnabler ScheduledDownloadEnabler
{
get
{
return scheduledDownloadEnabler1;
}
}
}
}
MyDownloader.Spider/UI/StartAutoDownloadsForm.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
MyDownloader.Spider/UI/WebSpider.Designer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
using MyDownloader.Core.UI;
using MyDownloader.App.UI;
namespace MyDownloader.Spider.UI
{
partial class WebSpider
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.btnDownloadSite = new System.Windows.Forms.Button();
this.btnAbort = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label5 = new System.Windows.Forms.Label();
this.lblTotalFiles = new System.Windows.Forms.Label();
this.lblDownloadedFiles = new System.Windows.Forms.Label();
this.progDownload = new System.Windows.Forms.ProgressBar();
this.tabParams = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.chkResourcesFromExternal = new System.Windows.Forms.CheckBox();
this.chkImagesFromExternal = new System.Windows.Forms.CheckBox();
this.location1 = new MyDownloader.App.UI.Location();
this.numDownloadDepth = new System.Windows.Forms.NumericUpDown();
this.label6 = new System.Windows.Forms.Label();
this.chkRemoveCompleted = new System.Windows.Forms.CheckBox();
this.folderBrowser1 = new MyDownloader.Core.UI.DownloadFolder();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtExcludeExt = new System.Windows.Forms.TextBox();
this.chkExcludeExtensions = new System.Windows.Forms.CheckBox();
this.txtExcludeNames = new System.Windows.Forms.TextBox();
this.chkExcludeNames = new System.Windows.Forms.CheckBox();
this.tmrRefresh = new System.Windows.Forms.Timer(this.components);
this.waitControl1 = new MyDownloader.Core.UI.WaitControl();
this.tableLayoutPanel1.SuspendLayout();
this.tabParams.SuspendLayout();
this.tabPage1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numDownloadDepth)).BeginInit();
this.tabPage2.SuspendLayout();
this.SuspendLayout();
//
// btnDownloadSite
//
this.btnDownloadSite.Location = new System.Drawing.Point(0, 222);
this.btnDownloadSite.Name = "btnDownloadSite";
this.btnDownloadSite.Size = new System.Drawing.Size(115, 23);
this.btnDownloadSite.TabIndex = 1;
this.btnDownloadSite.Text = "Download Site";
this.btnDownloadSite.UseVisualStyleBackColor = true;
this.btnDownloadSite.Click += new System.EventHandler(this.btnDownloadSite_Click);
//
// btnAbort
//
this.btnAbort.Location = new System.Drawing.Point(121, 222);
this.btnAbort.Name = "btnAbort";
this.btnAbort.Size = new System.Drawing.Size(75, 23);
this.btnAbort.TabIndex = 2;
this.btnAbort.Text = "Abort";
this.btnAbort.UseVisualStyleBackColor = true;
this.btnAbort.Click += new System.EventHandler(this.btnAbort_Click);
//
// label1
//
this.label1.AutoEllipsis = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(3, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(133, 18);
this.label1.TabIndex = 0;
this.label1.Text = "Downloaded files:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label2
//
this.label2.AutoEllipsis = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(3, 18);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(133, 18);
this.label2.TabIndex = 2;
this.label2.Text = "Total files:";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 70F));
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.lblTotalFiles, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.lblDownloadedFiles, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.progDownload, 1, 2);
this.tableLayoutPanel1.Location = new System.Drawing.Point(2, 248);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(466, 56);
this.tableLayoutPanel1.TabIndex = 4;
//
// label5
//
this.label5.AutoEllipsis = true;
this.label5.Dock = System.Windows.Forms.DockStyle.Fill;
this.label5.Location = new System.Drawing.Point(3, 36);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(133, 20);
this.label5.TabIndex = 4;
this.label5.Text = "Progress:";
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblTotalFiles
//
this.lblTotalFiles.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblTotalFiles.Location = new System.Drawing.Point(142, 18);
this.lblTotalFiles.Name = "lblTotalFiles";
this.lblTotalFiles.Size = new System.Drawing.Size(321, 18);
this.lblTotalFiles.TabIndex = 3;
this.lblTotalFiles.Text = "0";
this.lblTotalFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblDownloadedFiles
//
this.lblDownloadedFiles.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblDownloadedFiles.Location = new System.Drawing.Point(142, 0);
this.lblDownloadedFiles.Name = "lblDownloadedFiles";
this.lblDownloadedFiles.Size = new System.Drawing.Size(321, 18);
this.lblDownloadedFiles.TabIndex = 1;
this.lblDownloadedFiles.Text = "0";
this.lblDownloadedFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// progDownload
//
this.progDownload.Dock = System.Windows.Forms.DockStyle.Fill;
this.progDownload.Location = new System.Drawing.Point(142, 39);
this.progDownload.Name = "progDownload";
this.progDownload.Size = new System.Drawing.Size(321, 14);
this.progDownload.TabIndex = 5;
this.progDownload.Value = 50;
//
// tabParams
//
this.tabParams.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabParams.Controls.Add(this.tabPage1);
this.tabParams.Controls.Add(this.tabPage2);
this.tabParams.Location = new System.Drawing.Point(0, 1);
this.tabParams.Name = "tabParams";
this.tabParams.SelectedIndex = 0;
this.tabParams.Size = new System.Drawing.Size(467, 215);
this.tabParams.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.AutoScroll = true;
this.tabPage1.Controls.Add(this.chkResourcesFromExternal);
this.tabPage1.Controls.Add(this.chkImagesFromExternal);
this.tabPage1.Controls.Add(this.location1);
this.tabPage1.Controls.Add(this.numDownloadDepth);
this.tabPage1.Controls.Add(this.label6);
this.tabPage1.Controls.Add(this.chkRemoveCompleted);
this.tabPage1.Controls.Add(this.folderBrowser1);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(459, 189);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Parameters";
this.tabPage1.UseVisualStyleBackColor = true;
//
// chkResourcesFromExternal
//
this.chkResourcesFromExternal.AutoSize = true;
this.chkResourcesFromExternal.Location = new System.Drawing.Point(0, 168);
this.chkResourcesFromExternal.Name = "chkResourcesFromExternal";
this.chkResourcesFromExternal.Size = new System.Drawing.Size(210, 17);
this.chkResourcesFromExternal.TabIndex = 4;
this.chkResourcesFromExternal.Text = "Download resources from external sites";
this.chkResourcesFromExternal.UseVisualStyleBackColor = true;
//
// chkImagesFromExternal
//
this.chkImagesFromExternal.AutoSize = true;
this.chkImagesFromExternal.Location = new System.Drawing.Point(0, 152);
this.chkImagesFromExternal.Name = "chkImagesFromExternal";
this.chkImagesFromExternal.Size = new System.Drawing.Size(197, 17);
this.chkImagesFromExternal.TabIndex = 3;
this.chkImagesFromExternal.Text = "Download images from external sites";
this.chkImagesFromExternal.UseVisualStyleBackColor = true;
//
// location1
//
this.location1.Dock = System.Windows.Forms.DockStyle.Top;
this.location1.Location = new System.Drawing.Point(3, 45);
this.location1.Name = "location1";
this.location1.Size = new System.Drawing.Size(453, 91);
this.location1.TabIndex = 1;
this.location1.UrlLabelTitle = "URL";
//
// numDownloadDepth
//
this.numDownloadDepth.Location = new System.Drawing.Point(288, 152);
this.numDownloadDepth.Name = "numDownloadDepth";
this.numDownloadDepth.Size = new System.Drawing.Size(120, 20);
this.numDownloadDepth.TabIndex = 6;
this.numDownloadDepth.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(288, 136);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(151, 13);
this.label6.TabIndex = 5;
this.label6.Text = "Download depth (0 for infinite):";
//
// chkRemoveCompleted
//
this.chkRemoveCompleted.AutoSize = true;
this.chkRemoveCompleted.Location = new System.Drawing.Point(0, 136);
this.chkRemoveCompleted.Name = "chkRemoveCompleted";
this.chkRemoveCompleted.Size = new System.Drawing.Size(210, 17);
this.chkRemoveCompleted.TabIndex = 2;
this.chkRemoveCompleted.Text = "Remove completed downloads from list";
this.chkRemoveCompleted.UseVisualStyleBackColor = true;
//
// folderBrowser1
//
this.folderBrowser1.Dock = System.Windows.Forms.DockStyle.Top;
this.folderBrowser1.LabelText = "Save to:";
this.folderBrowser1.Location = new System.Drawing.Point(3, 3);
this.folderBrowser1.Name = "folderBrowser1";
this.folderBrowser1.Size = new System.Drawing.Size(453, 42);
this.folderBrowser1.TabIndex = 0;
//
// tabPage2
//
this.tabPage2.AutoScroll = true;
this.tabPage2.AutoScrollMargin = new System.Drawing.Size(0, 8);
this.tabPage2.Controls.Add(this.txtExcludeExt);
this.tabPage2.Controls.Add(this.chkExcludeExtensions);
this.tabPage2.Controls.Add(this.txtExcludeNames);
this.tabPage2.Controls.Add(this.chkExcludeNames);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(459, 189);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Advanced";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtExcludeExt
//
this.txtExcludeExt.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtExcludeExt.Enabled = false;
this.txtExcludeExt.Location = new System.Drawing.Point(8, 64);
this.txtExcludeExt.Name = "txtExcludeExt";
this.txtExcludeExt.Size = new System.Drawing.Size(422, 20);
this.txtExcludeExt.TabIndex = 3;
//
// chkExcludeExtensions
//
this.chkExcludeExtensions.AutoSize = true;
this.chkExcludeExtensions.Location = new System.Drawing.Point(8, 48);
this.chkExcludeExtensions.Name = "chkExcludeExtensions";
this.chkExcludeExtensions.Size = new System.Drawing.Size(262, 17);
this.chkExcludeExtensions.TabIndex = 2;
this.chkExcludeExtensions.Text = "Exclude files with extension (separated by comma)";
this.chkExcludeExtensions.UseVisualStyleBackColor = true;
this.chkExcludeExtensions.CheckedChanged += new System.EventHandler(this.check_CheckedChanged);
//
// txtExcludeNames
//
this.txtExcludeNames.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtExcludeNames.Enabled = false;
this.txtExcludeNames.Location = new System.Drawing.Point(8, 24);
this.txtExcludeNames.Name = "txtExcludeNames";
this.txtExcludeNames.Size = new System.Drawing.Size(422, 20);
this.txtExcludeNames.TabIndex = 1;
//
// chkExcludeNames
//
this.chkExcludeNames.AutoSize = true;
this.chkExcludeNames.Location = new System.Drawing.Point(8, 8);
this.chkExcludeNames.Name = "chkExcludeNames";
this.chkExcludeNames.Size = new System.Drawing.Size(285, 17);
this.chkExcludeNames.TabIndex = 0;
this.chkExcludeNames.Text = "Exclude files that name contains (separated by comma)";
this.chkExcludeNames.UseVisualStyleBackColor = true;
this.chkExcludeNames.CheckedChanged += new System.EventHandler(this.check_CheckedChanged);
//
// tmrRefresh
//
this.tmrRefresh.Interval = 1500;
this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick);
//
// waitControl1
//
this.waitControl1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.waitControl1.Location = new System.Drawing.Point(200, 224);
this.waitControl1.Name = "waitControl1";
this.waitControl1.Size = new System.Drawing.Size(257, 16);
this.waitControl1.TabIndex = 5;
this.waitControl1.Text = "Downloading site, please wait...";
this.waitControl1.Visible = false;
//
// WebSpider
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.waitControl1);
this.Controls.Add(this.tabParams);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.btnAbort);
this.Controls.Add(this.btnDownloadSite);
this.Name = "WebSpider";
this.Size = new System.Drawing.Size(470, 348);
this.tableLayoutPanel1.ResumeLayout(false);
this.tabParams.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numDownloadDepth)).EndInit();
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnDownloadSite;
private System.Windows.Forms.Button btnAbort;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblTotalFiles;
private System.Windows.Forms.Label label5;
private DownloadFolder folderBrowser1;
private System.Windows.Forms.TabControl tabParams;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.CheckBox chkRemoveCompleted;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.NumericUpDown numDownloadDepth;
private System.Windows.Forms.TextBox txtExcludeNames;
private System.Windows.Forms.CheckBox chkExcludeNames;
private System.Windows.Forms.TextBox txtExcludeExt;
private System.Windows.Forms.CheckBox chkExcludeExtensions;
private System.Windows.Forms.Label lblDownloadedFiles;
private System.Windows.Forms.ProgressBar progDownload;
private Location location1;
private System.Windows.Forms.Timer tmrRefresh;
private System.Windows.Forms.CheckBox chkResourcesFromExternal;
private System.Windows.Forms.CheckBox chkImagesFromExternal;
private WaitControl waitControl1;
}
}
MyDownloader.Spider/UI/WebSpider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyDownloader.Spider.Web.Rules;
using MyDownloader.Core;
using MyDownloader.Extension.AutoDownloads;
using MyDownloader.Core.UI;
using MyDownloader.Spider.Web;
namespace MyDownloader.Spider.UI
{
public partial class WebSpider : UserControl
{
public WebSpider()
{
InitializeComponent();
EnterDownloadMode(false);
UpdateInputBasesOnCheckBoxes();
}
Spider siteSpider;
private void btnDownloadSite_Click(object sender, EventArgs e)
{
ResourceLocation rl = this.location1.ResourceLocation[0];
rl.BindProtocolProviderType();
if (rl.ProtocolProviderType == null)
{
MessageBox.Show("Invalid URL format, please check the location field.",
AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
AutoDownloadsExtension scheduler;
scheduler = (AutoDownloadsExtension)AppManager.Instance.Application.GetExtensionByType(typeof(AutoDownloadsExtension));
if (! scheduler.Active)
{
using (StartAutoDownloadsForm startAd = new StartAutoDownloadsForm())
{
if (startAd.ShowDialog() == DialogResult.Yes)
{
startAd.ScheduledDownloadEnabler.ApplySettings();
}
}
if (!scheduler.Active)
{
return;
}
}
SpiderContext spiderCntx = new SpiderContext(
folderBrowser1.Folder,
rl.URL);
spiderCntx.NamingRules.Add(
new BaseLocationNamingRule(chkImagesFromExternal.Checked, chkResourcesFromExternal.Checked));
if (chkExcludeExtensions.Checked)
{
spiderCntx.NamingRules.Add(new ExcludeExtensionNamingRule(txtExcludeExt.Text.Split(',')));
}
if (chkExcludeNames.Checked)
{
spiderCntx.NamingRules.Add(new ExcludeNameNamingRule(txtExcludeNames.Text.Split(',')));
}
if (numDownloadDepth.Value > 0)
{
spiderCntx.NamingRules.Add(new MaxDepthNamingRule((int)numDownloadDepth.Value));
}
if (chkRemoveCompleted.Checked)
{
spiderCntx.ResourceCompleted += delegate(SpiderContext cntx, ISpiderResource resource)
{
DownloadManager.Instance.ClearEnded();
};
}
siteSpider = new Spider(spiderCntx, new WebSpiderResourceFactory());
siteSpider.Completed += new CompletedEventHandler(siteSpider_Completed);
siteSpider.Aborted += new EventHandler(siteSpider_Aborted);
siteSpider.BeginLookup();
EnterDownloadMode(true);
}
private void EnterDownloadMode(bool downloading)
{
RefreshStatus();
progDownload.Value = 0;
tabParams.Enabled = !downloading;
btnAbort.Enabled = downloading;
btnDownloadSite.Enabled = !downloading;
waitControl1.Visible = downloading;
tmrRefresh.Enabled = downloading;
}
void siteSpider_Aborted(object sender, EventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate() { EnterDownloadMode(false); });
}
void siteSpider_Completed(SpiderContext cntx)
{
this.BeginInvoke((MethodInvoker)delegate() { EnterDownloadMode(false); });
}
private void btnAbort_Click(object sender, EventArgs e)
{
siteSpider.Abort();
}
private void tmrRefresh_Tick(object sender, EventArgs e)
{
RefreshStatus();
}
private void RefreshStatus()
{
float totalVisited;
float totalDownloaded;
if (siteSpider != null)
{
totalVisited = siteSpider.Context.VisitedLocations.Count;
totalDownloaded = siteSpider.Context.CompletedResources.Count;
}
else
{
totalVisited = totalDownloaded = 0;
}
lblTotalFiles.Text = totalVisited.ToString();
lblDownloadedFiles.Text = totalDownloaded.ToString();
try
{
if (totalVisited != 0)
{
progDownload.Value = (int)((totalDownloaded / totalVisited) * 100);
}
else
{
progDownload.Value = 0;
}
}
catch (Exception)
{
}
}
private void check_CheckedChanged(object sender, EventArgs e)
{
UpdateInputBasesOnCheckBoxes();
}
private void UpdateInputBasesOnCheckBoxes()
{
txtExcludeExt.Enabled = chkExcludeExtensions.Checked;
txtExcludeNames.Enabled = chkExcludeNames.Checked;
}
}
}
MyDownloader.Spider/UI/WebSpider.resx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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>
<metadata name="tmrRefresh.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>58</value>
</metadata>
</root>
MyDownloader.Spider/Web/DownloaderAsyncRetrive.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Core;
namespace MyDownloader.Spider.Web
{
class DownloaderAsyncRetrive : IAsyncRetriver
{
Downloader downloader;
ISpiderResource resource;
internal DownloaderAsyncRetrive(ISpiderResource resource, Downloader d)
{
this.downloader = d;
this.resource = resource;
}
#region IAsyncRetrive Members
public ISpiderResource Resource
{
get { return resource; }
}
public bool IsCompleted
{
get { return !downloader.IsWorking() ; }
}
#endregion
}
}
MyDownloader.Spider/Web/Rules/BaseLocationNamingRule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using System.Text;
using MyDownloader.Spider.Parsers.Html;
namespace MyDownloader.Spider.Web.Rules
{
public class BaseLocationNamingRule: INamingRule
{
private bool downloadImagesFromExternalSite;
private bool downloadResourceFromExternalSite;
public BaseLocationNamingRule(
bool downloadImagesFromExternalSite,
bool downloadResourceFromExternalSite)
{
this.downloadImagesFromExternalSite = downloadImagesFromExternalSite;
this.downloadResourceFromExternalSite = downloadResourceFromExternalSite;
}
#region INamingRule Members
public bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider)
{
UrlType urlType = ((WebSpiderResource)parentSpider).addingUrlType;
if (
!(urlType == UrlType.Img && this.downloadImagesFromExternalSite)
&&
!(urlType != UrlType.Img && this.downloadResourceFromExternalSite)
)
{
string tempbase = context.BaseLocation;
int i;
if ((i = tempbase.LastIndexOf("/")) >= 0)
{
tempbase = tempbase.Substring(0, i + 1);
}
if (!location.OriginalString.StartsWith(tempbase))
{
return false;
}
}
return true;
}
#endregion
}
}
MyDownloader.Spider/Web/Rules/ExcludeExtensionNamingRule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MyDownloader.Spider.Web.Rules
{
public class ExcludeExtensionNamingRule: INamingRule
{
string[] extensionsToExclude;
public ExcludeExtensionNamingRule(string[] extensionsToExclude)
{
for (int i = 0; i < extensionsToExclude.Length; i++)
{
extensionsToExclude[i] = extensionsToExclude[i].ToLower();
}
this.extensionsToExclude = extensionsToExclude;
}
#region INamingRule Members
public bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider)
{
string ext = Path.GetExtension(location.Segments[location.Segments.Length-1]).ToLower();
int index = Array.IndexOf<string>(this.extensionsToExclude, ext);
return index < 0;
}
#endregion
}
}
MyDownloader.Spider/Web/Rules/ExcludeNameNamingRule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider.Web.Rules
{
class ExcludeNameNamingRule: INamingRule
{
string[] namesToExclude;
public ExcludeNameNamingRule(string[] namesToExclude)
{
for (int i = 0; i < namesToExclude.Length; i++)
{
namesToExclude[i] = namesToExclude[i].ToLower();
}
this.namesToExclude = namesToExclude;
}
#region INamingRule Members
public bool Accept(Uri uri, SpiderContext context, ISpiderResource parentSpider)
{
string fileName = uri.Segments[uri.Segments.Length - 1];
for (int i = 0; i < namesToExclude.Length; i++)
{
if (fileName.IndexOf(namesToExclude[i]) >= 0)
{
return false;
}
}
return true;
}
#endregion
}
}
MyDownloader.Spider/Web/Rules/MaxDepthNamingRule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider.Web.Rules
{
public class MaxDepthNamingRule: INamingRule
{
private int maxDepth;
public MaxDepthNamingRule(int maxDepth)
{
this.maxDepth = maxDepth;
}
#region INamingRule Members
public bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider)
{
if (this.maxDepth > 0 && parentSpider.Depth >= this.maxDepth)
{
return false;
}
else
{
return true;
}
}
#endregion
}
}
MyDownloader.Spider/Web/WebSpiderResource.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
using System;
using System.Collections.Generic;
using MyDownloader.Core;
using System.IO;
using MyDownloader.Spider.Parsers.Html;
namespace MyDownloader.Spider.Web
{
public class WebSpiderResource : ISpiderResource
{
private string location;
internal UrlType addingUrlType;
private int depth;
private ISpiderResource parent;
private SpiderContext context;
private Downloader download;
private List<ISpiderResource> nextResources = new List<ISpiderResource>();
public WebSpiderResource(SpiderContext context, ISpiderResource parent, string location)
{
this.context = context;
this.location = location;
this.parent = parent;
UpdateDepth();
string localFile = GetLocalFile();
download = DownloadManager.Instance.Add(
ResourceLocation.FromURL(this.Location),
null,
localFile,
1,
false);
download.StateChanged += new EventHandler(download_StateChanged);
}
private void UpdateDepth()
{
if (this.parent == null)
{
this.depth = 0;
}
else
{
ISpiderResource tmpParent = this.parent;
while (tmpParent != null)
{
this.depth++;
tmpParent = tmpParent.ParentResource;
}
}
}
void download_StateChanged(object sender, EventArgs e)
{
switch (download.State)
{
case DownloaderState.Ended:
LoadData();
goto case DownloaderState.EndedWithError;
case DownloaderState.EndedWithError:
context.NotifyCompletion(this);
break;
}
}
private void LoadData()
{
nextResources.Clear();
if (download.RemoteFileInfo.MimeType.IndexOf("text/html", StringComparison.OrdinalIgnoreCase) < 0)
{
return;
}
try
{
DownloadManager.Instance.OnBeginAddBatchDownloads();
using (Stream htmlStream = File.OpenRead(download.LocalFile))
{
using (HtmlParser parser = new HtmlParser(htmlStream))
{
AddUrls(parser.GetHrefs(context.BaseLocation), UrlType.Href);
AddUrls(parser.GetImages(context.BaseLocation), UrlType.Img);
AddUrls(parser.GetFrames(context.BaseLocation), UrlType.Frame);
AddUrls(parser.GetIFrames(context.BaseLocation), UrlType.IFrame);
}
}
}
finally
{
DownloadManager.Instance.OnEndAddBatchDownloads();
}
}
private void AddUrls(IEnumerable<Uri> uris, UrlType type)
{
this.addingUrlType = type;
IEnumerator<Uri> enumUri = uris.GetEnumerator();
while (enumUri.MoveNext())
{
AddUrl(enumUri.Current);
}
}
private void AddUrl(Uri uri)
{
if (this.context.AddURIToVisit(uri, this))
{
System.Diagnostics.Debug.WriteLine(uri.OriginalString);
nextResources.Add(
new WebSpiderResource(this.context, this, uri.OriginalString));
}
}
private string GetLocalFile()
{
Uri uri = new Uri(this.Location);
string dirSep = Path.DirectorySeparatorChar.ToString();
string fileName = String.Concat(uri.Host, string.Join("", uri.Segments));
string dir =
this.context.BaseDirectory +
dirSep +
fileName.Replace("/", dirSep);
if (dir.EndsWith(dirSep))
{
dir += "default.html";
}
return dir;
}
#region ISpiderResource Members
public IAsyncRetriver BeginReceive()
{
download.Start();
return new DownloaderAsyncRetrive(this, download);
}
public void EndReceive()
{
download.WaitForConclusion();
}
public string Location
{
get { return location; }
}
public int Depth
{
get { return this.depth; }
}
public ISpiderResource ParentResource
{
get
{
return this.parent;
}
}
public List<ISpiderResource> NextResources
{
get
{
return this.nextResources;
}
}
#endregion
}
}
MyDownloader.Spider/Web/WebSpiderResourceFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Text;
namespace MyDownloader.Spider.Web
{
public class WebSpiderResourceFactory: ISpiderResourceFactory
{
#region ISpiderResourceFactory Members
public ISpiderResource CreateSpider(SpiderContext cntx, ISpiderResource parent, string location)
{
return new WebSpiderResource(cntx, parent, location);
}
#endregion
}
}
MyDownloader.Tests/Extension/Video/VideoConverterTest.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using MyDownloader.Extension.Video;
namespace MyDownloader.Tests.Extension.Video
{
[TestFixture]
public class VideoConverterTest
{
[Test]
public void ToMp3()
{
VideoConverter.Convert(@"C:\Temp\video.mp3", VideoFormat.MP3);
}
[Test]
public void ToAVI()
{
VideoConverter.Convert(@"C:\Temp\video.avi", VideoFormat.AVI);
}
[Test]
public void ToMPEG()
{
VideoConverter.Convert(@"C:\Temp\video.mpeg", VideoFormat.MPEG);
}
}
}
MyDownloader.Tests/MyDownloader.Tests.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3232779E-E9F4-4D70-9969-F435D98B1A8B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyDownloader.Tests</RootNamespace>
<AssemblyName>MyDownloader.Tests</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extension\Video\VideoConverterTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyDownloader.Core\MyDownloader.Core.csproj">
<Project>{E763345E-6696-4C53-8764-47E4ABD67DEF}</Project>
<Name>MyDownloader.Core</Name>
</ProjectReference>
<ProjectReference Include="..\MyDownloader.Extension\MyDownloader.Extension.csproj">
<Project>{FEA18B6C-491F-401A-A06B-AE47888FF288}</Project>
<Name>MyDownloader.Extension</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
MyDownloader.Tests/Properties/AssemblyInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("MyDownloader.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MyDownloader.Tests")]
[assembly: AssemblyCopyright("Copyright © 2007")]
[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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("658581b3-e94e-48f5-88d1-0fec8502245d")]
// 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 Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
MyDownloader.sln
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.App", "MyDownloader.App\MyDownloader.App.csproj", "{18AE3994-8F48-49B1-AC63-342F70ED1135}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.Core", "MyDownloader.Core\MyDownloader.Core.csproj", "{E763345E-6696-4C53-8764-47E4ABD67DEF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.Extension", "MyDownloader.Extension\MyDownloader.Extension.csproj", "{FEA18B6C-491F-401A-A06B-AE47888FF288}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.Spider", "MyDownloader.Spider\MyDownloader.Spider.csproj", "{69C99442-953E-4559-96D3-C82CC57A3C87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.IEPlugin", "MyDownloader.IEPlugin\MyDownloader.IEPlugin.csproj", "{91BB212C-D158-4B83-A3BC-1A41BBDC8463}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{18AE3994-8F48-49B1-AC63-342F70ED1135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18AE3994-8F48-49B1-AC63-342F70ED1135}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18AE3994-8F48-49B1-AC63-342F70ED1135}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18AE3994-8F48-49B1-AC63-342F70ED1135}.Release|Any CPU.Build.0 = Release|Any CPU
{E763345E-6696-4C53-8764-47E4ABD67DEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E763345E-6696-4C53-8764-47E4ABD67DEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E763345E-6696-4C53-8764-47E4ABD67DEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E763345E-6696-4C53-8764-47E4ABD67DEF}.Release|Any CPU.Build.0 = Release|Any CPU
{FEA18B6C-491F-401A-A06B-AE47888FF288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FEA18B6C-491F-401A-A06B-AE47888FF288}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FEA18B6C-491F-401A-A06B-AE47888FF288}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FEA18B6C-491F-401A-A06B-AE47888FF288}.Release|Any CPU.Build.0 = Release|Any CPU
{69C99442-953E-4559-96D3-C82CC57A3C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69C99442-953E-4559-96D3-C82CC57A3C87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69C99442-953E-4559-96D3-C82CC57A3C87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69C99442-953E-4559-96D3-C82CC57A3C87}.Release|Any CPU.Build.0 = Release|Any CPU
{91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
installer.iss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[Setup]
AppName=.Net Download Manager
AppVersion=1.3
LicenseFile=MyDownloader.App\bin\Release\License.txt
AppPublisher=Nathan Adams
AppPublisherURL=http://code.google.com/u/112375326098483542471/
DefaultDirName={pf}\.Net Download Manager
AppReadmeFile=MyDownloader.App\bin\Release\readme.txt
InfoBeforeFile=MyDownloader.App\bin\Release\readme.txt
DefaultGroupName=.Net Download Manager
[Files]
Source: "MyDownloader.App\bin\Release\ICSharpCode.SharpZipLib.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\MyDownloader.App.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\MyDownloader.Core.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\MyDownloader.Extension.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\MyDownloader.Spider.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\TabStrip.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\INIFileParser.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "MyDownloader.App\bin\Release\System.Data.SQLite.dll"; DestDir: "{app}"; Flags: ignoreversion
[ThirdParty]
UseRelativePaths=True
[Icons]
Name: "{userstartmenu}\.Net Download Manager\Uninstall DNDM"; Filename: "{uninstallexe}"
Name: "{userstartmenu}\.Net Download Manager\.Net Download Manager"; Filename: "{app}\MyDownloader.App.exe"

Archive Download the corresponding diff file

Branches

Tags

Page rendered in 2.40754s using 14 queries.