Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 179089e

Browse files
authored
Merge pull request #42 from dotnet-campus/t/lindexi/VS2022
支持 VS 2022 版本
2 parents d8aa553 + 193f3fb commit 179089e

17 files changed

+768
-9
lines changed

EncodingNormalior.sln

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,76 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.26228.9
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31521.260
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncodingNormalior", "EncodingNormalior\EncodingNormalior.csproj", "{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}"
7-
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncodingNormalizerVsx", "EncodingNormalizerVsx\EncodingNormalizerVsx.csproj", "{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EncodingNormalior", "EncodingNormalior\EncodingNormalior.csproj", "{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}"
97
EndProject
108
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EncodingNormalizer.UnitTest", "EncodingNormalizer.UnitTest\EncodingNormalizer.UnitTest.csproj", "{388DB615-88E4-4306-B941-DC3C81B06194}"
119
EndProject
1210
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EncodingUtf8AndGBKDifferentiater", "EncodingUtf8AndGBKDifferentiater\EncodingUtf8AndGBKDifferentiater.csproj", "{19184DC4-D745-451E-A3DA-9A827730E16A}"
1311
EndProject
1412
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EncodingNormalior.WPF", "EncodingNormalior.WPF\EncodingNormalior.WPF.csproj", "{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}"
1513
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncodingNormalizerVsixForVS2022", "EncodingNormalizerVsix\EncodingNormalizerVsixForVS2022.csproj", "{C254E902-278A-4021-A50A-049536834C45}"
15+
EndProject
16+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncodingNormalizerVsx", "EncodingNormalizerVsx\EncodingNormalizerVsx.csproj", "{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}"
17+
EndProject
1618
Global
1719
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1820
Debug|Any CPU = Debug|Any CPU
21+
Debug|x86 = Debug|x86
1922
Release|Any CPU = Release|Any CPU
23+
Release|x86 = Release|x86
2024
EndGlobalSection
2125
GlobalSection(ProjectConfigurationPlatforms) = postSolution
2226
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2327
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Debug|x86.ActiveCfg = Debug|Any CPU
29+
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Debug|x86.Build.0 = Debug|Any CPU
2430
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Release|Any CPU.ActiveCfg = Release|Any CPU
2531
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Release|Any CPU.Build.0 = Release|Any CPU
26-
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27-
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
28-
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
29-
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Release|x86.ActiveCfg = Release|Any CPU
33+
{B4D74A9C-F593-4DD9-9CE6-FF12259E6337}.Release|x86.Build.0 = Release|Any CPU
3034
{388DB615-88E4-4306-B941-DC3C81B06194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3135
{388DB615-88E4-4306-B941-DC3C81B06194}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{388DB615-88E4-4306-B941-DC3C81B06194}.Debug|x86.ActiveCfg = Debug|Any CPU
37+
{388DB615-88E4-4306-B941-DC3C81B06194}.Debug|x86.Build.0 = Debug|Any CPU
3238
{388DB615-88E4-4306-B941-DC3C81B06194}.Release|Any CPU.ActiveCfg = Release|Any CPU
3339
{388DB615-88E4-4306-B941-DC3C81B06194}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{388DB615-88E4-4306-B941-DC3C81B06194}.Release|x86.ActiveCfg = Release|Any CPU
41+
{388DB615-88E4-4306-B941-DC3C81B06194}.Release|x86.Build.0 = Release|Any CPU
3442
{19184DC4-D745-451E-A3DA-9A827730E16A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3543
{19184DC4-D745-451E-A3DA-9A827730E16A}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{19184DC4-D745-451E-A3DA-9A827730E16A}.Debug|x86.ActiveCfg = Debug|Any CPU
45+
{19184DC4-D745-451E-A3DA-9A827730E16A}.Debug|x86.Build.0 = Debug|Any CPU
3646
{19184DC4-D745-451E-A3DA-9A827730E16A}.Release|Any CPU.ActiveCfg = Release|Any CPU
3747
{19184DC4-D745-451E-A3DA-9A827730E16A}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{19184DC4-D745-451E-A3DA-9A827730E16A}.Release|x86.ActiveCfg = Release|Any CPU
49+
{19184DC4-D745-451E-A3DA-9A827730E16A}.Release|x86.Build.0 = Release|Any CPU
3850
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3951
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
52+
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Debug|x86.ActiveCfg = Debug|Any CPU
53+
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Debug|x86.Build.0 = Debug|Any CPU
4054
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
4155
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Release|x86.ActiveCfg = Release|Any CPU
57+
{DB0F1F5D-E82F-42A7-963F-4F072CAEBFAE}.Release|x86.Build.0 = Release|Any CPU
58+
{C254E902-278A-4021-A50A-049536834C45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
59+
{C254E902-278A-4021-A50A-049536834C45}.Debug|Any CPU.Build.0 = Debug|Any CPU
60+
{C254E902-278A-4021-A50A-049536834C45}.Debug|x86.ActiveCfg = Debug|x86
61+
{C254E902-278A-4021-A50A-049536834C45}.Debug|x86.Build.0 = Debug|x86
62+
{C254E902-278A-4021-A50A-049536834C45}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{C254E902-278A-4021-A50A-049536834C45}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{C254E902-278A-4021-A50A-049536834C45}.Release|x86.ActiveCfg = Release|x86
65+
{C254E902-278A-4021-A50A-049536834C45}.Release|x86.Build.0 = Release|x86
66+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
67+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
68+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Debug|x86.ActiveCfg = Debug|x86
69+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Debug|x86.Build.0 = Debug|x86
70+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
71+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Release|Any CPU.Build.0 = Release|Any CPU
72+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Release|x86.ActiveCfg = Release|x86
73+
{5C4AABAC-646E-4CA0-822A-0A3D18A296C2}.Release|x86.Build.0 = Release|x86
4274
EndGlobalSection
4375
GlobalSection(SolutionProperties) = preSolution
4476
HideSolutionNode = FALSE
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
using EncodingNormalizerVsx.View;
2+
3+
using EnvDTE;
4+
5+
using EnvDTE80;
6+
7+
using Microsoft.VisualStudio.Shell;
8+
using Microsoft.VisualStudio.Shell.Interop;
9+
10+
using System;
11+
using System.Collections.Generic;
12+
using System.ComponentModel.Design;
13+
using System.Globalization;
14+
using System.IO;
15+
using System.Linq;
16+
using System.Threading;
17+
using System.Threading.Tasks;
18+
using System.Windows;
19+
20+
using Task = System.Threading.Tasks.Task;
21+
using Window = System.Windows.Window;
22+
#pragma warning disable IDE0090 // 忽略警告
23+
24+
namespace EncodingNormalizerVsix;
25+
26+
/// <summary>
27+
/// Command handler
28+
/// </summary>
29+
internal sealed class EncodingNormalizer
30+
{
31+
/// <summary>
32+
/// Command ID.
33+
/// </summary>
34+
public const int CommandId = 0x0100;
35+
36+
/// <summary>
37+
/// Command menu group (command set GUID).
38+
/// </summary>
39+
public static readonly Guid CommandSet = new Guid("0640f5ce-e6bc-43ba-b45e-497d70819a20");
40+
41+
/// <summary>
42+
/// VS Package that provides this command, not null.
43+
/// </summary>
44+
private readonly AsyncPackage _package;
45+
46+
private Window _conformWindow;
47+
private Window _definitionWindow;
48+
49+
/// <summary>
50+
/// Initializes a new instance of the <see cref="EncodingNormalizer"/> class.
51+
/// Adds our command handlers for menu (commands must exist in the command table file)
52+
/// </summary>
53+
/// <param name="package">Owner package, not null.</param>
54+
/// <param name="commandService">Command service to add command to, not null.</param>
55+
private EncodingNormalizer(AsyncPackage package, OleMenuCommandService commandService)
56+
{
57+
_package = package ?? throw new ArgumentNullException(nameof(package));
58+
commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));
59+
60+
CommandID menuCommandID = new CommandID(CommandSet, CommandId);
61+
MenuCommand menuItem = new MenuCommand(EncodingNormalizerCallback, menuCommandID);
62+
commandService.AddCommand(menuItem);
63+
64+
CommandID convertCurrentFileSaveEncodingCommand = new CommandID(CommandSet, 0x0103);
65+
MenuCommand convertCurrentEncodingMenuCommand = new MenuCommand(ConvertCurrentFileEncoding, convertCurrentFileSaveEncodingCommand);
66+
commandService.AddCommand(convertCurrentEncodingMenuCommand);
67+
68+
menuCommandID = new CommandID(CommandSet, 0x0101);
69+
menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
70+
commandService.AddCommand(menuItem);
71+
}
72+
73+
/// <summary>
74+
/// 修改用户打开的文件的编码
75+
/// </summary>
76+
/// <param name="sender"></param>
77+
/// <param name="e"></param>
78+
private async void ConvertCurrentFileEncoding(object sender, EventArgs e)
79+
{
80+
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(_package.DisposalToken);
81+
// 修改用户打开的文件的编码
82+
DTE dte = (DTE) await ServiceProvider.GetServiceAsync(typeof(DTE));
83+
Document document = dte.ActiveDocument;
84+
85+
if (document is null)
86+
{
87+
IServiceProvider serviceProvider = (IServiceProvider) ServiceProvider;
88+
VsShellUtilities.ShowMessageBox(serviceProvider, "Can not find any file opened", "Fail to convert current file encoding", OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
89+
return;
90+
}
91+
string str = document.FullName;
92+
93+
new ConvertFileEncodingPage(new FileInfo(str)).Show();
94+
}
95+
96+
/// <summary>
97+
/// Gets the instance of the command.
98+
/// </summary>
99+
public static EncodingNormalizer Instance
100+
{
101+
get;
102+
private set;
103+
}
104+
105+
/// <summary>
106+
/// Gets the service provider from the owner package.
107+
/// </summary>
108+
private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider
109+
{
110+
get
111+
{
112+
return this._package;
113+
}
114+
}
115+
116+
private async void EncodingNormalizerCallback(object sender, EventArgs e)
117+
{
118+
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(_package.DisposalToken);
119+
DTE dte = (DTE) await ServiceProvider.GetServiceAsync(typeof(DTE));
120+
string file = dte.Solution.FullName;
121+
List<string> project = new List<string>();
122+
if (dte.Solution.Projects.Count > 0)
123+
{
124+
int noLoadProjectCount = TryParseProject(dte, project);
125+
126+
if (noLoadProjectCount > 0)
127+
{
128+
if (project.Count == 0)
129+
{
130+
MessageBox.Show("All project not loaded.", "全部项目都没有加载完成");
131+
return;
132+
}
133+
MessageBox.Show("存在" + noLoadProjectCount + "个工程没有加载");
134+
}
135+
else
136+
{
137+
if (project.Count == 0)
138+
{
139+
MessageBox.Show("Cant find any project.", "没有发现工程");
140+
return;
141+
}
142+
}
143+
}
144+
else
145+
{
146+
MessageBox.Show("Cant find the solution.", "少年,听说你没有打开工程");
147+
return;
148+
}
149+
150+
ConformWindow(file, project);
151+
}
152+
153+
private static int TryParseProject(DTE dte, List<string> project)
154+
{
155+
ThreadHelper.ThrowIfNotOnUIThread();
156+
int noLoadProjectCount = 0;
157+
158+
foreach (object temp in dte.Solution.Projects)
159+
{
160+
try
161+
{
162+
if (temp is Project)
163+
{
164+
if (((Project) temp).Kind == ProjectKinds.vsProjectKindSolutionFolder)
165+
{
166+
project.AddRange(GetSolutionFolderProjects((Project) temp).Select(ParseProjectFolder));
167+
}
168+
else
169+
{
170+
project.Add(ParseProjectFolder((Project) temp));
171+
}
172+
}
173+
}
174+
catch (NotImplementedException)
175+
{
176+
noLoadProjectCount++;
177+
}
178+
}
179+
return noLoadProjectCount;
180+
}
181+
182+
private static string ParseProjectFolder(Project project)
183+
{
184+
ThreadHelper.ThrowIfNotOnUIThread();
185+
string file = project.FullName;
186+
if (!string.IsNullOrEmpty(file))
187+
{
188+
return new FileInfo(file).Directory?.FullName;
189+
}
190+
return "";
191+
}
192+
193+
private static List<Project> GetSolutionFolderProjects(Project solutionFolder)
194+
{
195+
ThreadHelper.ThrowIfNotOnUIThread();
196+
List<Project> project = new List<Project>();
197+
for (int i = 1; i <= solutionFolder.ProjectItems.Count; i++)
198+
{
199+
Project subProject = solutionFolder.ProjectItems.Item(i).SubProject;
200+
if (subProject == null)
201+
{
202+
continue;
203+
}
204+
205+
// If this is another solution folder, do a recursive call, otherwise add
206+
if (subProject.Kind == ProjectKinds.vsProjectKindSolutionFolder)
207+
{
208+
project.AddRange(GetSolutionFolderProjects(subProject));
209+
}
210+
else
211+
{
212+
project.Add(subProject);
213+
}
214+
}
215+
return project;
216+
}
217+
218+
private void ConformWindow(string file, List<string> project)
219+
{
220+
if (_conformWindow != null)
221+
{
222+
_conformWindow.Focus();
223+
_conformWindow.Show();
224+
return;
225+
}
226+
227+
string folder = "";
228+
if (!string.IsNullOrEmpty(file))
229+
{
230+
folder = new FileInfo(file).Directory?.FullName;
231+
}
232+
Window window = new Window()
233+
{
234+
Width = 500,
235+
Height = 500
236+
};
237+
ConformPage conformPage = new ConformPage();
238+
window.Content = conformPage;
239+
window.Title = "编码规范工具";
240+
conformPage.Closing += (_s, _e) =>
241+
{
242+
window.Close();
243+
_conformWindow = null;
244+
};
245+
window.Closed += (_s, _e) => { _conformWindow = null; };
246+
conformPage.SolutionFolder = folder;
247+
conformPage.Project = project;
248+
window.Show();
249+
conformPage.InspectFolderEncoding();
250+
_conformWindow = window;
251+
}
252+
253+
/// <summary>
254+
/// Initializes the singleton instance of the command.
255+
/// </summary>
256+
/// <param name="package">Owner package, not null.</param>
257+
public static async Task InitializeAsync(AsyncPackage package)
258+
{
259+
// Switch to the main thread - the call to AddCommand in HelloCommand's constructor requires
260+
// the UI thread.
261+
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
262+
263+
OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
264+
Instance = new EncodingNormalizer(package, commandService);
265+
}
266+
267+
/// <summary>
268+
/// This function is the callback used to execute the command when the menu item is clicked.
269+
/// See the constructor to see how the menu item is associated with this function using
270+
/// OleMenuCommandService service and MenuCommand class.
271+
/// </summary>
272+
/// <param name="sender">Event sender.</param>
273+
/// <param name="e">Event args.</param>
274+
private void MenuItemCallback(object sender, EventArgs e)
275+
{
276+
if (_definitionWindow != null)
277+
{
278+
_definitionWindow.Focus();
279+
_definitionWindow.Show();
280+
return;
281+
}
282+
Window window = new Window();
283+
DefinitionPage definitionPage = new DefinitionPage();
284+
definitionPage.Closing += (_s, _e) =>
285+
{
286+
window.Close();
287+
_definitionWindow = null;
288+
};
289+
window.Closed += (_s, _e) => { _definitionWindow = null; };
290+
window.Title = "编码规范工具设置";
291+
window.Content = definitionPage;
292+
window.Show();
293+
294+
_definitionWindow = window;
295+
}
296+
}

0 commit comments

Comments
 (0)