├── .gitattributes
├── .gitignore
├── App.config
├── Enterprise_Solution.ico
├── LICENSE
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── MessageBoxEx.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── README.md
├── Visual-Studio-Downloader.csproj
├── Visual-Studio-Downloader.sln
└── VisualStudioDownloader.JPG
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Enterprise_Solution.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnterpriseSolution/Visual-Studio-Downloader/644ac1f21afe925c33d6147db475079f5e332266/Enterprise_Solution.ico
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Raymond
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | using VisualStudioDownloader.Properties;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Diagnostics;
7 | using System.Drawing;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Net;
11 | using System.Runtime.CompilerServices;
12 | using System.Threading;
13 | using System.Windows.Forms;
14 | using System.Xml;
15 |
16 | namespace VisualStudioDownloader
17 | {
18 | partial class MainForm
19 | {
20 | ///
21 | /// Required designer variable.
22 | ///
23 | private System.ComponentModel.IContainer components = null;
24 |
25 | ///
26 | /// Clean up any resources being used.
27 | ///
28 | /// true if managed resources should be disposed; otherwise, false.
29 | protected override void Dispose(bool disposing)
30 | {
31 | if (disposing && (components != null))
32 | {
33 | components.Dispose();
34 | }
35 | base.Dispose(disposing);
36 | }
37 |
38 | #region Windows Form Designer generated code
39 |
40 | ///
41 | /// Required method for Designer support - do not modify
42 | /// the contents of this method with the code editor.
43 | ///
44 | private void InitializeComponent()
45 | {
46 | this.SuspendLayout();
47 |
48 | System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Visual Studio 核心编辑器");
49 | System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Azure 开发");
50 | System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("数据存储和处理");
51 | System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("数据科学和分析应用程序");
52 | System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode(".NET 桌面开发");
53 | System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("使用 Unity 的游戏开发");
54 | System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("使用 C++ 的 Linux 开发");
55 | System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("使用 C++ 的桌面开发");
56 | System.Windows.Forms.TreeNode treeNode9 = new System.Windows.Forms.TreeNode("使用 C++ 的游戏开发");
57 | System.Windows.Forms.TreeNode treeNode10 = new System.Windows.Forms.TreeNode("使用 C++ 的移动开发");
58 | System.Windows.Forms.TreeNode treeNode11 = new System.Windows.Forms.TreeNode(".NET Core 跨平台开发");
59 | System.Windows.Forms.TreeNode treeNode12 = new System.Windows.Forms.TreeNode("使用 .NET 的移动开发");
60 | System.Windows.Forms.TreeNode treeNode13 = new System.Windows.Forms.TreeNode("ASP.NET 和 Web 开发");
61 | System.Windows.Forms.TreeNode treeNode14 = new System.Windows.Forms.TreeNode("Node.js 开发");
62 | System.Windows.Forms.TreeNode treeNode15 = new System.Windows.Forms.TreeNode("Office/SharePoint 开发");
63 | System.Windows.Forms.TreeNode treeNode16 = new System.Windows.Forms.TreeNode("Python 开发");
64 | System.Windows.Forms.TreeNode treeNode17 = new System.Windows.Forms.TreeNode("通用 Windows 平台开发");
65 | System.Windows.Forms.TreeNode treeNode18 = new System.Windows.Forms.TreeNode("Visual Studio 扩展开发");
66 | System.Windows.Forms.TreeNode treeNode19 = new System.Windows.Forms.TreeNode("使用 JavaScript 的移动开发");
67 | System.Windows.Forms.TreeNode treeNode20 = new System.Windows.Forms.TreeNode("独立组件");
68 | this.label1 = new System.Windows.Forms.Label();
69 | this.label2 = new System.Windows.Forms.Label();
70 | this.txtSaveDirectory = new System.Windows.Forms.TextBox();
71 | this.btnSelectDir = new System.Windows.Forms.Button();
72 | this.cbxVersion = new System.Windows.Forms.ComboBox();
73 | this.btnDown = new System.Windows.Forms.Button();
74 | this.txtcmdLogTextArea = new System.Windows.Forms.TextBox();
75 | this.treeViewWorkload = new System.Windows.Forms.TreeView();
76 | this.btnBuild = new System.Windows.Forms.Button();
77 | this.cbxLanguage = new System.Windows.Forms.ComboBox();
78 | this.label3 = new System.Windows.Forms.Label();
79 | this.SuspendLayout();
80 | //
81 | // label1
82 | //
83 | this.label1.AutoSize = true;
84 | this.label1.Location = new System.Drawing.Point(12, 10);
85 | this.label1.Name = "label1";
86 | this.label1.Size = new System.Drawing.Size(54, 13);
87 | this.label1.TabIndex = 0;
88 | this.label1.Text = "Version:";
89 | //
90 | // label2
91 | //
92 | this.label2.AutoSize = true;
93 | this.label2.Location = new System.Drawing.Point(12, 40);
94 | this.label2.Name = "label2";
95 | this.label2.Size = new System.Drawing.Size(61, 13);
96 | this.label2.TabIndex = 1;
97 | this.label2.Text = "Directory:";
98 | //
99 | // txtSaveDirectory
100 | //
101 | this.txtSaveDirectory.Enabled = false;
102 | this.txtSaveDirectory.Location = new System.Drawing.Point(83, 37);
103 | this.txtSaveDirectory.Name = "txtSaveDirectory";
104 | this.txtSaveDirectory.Size = new System.Drawing.Size(330, 20);
105 | this.txtSaveDirectory.TabIndex = 2;
106 | //
107 | // btnSelectDir
108 | //
109 | this.btnSelectDir.Location = new System.Drawing.Point(419, 35);
110 | this.btnSelectDir.Name = "btnSelectDir";
111 | this.btnSelectDir.Size = new System.Drawing.Size(31, 25);
112 | this.btnSelectDir.TabIndex = 3;
113 | this.btnSelectDir.Text = "...";
114 | this.btnSelectDir.UseVisualStyleBackColor = true;
115 | this.btnSelectDir.Click += new System.EventHandler(this.btnSelectDir_Click);
116 | //
117 | // cbxVersion
118 | //
119 | this.cbxVersion.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
120 | this.cbxVersion.FormattingEnabled = true;
121 | this.cbxVersion.Items.AddRange(new object[] {
122 | "Visual Studio Community 2022",
123 | "Visual Studio Professional 2022",
124 | "Visual Studio Enterprise 2022"});
125 | this.cbxVersion.Location = new System.Drawing.Point(83, 10);
126 | this.cbxVersion.Name = "cbxVersion";
127 | this.cbxVersion.Size = new System.Drawing.Size(330, 21);
128 | this.cbxVersion.TabIndex = 4;
129 | //
130 | // btnDown
131 | //
132 | this.btnDown.Location = new System.Drawing.Point(419, 153);
133 | this.btnDown.Name = "btnDown";
134 | this.btnDown.Size = new System.Drawing.Size(80, 25);
135 | this.btnDown.TabIndex = 6;
136 | this.btnDown.Text = "Start";
137 | this.btnDown.UseVisualStyleBackColor = true;
138 | this.btnDown.Click += new System.EventHandler(this.btnDown_Click);
139 | //
140 | // txtcmdLogTextArea
141 | //
142 | this.txtcmdLogTextArea.Location = new System.Drawing.Point(11, 121);
143 | this.txtcmdLogTextArea.Multiline = true;
144 | this.txtcmdLogTextArea.Name = "txtcmdLogTextArea";
145 | this.txtcmdLogTextArea.Size = new System.Drawing.Size(399, 110);
146 | this.txtcmdLogTextArea.TabIndex = 8;
147 | //
148 | // treeViewWorkload
149 | //
150 | this.treeViewWorkload.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
151 | | System.Windows.Forms.AnchorStyles.Left)
152 | | System.Windows.Forms.AnchorStyles.Right)));
153 | this.treeViewWorkload.CheckBoxes = true;
154 | this.treeViewWorkload.Location = new System.Drawing.Point(14, 244);
155 | this.treeViewWorkload.Name = "treeViewWorkload";
156 | treeNode1.Name = "CoreEditor";
157 | treeNode1.Text = "Visual Studio 核心编辑器";
158 | treeNode1.ToolTipText = "Visual Studio 核心 shell 体验,包括语法感知代码编辑、源代码管理和工作项管理。";
159 | treeNode2.Name = "Azure";
160 | treeNode2.Text = "Azure 开发";
161 | treeNode2.ToolTipText = "用于开发云应用、创建资源以及生成包括 Docker 支持的容器的 Azure SDK、工具和项目。";
162 | treeNode3.Name = "Data";
163 | treeNode3.Text = "数据存储和处理";
164 | treeNode3.ToolTipText = "使用 SQL Server、Azure Data Lake 或 Hadoop 连接、开发和测试数据解决方案。";
165 | treeNode4.Name = "DataScience";
166 | treeNode4.Text = "数据科学和分析应用程序";
167 | treeNode4.ToolTipText = "用于创建数据科学应用程序的语言和工具(包括 Python、R 和 F#)。";
168 | treeNode5.Name = "ManagedDesktop";
169 | treeNode5.Text = ".NET 桌面开发";
170 | treeNode5.ToolTipText = "使用 C#、Visual Basic 和 F# 生成 WPF、Windows 窗体和控制台应用程序。";
171 | treeNode6.Name = "ManagedGame";
172 | treeNode6.Text = "使用 Unity 的游戏开发";
173 | treeNode6.ToolTipText = "使用 Unity(功能强大的跨平台开发环境)创建 2D 和 3D 游戏。";
174 | treeNode7.Name = "NativeCrossPlat";
175 | treeNode7.Text = "使用 C++ 的 Linux 开发";
176 | treeNode7.ToolTipText = "创建和调试在 Linux 环境中运行的应用程序。";
177 | treeNode8.Name = "NativeDesktop";
178 | treeNode8.Text = "使用 C++ 的桌面开发";
179 | treeNode8.ToolTipText = "使用 Microsoft C++ 工具集、ATL 或 MFC 生成 Windows 桌面应用程序。";
180 | treeNode9.Name = "NativeGame";
181 | treeNode9.Text = "使用 C++ 的游戏开发";
182 | treeNode9.ToolTipText = "以 DirectX、Unreal 或 Cocos2d 为后盾,利用 C++ 的强大功能生成专业游戏。";
183 | treeNode10.Name = "NativeMobile";
184 | treeNode10.Text = "使用 C++ 的移动开发";
185 | treeNode10.ToolTipText = "使用 C++ 生成适用于 iOS、Android 或 Windows 的跨平台应用程序。";
186 | treeNode11.Name = "NetCoreTools";
187 | treeNode11.Text = ".NET Core 跨平台开发";
188 | treeNode11.ToolTipText = "使用 .NET Core、ASP.NET Core、HTML/JavaScript 和包括 Docker 支持的容器生成跨平台应用程序。";
189 | treeNode12.Name = "NetCrossPlat";
190 | treeNode12.Text = "使用 .NET 的移动开发";
191 | treeNode12.ToolTipText = "使用 Xmarin 生成适用于 iOS、Android 或 Windows 的跨平台应用程序。";
192 | treeNode13.Name = "NetWeb";
193 | treeNode13.Text = "ASP.NET 和 Web 开发";
194 | treeNode13.ToolTipText = "使用 ASP.NET、ASP.NET Core、HTML/JavaScript 和包括 Docker 支持的容器生成 Web 应用程序。";
195 | treeNode14.Name = "Node";
196 | treeNode14.Text = "Node.js 开发";
197 | treeNode14.ToolTipText = "使用 Node.js(事件驱动的异步 JavaScript 运行时)生成可扩展的网络应用程序。";
198 | treeNode15.Name = "Office";
199 | treeNode15.Text = "Office/SharePoint 开发";
200 | treeNode15.ToolTipText = "使用 C#、VB 和 JavaScript 创建 Office 和 SharePoint 外接程序、SharePoint 解决方案和 VSTO 外接程序。";
201 | treeNode16.Name = "Python";
202 | treeNode16.Text = "Python 开发";
203 | treeNode16.ToolTipText = "适用于 Python 的编辑、调试、交互式开发和源代码管理。";
204 | treeNode17.Name = "Universal";
205 | treeNode17.Text = "通用 Windows 平台开发";
206 | treeNode17.ToolTipText = "使用 C#、VB 和 JavaScript 或 C++(可选)创建适用于通用 Windows 平台的应用程序。";
207 | treeNode18.Name = "VisualStudioExtension";
208 | treeNode18.Text = "Visual Studio 扩展开发";
209 | treeNode18.ToolTipText = "创建适用于 Visual Studio 的加载项和扩展,包括新命令、代码分析器和工具窗口。";
210 | treeNode19.Name = "WebCrossPlat";
211 | treeNode19.Text = "使用 JavaScript 的移动开发";
212 | treeNode19.ToolTipText = "使用用于 Apache Cordova 的工具生成 Android、iOS 和 UWP 应用。";
213 | treeNode20.Name = "Others";
214 | treeNode20.Text = "独立组件";
215 | treeNode20.ToolTipText = "这些组件不随附于任何工作负载,但可选择作为单个组件。";
216 | this.treeViewWorkload.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
217 | treeNode1,
218 | treeNode2,
219 | treeNode3,
220 | treeNode4,
221 | treeNode5,
222 | treeNode6,
223 | treeNode7,
224 | treeNode8,
225 | treeNode9,
226 | treeNode10,
227 | treeNode11,
228 | treeNode12,
229 | treeNode13,
230 | treeNode14,
231 | treeNode15,
232 | treeNode16,
233 | treeNode17,
234 | treeNode18,
235 | treeNode19,
236 | treeNode20});
237 | this.treeViewWorkload.ShowNodeToolTips = true;
238 | this.treeViewWorkload.Size = new System.Drawing.Size(488, 420);
239 | this.treeViewWorkload.TabIndex = 9;
240 | this.treeViewWorkload.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeViewWorkload_NodeMouseClick);
241 | //
242 | // btnBuild
243 | //
244 | this.btnBuild.Location = new System.Drawing.Point(419, 121);
245 | this.btnBuild.Name = "btnBuild";
246 | this.btnBuild.Size = new System.Drawing.Size(80, 25);
247 | this.btnBuild.TabIndex = 6;
248 | this.btnBuild.Text = "Initiate";
249 | this.btnBuild.UseVisualStyleBackColor = true;
250 | this.btnBuild.Click += new System.EventHandler(this.btnBuild_Click);
251 | //
252 | // cbxLanguage
253 | //
254 | this.cbxLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
255 | this.cbxLanguage.FormattingEnabled = true;
256 | this.cbxLanguage.Location = new System.Drawing.Point(83, 63);
257 | this.cbxLanguage.Name = "cbxLanguage";
258 | this.cbxLanguage.Size = new System.Drawing.Size(330, 21);
259 | this.cbxLanguage.TabIndex = 11;
260 | //
261 | // label3
262 | //
263 | this.label3.AutoSize = true;
264 | this.label3.Location = new System.Drawing.Point(12, 66);
265 | this.label3.Name = "label3";
266 | this.label3.Size = new System.Drawing.Size(67, 13);
267 | this.label3.TabIndex = 10;
268 | this.label3.Text = "Language:";
269 | //
270 | // MainForm
271 | //
272 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
273 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
274 | this.ClientSize = new System.Drawing.Size(514, 676);
275 | this.Controls.Add(this.cbxLanguage);
276 | this.Controls.Add(this.label3);
277 | this.Controls.Add(this.treeViewWorkload);
278 | this.Controls.Add(this.txtcmdLogTextArea);
279 | this.Controls.Add(this.btnBuild);
280 | this.Controls.Add(this.btnDown);
281 | this.Controls.Add(this.cbxVersion);
282 | this.Controls.Add(this.btnSelectDir);
283 | this.Controls.Add(this.txtSaveDirectory);
284 | this.Controls.Add(this.label2);
285 | this.Controls.Add(this.label1);
286 | this.MaximizeBox = false;
287 | this.Name = "MainForm";
288 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
289 | this.Text = "Visual Studio Downloader";
290 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
291 | this.Shown += new System.EventHandler(this.MainForm_Shown);
292 | this.ResumeLayout(false);
293 | this.PerformLayout();
294 |
295 | }
296 |
297 | #endregion
298 |
299 | private void InitTreeComponent()
300 | {
301 | DicNode item = new DicNode();
302 | item.Name = "CoreEditor";
303 | item.Text = "Visual Studio 核心编辑器";
304 | item.Tooltip = "Visual Studio 核心 shell 体验,包括语法感知代码编辑、源代码管理和工作项管理。";
305 | item.Ischecked = true;
306 | List list1 = new List();
307 | list1.Add(item);
308 | DicNode node2 = new DicNode();
309 | node2.Name = "Azure";
310 | node2.Text = "Azure 开发";
311 | node2.Tooltip = "用于开发云应用、创建资源以及生成包括 Docker 支持的容器的 Azure SDK、工具和项目。";
312 | list1.Add(node2);
313 | DicNode node3 = new DicNode();
314 | node3.Name = "Data";
315 | node3.Text = "数据存储和处理";
316 | node3.Tooltip = "使用 SQL Server、Azure Data Lake 或 Hadoop 连接、开发和测试数据解决方案。";
317 | list1.Add(node3);
318 | DicNode node4 = new DicNode();
319 | node4.Name = "DataScience";
320 | node4.Text = "数据科学和分析应用程序";
321 | node4.Tooltip = "用于创建数据科学应用程序的语言和工具(包括 Python、R 和 F#)。";
322 | list1.Add(node4);
323 | DicNode node5 = new DicNode();
324 | node5.Name = "ManagedDesktop";
325 | node5.Text = ".NET 桌面开发";
326 | node5.Tooltip = "使用 C#、Visual Basic 和 F# 生成 WPF、Windows 窗体和控制台应用程序。";
327 | list1.Add(node5);
328 | DicNode node6 = new DicNode();
329 | node6.Name = "ManagedGame";
330 | node6.Text = "使用 Unity 的游戏开发";
331 | node6.Tooltip = "使用 Unity(功能强大的跨平台开发环境)创建 2D 和 3D 游戏。";
332 | list1.Add(node6);
333 | DicNode node7 = new DicNode();
334 | node7.Name = "NativeCrossPlat";
335 | node7.Text = "使用 C++ 的 Linux 开发";
336 | node7.Tooltip = "创建和调试在 Linux 环境中运行的应用程序。";
337 | list1.Add(node7);
338 | DicNode node8 = new DicNode();
339 | node8.Name = "NativeDesktop";
340 | node8.Text = "使用 C++ 的桌面开发";
341 | node8.Tooltip = "使用 Microsoft C++ 工具集、ATL 或 MFC 生成 Windows 桌面应用程序。";
342 | list1.Add(node8);
343 | DicNode node9 = new DicNode();
344 | node9.Name = "NativeGame";
345 | node9.Text = "使用 C++ 的游戏开发";
346 | node9.Tooltip = "以 DirectX、Unreal 或 Cocos2d 为后盾,利用 C++ 的强大功能生成专业游戏。";
347 | list1.Add(node9);
348 | DicNode node10 = new DicNode();
349 | node10.Name = "NativeMobile";
350 | node10.Text = "使用 C++ 的移动开发";
351 | node10.Tooltip = "使用 C++ 生成适用于 iOS、Android 或 Windows 的跨平台应用程序。";
352 | list1.Add(node10);
353 | DicNode node11 = new DicNode();
354 | node11.Name = "NetCoreTools";
355 | node11.Text = ".NET Core 跨平台开发";
356 | node11.Tooltip = "使用 .NET Core、ASP.NET Core、HTML/JavaScript 和包括 Docker 支持的容器生成跨平台应用程序。";
357 | list1.Add(node11);
358 | DicNode node12 = new DicNode();
359 | node12.Name = "NetCrossPlat";
360 | node12.Text = "使用 .NET 的移动开发";
361 | node12.Tooltip = "使用 Xmarin 生成适用于 iOS、Android 或 Windows 的跨平台应用程序。";
362 | list1.Add(node12);
363 | DicNode node13 = new DicNode();
364 | node13.Name = "NetWeb";
365 | node13.Text = "ASP.NET 和 Web 开发";
366 | node13.Tooltip = "使用 ASP.NET、ASP.NET Core、HTML/JavaScript 和包括 Docker 支持的容器生成 Web 应用程序。";
367 | list1.Add(node13);
368 | DicNode node14 = new DicNode();
369 | node14.Name = "Node";
370 | node14.Text = "Node.js 开发";
371 | node14.Tooltip = "使用 Node.js(事件驱动的异步 JavaScript 运行时)生成可扩展的网络应用程序。";
372 | list1.Add(node14);
373 | DicNode node15 = new DicNode();
374 | node15.Name = "Office";
375 | node15.Text = "Office/SharePoint 开发";
376 | node15.Tooltip = "使用 C#、VB 和 JavaScript 创建 Office 和 SharePoint 外接程序、SharePoint 解决方案和 VSTO 外接程序。";
377 | list1.Add(node15);
378 | DicNode node16 = new DicNode();
379 | node16.Name = "Python";
380 | node16.Text = "Python 开发";
381 | node16.Tooltip = "适用于 Python 的编辑、调试、交互式开发和源代码管理。";
382 | list1.Add(node16);
383 | DicNode node17 = new DicNode();
384 | node17.Name = "Universal";
385 | node17.Text = "通用 Windows 平台开发";
386 | node17.Tooltip = "使用 C#、VB 和 JavaScript 或 C++(可选)创建适用于通用 Windows 平台的应用程序。";
387 | list1.Add(node17);
388 | DicNode node18 = new DicNode();
389 | node18.Name = "VisualStudioExtension";
390 | node18.Text = "Visual Studio 扩展开发";
391 | node18.Tooltip = "创建适用于 Visual Studio 的加载项和扩展,包括新命令、代码分析器和工具窗口。";
392 | list1.Add(node18);
393 | DicNode node19 = new DicNode();
394 | node19.Name = "WebCrossPlat";
395 | node19.Text = "使用 JavaScript 的移动开发";
396 | node19.Tooltip = "使用用于 Apache Cordova 的工具生成 Android、iOS 和 UWP 应用。";
397 | list1.Add(node19);
398 | DicNode node20 = new DicNode();
399 | node20.Name = "Others";
400 | node20.Text = "独立组件";
401 | node20.Tooltip = "这些组件不随附于任何工作负载,但可选择作为单个组件。";
402 | list1.Add(node20);
403 | this.workloadList = list1;
404 | DicNode node21 = new DicNode();
405 | node21.Parentname = "Others";
406 | node21.Name = "Component.Android.Emulator";
407 | node21.Text = "适用于 Android 的 Visual Studio 仿真程序";
408 | List list2 = new List();
409 | list2.Add(node21);
410 | DicNode node22 = new DicNode();
411 | node22.Parentname = "Others";
412 | node22.Name = "Component.Android.NDK.R11C";
413 | node22.Text = "Android NDK (R11C)";
414 | list2.Add(node22);
415 | DicNode node23 = new DicNode();
416 | node23.Parentname = "Others";
417 | node23.Name = "Component.Android.NDK.R11C_3264";
418 | node23.Text = "Android NDK (R11C)(32 位)";
419 | list2.Add(node23);
420 | DicNode node24 = new DicNode();
421 | node24.Parentname = "Others";
422 | node24.Name = "Component.Android.SDK23";
423 | node24.Text = "Android SDK 安装程序(API 级别 23)(全局安装)";
424 | list2.Add(node24);
425 | DicNode node25 = new DicNode();
426 | node25.Parentname = "Others";
427 | node25.Name = "Component.Android.SDK25";
428 | node25.Text = "Android SDK 安装程序(API 级别 25)";
429 | list2.Add(node25);
430 | DicNode node26 = new DicNode();
431 | node26.Parentname = "Others";
432 | node26.Name = "Component.GitHub.VisualStudio";
433 | node26.Text = "适用于 Visual Studio 的 GitHub 扩展";
434 | list2.Add(node26);
435 | DicNode node27 = new DicNode();
436 | node27.Parentname = "Others";
437 | node27.Name = "Component.Google.Android.Emulator.API23.V2";
438 | node27.Text = "Google Android Emulator(API 级别 23)(全局安装)";
439 | list2.Add(node27);
440 | DicNode node28 = new DicNode();
441 | node28.Parentname = "Others";
442 | node28.Name = "Component.Google.Android.Emulator.API25";
443 | node28.Text = "Google Android Emulator(API 级别 25)";
444 | list2.Add(node28);
445 | DicNode node29 = new DicNode();
446 | node29.Parentname = "Others";
447 | node29.Name = "Microsoft.Component.Blend.SDK.WPF";
448 | node29.Text = "用于 .NET 的 Blend for Visual Studio SDK ";
449 | list2.Add(node29);
450 | DicNode node30 = new DicNode();
451 | node30.Parentname = "Others";
452 | node30.Name = "Microsoft.Component.HelpViewer";
453 | node30.Text = "帮助查看器";
454 | list2.Add(node30);
455 | DicNode node31 = new DicNode();
456 | node31.Parentname = "Others";
457 | node31.Name = "Microsoft.VisualStudio.Component.LinqToSql";
458 | node31.Text = "LINQ to SQL 工具";
459 | list2.Add(node31);
460 | DicNode node32 = new DicNode();
461 | node32.Parentname = "Others";
462 | node32.Name = "Microsoft.VisualStudio.Component.Phone.Emulator Windows";
463 | node32.Text = "10 移动版仿真程序(周年纪念版)";
464 | list2.Add(node32);
465 | DicNode node33 = new DicNode();
466 | node33.Parentname = "Others";
467 | node33.Name = "Microsoft.VisualStudio.Component.Phone.Emulator.15063";
468 | node33.Text = "Windows 10 Mobile 仿真器(创意者更新)";
469 | list2.Add(node33);
470 | DicNode node34 = new DicNode();
471 | node34.Parentname = "Others";
472 | node34.Name = "Microsoft.VisualStudio.Component.Runtime.Node.x86.6.4.0";
473 | node34.Text = "基于 Node.js v6.4.0 (x86) 的组件运行时";
474 | list2.Add(node34);
475 | DicNode node35 = new DicNode();
476 | node35.Parentname = "Others";
477 | node35.Name = "Microsoft.VisualStudio.Component.Runtime.Node.x86.7.4.0";
478 | node35.Text = "基于 Node.js v7.4.0 (x86) 的组件运行时";
479 | list2.Add(node35);
480 | DicNode node36 = new DicNode();
481 | node36.Parentname = "Others";
482 | node36.Name = "Microsoft.VisualStudio.Component.TestTools.CodedUITest";
483 | node36.Text = "编码的 UI 测试";
484 | list2.Add(node36);
485 | DicNode node37 = new DicNode();
486 | node37.Parentname = "Others";
487 | node37.Name = "Microsoft.VisualStudio.Component.TestTools.FeedbackClient";
488 | node37.Text = "Microsoft Feedback Client";
489 | list2.Add(node37);
490 | DicNode node38 = new DicNode();
491 | node38.Parentname = "Others";
492 | node38.Name = "Microsoft.VisualStudio.Component.TestTools.MicrosoftTestManager Microsoft";
493 | node38.Text = "测试管理器";
494 | list2.Add(node38);
495 | DicNode node39 = new DicNode();
496 | node39.Parentname = "Others";
497 | node39.Name = "Microsoft.VisualStudio.Component.TypeScript.2.0";
498 | node39.Text = "TypeScript 2.0 SDK";
499 | list2.Add(node39);
500 | DicNode node40 = new DicNode();
501 | node40.Parentname = "Others";
502 | node40.Name = "Microsoft.VisualStudio.Component.TypeScript.2.1";
503 | node40.Text = "TypeScript 2.1 SDK";
504 | list2.Add(node40);
505 | DicNode node41 = new DicNode();
506 | node41.Parentname = "Others";
507 | node41.Name = "Microsoft.VisualStudio.Component.TypeScript.2.2";
508 | node41.Text = "TypeScript 2.2 SDK";
509 | list2.Add(node41);
510 | DicNode node42 = new DicNode();
511 | node42.Parentname = "Others";
512 | node42.Name = "Microsoft.VisualStudio.Component.TypeScript.2.5";
513 | node42.Text = "TypeScript 2.5 SDK";
514 | list2.Add(node42);
515 | DicNode node43 = new DicNode();
516 | node43.Parentname = "Others";
517 | node43.Name = "Microsoft.VisualStudio.Component.TypeScript.2.6";
518 | node43.Text = "TypeScript 2.6 SDK";
519 | list2.Add(node43);
520 | DicNode node44 = new DicNode();
521 | node44.Parentname = "Others";
522 | node44.Name = "Microsoft.VisualStudio.Component.TypeScript.2.7";
523 | node44.Text = "TypeScript 2.7 SDK";
524 | list2.Add(node44);
525 | DicNode node45 = new DicNode();
526 | node45.Parentname = "Others";
527 | node45.Name = "Microsoft.VisualStudio.Component.UWP.VC.ARM64";
528 | node45.Text = "适用于 ARM64 的 C++ 通用 Windows 平台工具";
529 | list2.Add(node45);
530 | DicNode node46 = new DicNode();
531 | node46.Parentname = "Others";
532 | node46.Name = "Microsoft.VisualStudio.Component.VC.ATL.ARM.Spectre";
533 | node46.Text = "带有 Spectre 缓解措施的 Visual C++ ATL for ARM";
534 | list2.Add(node46);
535 | DicNode node47 = new DicNode();
536 | node47.Parentname = "Others";
537 | node47.Name = "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre";
538 | node47.Text = "带有 Spectre 缓解措施的 Visual C++ ATL for ARM64";
539 | list2.Add(node47);
540 | DicNode node48 = new DicNode();
541 | node48.Parentname = "Others";
542 | node48.Name = "Microsoft.VisualStudio.Component.VC.ATL.Spectre";
543 | node48.Text = "带有 Spectre 缓解措施的 Visual C++ ATL (x86/x64)";
544 | list2.Add(node48);
545 | DicNode node49 = new DicNode();
546 | node49.Parentname = "Others";
547 | node49.Name = "Microsoft.VisualStudio.Component.VC.ATLMFC.Spectre";
548 | node49.Text = "带有 Spectre 缓解措施的 Visual C++ MFC for x86/x64";
549 | list2.Add(node49);
550 | DicNode node50 = new DicNode();
551 | node50.Parentname = "Others";
552 | node50.Name = "Microsoft.VisualStudio.Component.VC.ClangC2";
553 | node50.Text = "Clang/C2(实验)";
554 | list2.Add(node50);
555 | DicNode node51 = new DicNode();
556 | node51.Parentname = "Others";
557 | node51.Name = "Microsoft.VisualStudio.Component.VC.MFC.ARM";
558 | node51.Text = "Visual C++ MFC for ARM";
559 | list2.Add(node51);
560 | DicNode node52 = new DicNode();
561 | node52.Parentname = "Others";
562 | node52.Name = "Microsoft.VisualStudio.Component.VC.MFC.ARM.Spectre";
563 | node52.Text = "带有 Spectre 缓解措施的 Visual C++ MFC for ARM";
564 | list2.Add(node52);
565 | DicNode node53 = new DicNode();
566 | node53.Parentname = "Others";
567 | node53.Name = "Microsoft.VisualStudio.Component.VC.MFC.ARM64";
568 | node53.Text = "Visual C++ MFC for ARM64";
569 | list2.Add(node53);
570 | DicNode node54 = new DicNode();
571 | node54.Parentname = "Others";
572 | node54.Name = "Microsoft.VisualStudio.Component.VC.MFC.ARM64.Spectre";
573 | node54.Text = "带有 Spectre 缓解措施的针对 ARM64 的 Visual C++ MFC 支持";
574 | list2.Add(node54);
575 | DicNode node55 = new DicNode();
576 | node55.Parentname = "Others";
577 | node55.Name = "Microsoft.VisualStudio.Component.VC.Runtimes.ARM.Spectre";
578 | node55.Text = "面向 Spectre 的 VC++ 2022 版本 15.7 v14.14 库 (ARM)";
579 | list2.Add(node55);
580 | DicNode node56 = new DicNode();
581 | node56.Parentname = "Others";
582 | node56.Name = "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre";
583 | node56.Text = "面向 Spectre 的 VC++ 2022 版本 15.7 v14.14 库 (ARM64)";
584 | list2.Add(node56);
585 | DicNode node57 = new DicNode();
586 | node57.Parentname = "Others";
587 | node57.Name = "Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre";
588 | node57.Text = "面向 Spectre 的 VC++ 2022 版本 15.7 v14.14 库 (x86 和 x64)";
589 | list2.Add(node57);
590 | DicNode node58 = new DicNode();
591 | node58.Parentname = "Others";
592 | node58.Name = "Microsoft.VisualStudio.Component.VC.Tools.14.11";
593 | node58.Text = "VC++ 2022 版本 15.4 v14.11 工具集";
594 | list2.Add(node58);
595 | DicNode node59 = new DicNode();
596 | node59.Parentname = "Others";
597 | node59.Name = "Microsoft.VisualStudio.Component.VC.Tools.14.12";
598 | node59.Text = "VC++ 2022 版本 15.5 v14.12 工具集";
599 | list2.Add(node59);
600 | DicNode node60 = new DicNode();
601 | node60.Parentname = "Others";
602 | node60.Name = "Microsoft.VisualStudio.Component.VC.Tools.14.13";
603 | node60.Text = "VC++ 2022 版本 15.6 v14.13 工具集";
604 | list2.Add(node60);
605 | DicNode node61 = new DicNode();
606 | node61.Parentname = "Others";
607 | node61.Name = "Microsoft.VisualStudio.Component.VC.Tools.ARM64";
608 | node61.Text = "用于 ARM64 的 Visual C++ 编译器和库";
609 | list2.Add(node61);
610 | DicNode node62 = new DicNode();
611 | node62.Parentname = "Others";
612 | node62.Name = "Microsoft.VisualStudio.Component.Windows10SDK.16299.Desktop.arm";
613 | node62.Text = "适用于桌面 C++ [ARM 和 ARM64] 的 Windows 10 SDK";
614 | list2.Add(node62);
615 | this.componentList = list2;
616 | }
617 |
618 | private List workloadList;
619 | private List componentList;
620 | private Label label1;
621 | private Label label2;
622 | private TextBox txtSaveDirectory;
623 | private Button btnSelectDir;
624 | private ComboBox cbxVersion;
625 | private Button btnDown;
626 | private TextBox txtcmdLogTextArea;
627 | private TreeView treeViewWorkload;
628 | private ComboBox cbxLanguage;
629 | private Label label3;
630 | private Button btnBuild;
631 | }
632 | }
633 |
--------------------------------------------------------------------------------
/MainForm.cs:
--------------------------------------------------------------------------------
1 | using VisualStudioDownloader.Properties;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Diagnostics;
7 | using System.Drawing;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Net;
11 | using System.Runtime.CompilerServices;
12 | using System.Threading;
13 | using System.Windows.Forms;
14 | using System.Xml;
15 |
16 | namespace VisualStudioDownloader
17 | {
18 | public partial class MainForm : Form
19 | {
20 | private string baseFromPath = "https://aka.ms/vs/17/release/";
21 | /*
22 | https://aka.ms/vs/17/release/vs_enterprise.exe
23 |
24 | https://aka.ms/vs/17/release/vs_professional.exe
25 |
26 | https://aka.ms/vs/17/release/vs_community.exe
27 |
28 | */
29 | private const string vs_enterprise =
30 | "https://download.visualstudio.microsoft.com/download/pr/33081bfc-10f1-42d4-8f5a-df6709b8b105/4f370342df52079eafa623d16b50b1349a080722852ace1b98411e73ec8718b2/vs_Enterprise.exe";
31 |
32 | private const string vs_professional =
33 | " https://download.visualstudio.microsoft.com/download/pr/33081bfc-10f1-42d4-8f5a-df6709b8b105/70c749298e15efdf8a3543b74c8dcc4cd30a64cb2187953df43d05e29a5bb183/vs_Professional.exe";
34 |
35 | private const string vs_community =
36 | " https://download.visualstudio.microsoft.com/download/pr/33081bfc-10f1-42d4-8f5a-df6709b8b105/0b11ab6a0bc941b3968f666ac9ae26e257758ae8ae408bbe3118a341ac8816f3/vs_Community.exe";
37 |
38 |
39 | private string baseDownPath = Environment.CurrentDirectory;
40 |
41 | public event DelReadErrOutput ReadErrOutput;
42 |
43 | public event DelReadStdOutput ReadStdOutput;
44 |
45 | public MainForm()
46 | {
47 | InitTreeComponent();
48 | this.InitializeComponent();
49 | this.ReadStdOutput += new DelReadStdOutput(this.ReadStdOutputAction);
50 | this.ReadErrOutput += new DelReadErrOutput(this.ReadErrOutputAction);
51 | }
52 |
53 | private void btnBuild_Click(object sender, EventArgs e)
54 | {
55 | if (cbxVersion.SelectedIndex == -1)
56 | {
57 | MessageBoxEx.Show(this, "请选择程序版本", "提示");
58 | return;
59 | }
60 |
61 | if (txtSaveDirectory.Text.ToString() == "")
62 | {
63 | MessageBoxEx.Show(this, "请选择缓存目录", "提示");
64 | return;
65 | }
66 |
67 | if (!Directory.Exists(txtSaveDirectory.Text.Trim()))
68 | {
69 | MessageBoxEx.Show(this, "缓存目录不存在,请检查后重试", "提示");
70 | return;
71 | }
72 | string remoteFile = string.Empty;
73 |
74 | if (cbxVersion.SelectedIndex == 0)
75 | {
76 | remoteFile = vs_community;
77 | }
78 |
79 | if (cbxVersion.SelectedIndex == 1)
80 | {
81 | remoteFile = vs_professional;
82 | }
83 |
84 | if (cbxVersion.SelectedIndex == 2)
85 | {
86 | remoteFile = vs_enterprise;
87 | }
88 |
89 | string localFile = this.baseDownPath + @"\" + this.GetFileNameByVersionType();
90 |
91 | if (!File.Exists(localFile))
92 | this.DownloadFile(remoteFile, localFile, new Action(this.DownloadProgressChanged),
93 | new Action(this.DownloadFileCompleted));
94 |
95 | List list = (from a in workloadList
96 | where a.Ischecked
97 | select a).ToList();
98 | List list2 = (from a in componentList
99 | where a.Ischecked
100 | select a).ToList();
101 | if (list.Count != 1 || list2.Count != 0 ||
102 | MessageBoxEx.Show("是否确认只安装核心组件?", "提示", MessageBoxButtons.YesNo) != DialogResult.No)
103 | {
104 | string text = "";
105 | foreach (DicNode item in list)
106 | {
107 | if (item.Name == "Others")
108 | {
109 | List second = (from a in componentList
110 | where a.Parentname == "Others"
111 | select a).ToList();
112 | list2 = list2.Concat(second).ToList();
113 | }
114 | else
115 | {
116 | text = text + "--add Microsoft.VisualStudio.Workload." + item.Name + " ";
117 | }
118 | }
119 |
120 | foreach (DicNode item2 in list2)
121 | {
122 | text = text + "--add " + item2.Name + " ";
123 | }
124 |
125 | if (text != "")
126 | {
127 | text += "--includeRecommended ";
128 | }
129 |
130 | var language = cbxLanguage.SelectedItem as LanguageItem;
131 | string text2 = GetFileNameByVersionType() + " --layout " + txtSaveDirectory.Text.Trim() + " " + text +
132 | $" --lang {language.locale}";
133 | txtcmdLogTextArea.Text = text2;
134 | }
135 | }
136 |
137 | private void DownloadFileCompleted()
138 | {
139 | Cursor = Cursors.Default;
140 | }
141 |
142 | private void DownloadProgressChanged(int val)
143 | {
144 | Cursor = Cursors.WaitCursor;
145 | }
146 |
147 | private void btnDown_Click(object sender, EventArgs e)
148 | {
149 | this.RealAction(this.txtcmdLogTextArea.Text);
150 | }
151 |
152 | private void btnSave_ConfigClick()
153 | {
154 | string filename = Application.ExecutablePath + ".config";
155 | XmlDocument xmlDocument = new XmlDocument();
156 | xmlDocument.Load(filename);
157 | string xpath = "configuration/applicationSettings/VisualStudioDownloader.Properties.Settings/setting[@name='Version']/value";
158 | XmlNode xmlNode = xmlDocument.SelectSingleNode(xpath);
159 | if (xmlNode != null && cbxVersion.SelectedIndex > -1)
160 | {
161 | xmlNode.InnerText = cbxVersion.SelectedItem.ToString();
162 | xmlDocument.Save(filename);
163 | }
164 | xpath = "configuration/applicationSettings/VisualStudioDownloader.Properties.Settings/setting[@name='Directory']/value";
165 | xmlNode = xmlDocument.SelectSingleNode(xpath);
166 | if (xmlNode != null)
167 | {
168 | xmlNode.InnerText = txtSaveDirectory.Text.Trim();
169 | xmlDocument.Save(filename);
170 | Settings.Default.Reload();
171 | }
172 | xpath = "configuration/applicationSettings/VisualStudioDownloader.Properties.Settings/setting[@name='Workloads']/value";
173 | xmlNode = xmlDocument.SelectSingleNode(xpath);
174 | if (xmlNode != null)
175 | {
176 | string text = "";
177 | foreach (DicNode item in (from a in workloadList
178 | where a.Ischecked
179 | select a).ToList())
180 | {
181 | if (text != "")
182 | {
183 | text += "|";
184 | }
185 | text += item.Name;
186 | }
187 | xmlNode.InnerText = text;
188 | xmlDocument.Save(filename);
189 | Settings.Default.Reload();
190 | }
191 | xpath = "configuration/applicationSettings/VisualStudioDownloader.Properties.Settings/setting[@name='Components']/value";
192 | xmlNode = xmlDocument.SelectSingleNode(xpath);
193 | if (xmlNode != null)
194 | {
195 | string text = "";
196 | foreach (DicNode item2 in (from a in componentList
197 | where a.Ischecked
198 | select a).ToList())
199 | {
200 | if (text != "")
201 | {
202 | text += "|";
203 | }
204 | text += item2.Name;
205 | }
206 | xmlNode.InnerText = text;
207 | xmlDocument.Save(filename);
208 | Settings.Default.Reload();
209 | }
210 | }
211 |
212 | private void btnSelectDir_Click(object sender, EventArgs e)
213 | {
214 | FolderBrowserDialog dialog = new FolderBrowserDialog {
215 | ShowNewFolderButton = true,
216 | RootFolder = Environment.SpecialFolder.Desktop,
217 | SelectedPath = AppDomain.CurrentDomain.BaseDirectory
218 | };
219 | if (dialog.ShowDialog() == DialogResult.OK)
220 | {
221 | this.txtSaveDirectory.Text = dialog.SelectedPath;
222 | }
223 | }
224 |
225 | private void CmdProcess_Exited(object sender, EventArgs e)
226 | {
227 | }
228 |
229 | private string GetFileNameByVersionType()
230 | {
231 | string str = "";
232 | string str2 = this.cbxVersion.SelectedItem.ToString();
233 | if (str2 == "Visual Studio Community 2022")
234 | {
235 | str = "vs_community.exe";
236 | }
237 | else if (str2 == "Visual Studio Professional 2022")
238 | {
239 | str = "vs_professional.exe";
240 | }
241 | else if (str2 == "Visual Studio Enterprise 2022")
242 | {
243 | str = "vs_enterprise.exe";
244 | }
245 | return str;
246 | }
247 |
248 | private void DownloadFile(string url, string saveFile, Action downloadProgressChanged, Action downloadFileCompleted)
249 | {
250 | WebClient client = new WebClient
251 | {
252 | Proxy = null
253 | };
254 | if (downloadProgressChanged != null)
255 | {
256 | client.DownloadProgressChanged += delegate (object sender, DownloadProgressChangedEventArgs e)
257 | {
258 | object[] args = new object[] { e.ProgressPercentage };
259 | this.Invoke(downloadProgressChanged, args);
260 | };
261 | }
262 | if (downloadFileCompleted != null)
263 | {
264 | client.DownloadFileCompleted += (sender, e) => this.Invoke(downloadFileCompleted);
265 | }
266 | client.DownloadFileAsync(new Uri(url), saveFile);
267 | }
268 |
269 | private void MainForm_Shown(object sender, EventArgs e)
270 | {
271 | InitializeLanguage();
272 |
273 | if (Settings.Default["Version"].ToString() != "")
274 | {
275 | this.cbxVersion.SelectedItem = Settings.Default["Version"].ToString();
276 | }
277 | if (Settings.Default["Directory"].ToString() != "")
278 | {
279 | this.txtSaveDirectory.Text = Settings.Default["Directory"].ToString();
280 | }
281 | string str = "";
282 | string str2 = "";
283 | if (Settings.Default["Workloads"].ToString() != "")
284 | {
285 | str = Settings.Default["Workloads"].ToString();
286 | }
287 | if (Settings.Default["Components"].ToString() != "")
288 | {
289 | str2 = Settings.Default["Components"].ToString();
290 | }
291 |
292 | this.treeViewWorkload.Nodes.Clear();
293 | foreach (DicNode node in this.workloadList)
294 | {
295 | TreeNode node2 = new TreeNode {
296 | Name = node.Name,
297 | Text = node.Text,
298 | ToolTipText = node.Tooltip
299 | };
300 | if (str.IndexOf(node.Name) > -1)
301 | {
302 | node.Ischecked = true;
303 | node2.Checked = true;
304 | }
305 | if (node.Name == "CoreEditor")
306 | {
307 | node2.Checked = true;
308 | }
309 | if (node.Name == "Others")
310 | {
311 | int num = 0;
312 | foreach (DicNode node3 in this.componentList)
313 | {
314 | TreeNode node4 = new TreeNode {
315 | Name = node3.Name,
316 | Text = node3.Text,
317 | ToolTipText = node3.Tooltip
318 | };
319 | node2.Nodes.Add(node4);
320 | if (str2.IndexOf(node3.Name) > -1)
321 | {
322 | node3.Ischecked = true;
323 | node4.Checked = true;
324 | num++;
325 | }
326 | }
327 | if (node2.Nodes.Count != num)
328 | {
329 | node2.Checked = false;
330 | node.Ischecked = false;
331 | }
332 | }
333 | this.treeViewWorkload.Nodes.Add(node2);
334 | }
335 | }
336 |
337 | private void InitializeLanguage()
338 | {
339 | cbxLanguage.Items.Add(new LanguageItem("Cs-cz", "Czech"));
340 | cbxLanguage.Items.Add(new LanguageItem("De-de", "German"));
341 | cbxLanguage.Items.Add(new LanguageItem("En-us", "English"));
342 | cbxLanguage.Items.Add(new LanguageItem("Es-es", "Spanish"));
343 | cbxLanguage.Items.Add(new LanguageItem("Fr-fr", "French"));
344 | cbxLanguage.Items.Add(new LanguageItem("It-it", "Italian"));
345 | cbxLanguage.Items.Add(new LanguageItem("Ja-jp", "Japanese"));
346 | cbxLanguage.Items.Add(new LanguageItem("Ko-kr", "Korean"));
347 | cbxLanguage.Items.Add(new LanguageItem("Pl-pl", "Polish"));
348 | cbxLanguage.Items.Add(new LanguageItem("Pt-br", "Portuguese-Brazil"));
349 | cbxLanguage.Items.Add(new LanguageItem("Ru-ru", "Russian"));
350 | cbxLanguage.Items.Add(new LanguageItem("Tr-tr", "Turkish"));
351 | cbxLanguage.Items.Add(new LanguageItem("Zh-cn", "Chinese-Simplified"));
352 | cbxLanguage.Items.Add(new LanguageItem("Zh-tw", "Chinese-Traditional"));
353 |
354 | cbxLanguage.SelectedIndex = cbxLanguage.Items.Count - 2;
355 | }
356 |
357 | class LanguageItem
358 | {
359 | public LanguageItem(string locale, string description)
360 | {
361 | this.locale = locale;
362 | this.description = description;
363 | }
364 |
365 | public string locale;
366 | public string description;
367 |
368 | public override string ToString()
369 | {
370 | return description;
371 | }
372 | }
373 |
374 | private void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
375 | {
376 | if (e.Data != null)
377 | {
378 | object[] args = new object[] { e.Data };
379 | base.Invoke(this.ReadErrOutput, args);
380 | }
381 | }
382 |
383 | private void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
384 | {
385 | if (e.Data != null)
386 | {
387 | object[] args = new object[] { e.Data };
388 | base.Invoke(this.ReadStdOutput, args);
389 | }
390 | }
391 |
392 | private void ReadErrOutputAction(string result)
393 | {
394 | }
395 |
396 | private void ReadStdOutputAction(string result)
397 | {
398 | this.txtcmdLogTextArea.AppendText(result + "\r\n");
399 | }
400 |
401 | private void RealAction(string StartCmd)
402 | {
403 | Process process1 = new Process();
404 | process1.StartInfo.FileName = "cmd.exe";
405 | process1.StartInfo.WorkingDirectory = ".";
406 | process1.StartInfo.CreateNoWindow = true;
407 | process1.StartInfo.UseShellExecute = false;
408 | process1.StartInfo.RedirectStandardInput = true;
409 | process1.StartInfo.RedirectStandardOutput = true;
410 | process1.StartInfo.RedirectStandardError = true;
411 | process1.OutputDataReceived += new DataReceivedEventHandler(this.p_OutputDataReceived);
412 | process1.ErrorDataReceived += new DataReceivedEventHandler(this.p_ErrorDataReceived);
413 | process1.EnableRaisingEvents = true;
414 | process1.Exited += new EventHandler(this.CmdProcess_Exited);
415 | process1.Start();
416 | process1.StandardInput.WriteLine(StartCmd);
417 | process1.BeginOutputReadLine();
418 | process1.BeginErrorReadLine();
419 | }
420 |
421 | private void treeViewWorkload_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
422 | {
423 | if (e.Node.Name == "CoreEditor")
424 | {
425 | if (!e.Node.Checked)
426 | {
427 | e.Node.Checked = true;
428 | }
429 | }
430 | else
431 | {
432 | IEnumerator enumerator;
433 | if (e.Node.Nodes.Count > 0)
434 | {
435 | foreach (TreeNode nodeNode in e.Node.Nodes)
436 | {
437 | ((TreeNode)nodeNode).Checked = e.Node.Checked;
438 | }
439 | using (List.Enumerator enumerator2 = (from a in this.componentList
440 | where a.Parentname == e.Node.Name
441 | select a).ToList().GetEnumerator())
442 | {
443 | while (enumerator2.MoveNext())
444 | {
445 | enumerator2.Current.Ischecked = e.Node.Checked;
446 | }
447 | }
448 | }
449 | if (e.Node.Parent != null)
450 | {
451 | int count = e.Node.Parent.Nodes.Count;
452 | int num2 = 0;
453 | foreach (TreeNode nodeNode in e.Node.Parent.Nodes)
454 | {
455 | if (!((TreeNode)nodeNode).Checked)
456 | {
457 | continue;
458 | }
459 | num2++;
460 | }
461 | e.Node.Parent.Checked = count == num2;
462 | }
463 | DicNode node = this.workloadList.Find(a => a.Name == e.Node.Name);
464 | if (node != null)
465 | {
466 | node.Ischecked = e.Node.Checked;
467 | }
468 | node = this.componentList.Find(a => a.Name == e.Node.Name);
469 | if (node != null)
470 | {
471 | node.Ischecked = e.Node.Checked;
472 | }
473 | }
474 | }
475 |
476 | private class DicNode
477 | {
478 | private string parentname;
479 | private string name;
480 | private string text;
481 | private string tooltip;
482 | private bool ischecked;
483 |
484 | public string Parentname
485 | {
486 | get =>
487 | this.parentname;
488 | set =>
489 | this.parentname = value;
490 | }
491 |
492 | public string Name
493 | {
494 | get =>
495 | this.name;
496 | set =>
497 | this.name = value;
498 | }
499 |
500 | public string Text
501 | {
502 | get =>
503 | this.text;
504 | set =>
505 | this.text = value;
506 | }
507 |
508 | public string Tooltip
509 | {
510 | get =>
511 | this.tooltip;
512 | set =>
513 | this.tooltip = value;
514 | }
515 |
516 | public bool Ischecked
517 | {
518 | get =>
519 | this.ischecked;
520 | set =>
521 | this.ischecked = value;
522 | }
523 | }
524 |
525 | public delegate string MyDelegate();
526 |
527 | private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
528 | {
529 | btnSave_ConfigClick();
530 | }
531 |
532 | //private void InitializeComponent()
533 | //{
534 | // this.SuspendLayout();
535 | // //
536 | // // MainForm
537 | // //
538 | // this.ClientSize = new System.Drawing.Size(402, 314);
539 | // this.Name = "MainForm";
540 | // this.ResumeLayout(false);
541 |
542 | //}
543 | }
544 | }
545 |
546 |
--------------------------------------------------------------------------------
/MainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/MessageBoxEx.cs:
--------------------------------------------------------------------------------
1 | namespace VisualStudioDownloader
2 | {
3 | using System;
4 | using System.Drawing;
5 | using System.Runtime.CompilerServices;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Windows.Forms;
9 |
10 | public class MessageBoxEx
11 | {
12 | private static IWin32Window _owner;
13 | private static HookProc _hookProc = new HookProc(MessageBoxEx.MessageBoxHookProc);
14 | private static IntPtr _hHook = IntPtr.Zero;
15 | public const int WH_CALLWNDPROCRET = 12;
16 |
17 | [DllImport("user32.dll")]
18 | public static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
19 | private static void CenterWindow(IntPtr hChildWnd)
20 | {
21 | Rectangle lpRect = new Rectangle(0, 0, 0, 0);
22 | GetWindowRect(hChildWnd, ref lpRect);
23 | int nWidth = lpRect.Width - lpRect.X;
24 | int nHeight = lpRect.Height - lpRect.Y;
25 | Rectangle rectangle2 = new Rectangle(0, 0, 0, 0);
26 | GetWindowRect(_owner.Handle, ref rectangle2);
27 | Point point = new Point(0, 0) {
28 | X = rectangle2.X + ((rectangle2.Width - rectangle2.X) / 2),
29 | Y = rectangle2.Y + ((rectangle2.Height - rectangle2.Y) / 2)
30 | };
31 | Point point2 = new Point(0, 0) {
32 | X = point.X - (nWidth / 2),
33 | Y = point.Y - (nHeight / 2)
34 | };
35 | point2.X = (point2.X < 0) ? 0 : point2.X;
36 | point2.Y = (point2.Y < 0) ? 0 : point2.Y;
37 | MoveWindow(hChildWnd, point2.X, point2.Y, nWidth, nHeight, false);
38 | }
39 |
40 | [DllImport("user32.dll")]
41 | public static extern int EndDialog(IntPtr hDlg, IntPtr nResult);
42 | [DllImport("user32.dll")]
43 | private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect);
44 | [DllImport("user32.dll")]
45 | public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength);
46 | [DllImport("user32.dll")]
47 | public static extern int GetWindowTextLength(IntPtr hWnd);
48 | private static void Initialize()
49 | {
50 | if (_hHook != IntPtr.Zero)
51 | {
52 | throw new NotSupportedException("multiple calls are not supported");
53 | }
54 | if (_owner != null)
55 | {
56 | _hHook = SetWindowsHookEx(12, _hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
57 | }
58 | }
59 |
60 | private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam)
61 | {
62 | if (nCode < 0)
63 | {
64 | return CallNextHookEx(_hHook, nCode, wParam, lParam);
65 | }
66 | CWPRETSTRUCT cwpretstruct = (CWPRETSTRUCT) Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));
67 | IntPtr idHook = _hHook;
68 | if (cwpretstruct.message == 5)
69 | {
70 | try
71 | {
72 | CenterWindow(cwpretstruct.hwnd);
73 | }
74 | finally
75 | {
76 | UnhookWindowsHookEx(_hHook);
77 | _hHook = IntPtr.Zero;
78 | }
79 | }
80 | return CallNextHookEx(idHook, nCode, wParam, lParam);
81 | }
82 |
83 | [DllImport("user32.dll")]
84 | private static extern int MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
85 | [DllImport("User32.dll")]
86 | public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
87 | [DllImport("User32.dll")]
88 | public static extern UIntPtr SetTimer(IntPtr hWnd, UIntPtr nIDEvent, uint uElapse, TimerProc lpTimerFunc);
89 | [DllImport("user32.dll")]
90 | public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
91 | public static DialogResult Show(string text)
92 | {
93 | Initialize();
94 | return MessageBox.Show(text);
95 | }
96 |
97 | public static DialogResult Show(string text, string caption)
98 | {
99 | Initialize();
100 | return MessageBox.Show(text, caption);
101 | }
102 |
103 | public static DialogResult Show(IWin32Window owner, string text)
104 | {
105 | _owner = owner;
106 | Initialize();
107 | return MessageBox.Show(owner, text);
108 | }
109 |
110 | public static DialogResult Show(string text, string caption, MessageBoxButtons buttons)
111 | {
112 | Initialize();
113 | return MessageBox.Show(text, caption, buttons);
114 | }
115 |
116 | public static DialogResult Show(IWin32Window owner, string text, string caption)
117 | {
118 | _owner = owner;
119 | Initialize();
120 | return MessageBox.Show(owner, text, caption);
121 | }
122 |
123 | public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
124 | {
125 | Initialize();
126 | return MessageBox.Show(text, caption, buttons, icon);
127 | }
128 |
129 | public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons)
130 | {
131 | _owner = owner;
132 | Initialize();
133 | return MessageBox.Show(owner, text, caption, buttons);
134 | }
135 |
136 | public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton)
137 | {
138 | Initialize();
139 | return MessageBox.Show(text, caption, buttons, icon, defButton);
140 | }
141 |
142 | public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
143 | {
144 | _owner = owner;
145 | Initialize();
146 | return MessageBox.Show(owner, text, caption, buttons, icon);
147 | }
148 |
149 | public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton, MessageBoxOptions options)
150 | {
151 | Initialize();
152 | return MessageBox.Show(text, caption, buttons, icon, defButton, options);
153 | }
154 |
155 | public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton)
156 | {
157 | _owner = owner;
158 | Initialize();
159 | return MessageBox.Show(owner, text, caption, buttons, icon, defButton);
160 | }
161 |
162 | public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton, MessageBoxOptions options)
163 | {
164 | _owner = owner;
165 | Initialize();
166 | return MessageBox.Show(owner, text, caption, buttons, icon, defButton, options);
167 | }
168 |
169 | [DllImport("user32.dll")]
170 | public static extern int UnhookWindowsHookEx(IntPtr idHook);
171 |
172 | public enum CbtHookAction
173 | {
174 | HCBT_MOVESIZE,
175 | HCBT_MINMAX,
176 | HCBT_QS,
177 | HCBT_CREATEWND,
178 | HCBT_DESTROYWND,
179 | HCBT_ACTIVATE,
180 | HCBT_CLICKSKIPPED,
181 | HCBT_KEYSKIPPED,
182 | HCBT_SYSCOMMAND,
183 | HCBT_SETFOCUS
184 | }
185 |
186 | [StructLayout(LayoutKind.Sequential)]
187 | public struct CWPRETSTRUCT
188 | {
189 | public IntPtr lResult;
190 | public IntPtr lParam;
191 | public IntPtr wParam;
192 | public uint message;
193 | public IntPtr hwnd;
194 | }
195 |
196 | public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
197 |
198 | public delegate void TimerProc(IntPtr hWnd, uint uMsg, UIntPtr nIDEvent, uint dwTime);
199 | }
200 | }
201 |
202 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | namespace VisualStudioDownloader
2 | {
3 | using System;
4 | using System.Windows.Forms;
5 |
6 | public delegate void DelReadErrOutput(string result);
7 |
8 | public delegate void DelReadStdOutput(string result);
9 |
10 | internal static class Program
11 | {
12 | [STAThread]
13 | private static void Main()
14 | {
15 | Application.EnableVisualStyles();
16 | Application.SetCompatibleTextRenderingDefault(false);
17 | Application.Run(new MainForm());
18 | }
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("WindowsFormsApp1")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("WindowsFormsApp1")]
13 | [assembly: AssemblyCopyright("Copyright © 2023")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("ff5966fb-12af-4643-9abd-116f249c4c4a")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VisualStudioDownloader.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VisualStudioDownloader.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VisualStudioDownloader.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string Version {
30 | get {
31 | return ((string)(this["Version"]));
32 | }
33 | }
34 |
35 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
36 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
37 | [global::System.Configuration.DefaultSettingValueAttribute("")]
38 | public string Directory {
39 | get {
40 | return ((string)(this["Directory"]));
41 | }
42 | }
43 |
44 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
45 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
46 | [global::System.Configuration.DefaultSettingValueAttribute("")]
47 | public string Workloads {
48 | get {
49 | return ((string)(this["Workloads"]));
50 | }
51 | }
52 |
53 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
54 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
55 | [global::System.Configuration.DefaultSettingValueAttribute("")]
56 | public string Components {
57 | get {
58 | return ((string)(this["Components"]));
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Visual-Studio-Downloader
2 | Visual Studio Downloader can help you download the latest Visual Studio 2022 for offline installation.
3 | Simply choose the visual studio version,target directory,then click initialize button, a few seconds later,click the start button to begin download process.
4 |
5 | # Screenshot
6 | 
7 |
8 | More info on Visual Studio offline installation, please check https://learn.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio?view=vs-2022
9 |
--------------------------------------------------------------------------------
/Visual-Studio-Downloader.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FF5966FB-12AF-4643-9ABD-116F249C4C4A}
8 | WinExe
9 | VisualStudioDownloader
10 | VisualStudioDownloader
11 | v4.0
12 | 512
13 | true
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 | Enterprise_Solution.ico
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | Form
52 |
53 |
54 | MainForm.cs
55 |
56 |
57 |
58 |
59 |
60 | MainForm.cs
61 |
62 |
63 | ResXFileCodeGenerator
64 | Resources.Designer.cs
65 | Designer
66 |
67 |
68 | True
69 | Resources.resx
70 | True
71 |
72 |
73 |
74 | SettingsSingleFileGenerator
75 | Settings.Designer.cs
76 |
77 |
78 | True
79 | Settings.settings
80 | True
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/Visual-Studio-Downloader.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33205.214
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Visual-Studio-Downloader", "Visual-Studio-Downloader.csproj", "{FF5966FB-12AF-4643-9ABD-116F249C4C4A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {FF5966FB-12AF-4643-9ABD-116F249C4C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {FF5966FB-12AF-4643-9ABD-116F249C4C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {FF5966FB-12AF-4643-9ABD-116F249C4C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {FF5966FB-12AF-4643-9ABD-116F249C4C4A}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {6D0C4E26-D385-4195-8AAC-AD7D43A25FF4}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/VisualStudioDownloader.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EnterpriseSolution/Visual-Studio-Downloader/644ac1f21afe925c33d6147db475079f5e332266/VisualStudioDownloader.JPG
--------------------------------------------------------------------------------