├── .gitattributes
├── .gitignore
├── README.md
├── Standard
├── Helpers
│ ├── BitHelper.cs
│ ├── ColorHelper.cs
│ ├── EnumHelper.cs
│ ├── FileHelper.cs
│ └── ZipHelper.cs
└── Standard.csproj
├── StandardUnitTest
├── BitHelperUnitTest.cs
└── StandardUnitTest.csproj
├── Utils.Standard
├── Helpers
│ ├── BitHelper.cs
│ ├── EnumHelper.cs
│ ├── FileHelper.cs
│ └── ZipHelper.cs
└── Utils.Standard.csproj
├── Utils.sln
├── Utils
├── App.config
├── Helpers
│ ├── AppConfigHelper.cs
│ ├── CheckNameHelper.cs
│ ├── ExplorerSizeHelper.cs
│ └── ImageHelper
│ │ └── Gif
│ │ └── GifHelper.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Utils.csproj
└── WindowsApi
│ ├── Lib
│ └── Interop.RDPCOMAPILib.dll
│ ├── ScreenSharing
│ ├── AttendeeConnectInfoEventArgs.cs
│ ├── AttendeeDisConnectEventArgs.cs
│ ├── AttendeeInfo.cs
│ └── ScreenSharing.cs
│ ├── Theme
│ └── Theme.cs
│ ├── WLAN
│ ├── IWlan.cs
│ ├── WlanHelpers.cs
│ ├── WlanInterface.cs
│ ├── WlanManager.cs
│ └── WlanNotificationStructs.cs
│ ├── WMI
│ ├── Drive
│ │ └── Drive.cs
│ ├── Monitor
│ │ └── Monitor.cs
│ └── USBDeviceWatcher
│ │ ├── UsbDeviceInfo.cs
│ │ └── UsbDeviceWatcher.cs
│ └── Win32
│ ├── Advapi32
│ ├── Advapi32Base.cs
│ └── Advapi32Extension.cs
│ ├── Common
│ ├── ExecuteResult.cs
│ └── Win32ErrorCodes.cs
│ ├── Kernel32
│ ├── Kernel32Base.cs
│ └── Kernel32Extension.cs
│ ├── Shell32
│ ├── Shell32Base.Struct.cs
│ ├── Shell32Base.cs
│ └── Shell32Extension.cs
│ ├── User32
│ ├── User32Base.cs
│ └── User32Extension.cs
│ ├── Winmm
│ ├── WinmmBase.cs
│ └── WinmmExtension.cs
│ └── Wlanapi
│ ├── WlanapiBase.Enums.cs
│ ├── WlanapiBase.Struct.cs
│ └── WlanapiBase.cs
└── UtilsDemo
├── App.config
├── Program.cs
├── Properties
└── AssemblyInfo.cs
└── UtilsDemo.csproj
/.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 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 基础功能实现
2 |
3 | Standard2.0
4 |
5 | 类名 |
6 | 方法 |
7 | 参数 |
8 | 描述 |
9 |
10 | BitHelper |
11 | SetBit |
12 | (byte[] data, int bitIndex, bool value) |
13 | 传入指定字节数组,Bit的指定位置和对应值 |
14 |
15 | (byte data, int bitIndex, bool value) |
16 | 传入指定字节,Bit的指定位置和对应值 |
17 |
18 | (bool)GetBit |
19 | (byte[] data, int bitIndex) |
20 | 传入指定字节数组,Bit的指定位置和对应值,返回bool值,1:true;0:false |
21 |
22 | (byte data, int bitIndex) |
23 | 传入指定字节,Bit的指定位置和对应值,返回bool值,1:true;0:false |
24 |
25 | FileHelper |
26 | CheckFileOrDirectoryNameValidity |
27 | (string name) |
28 | 检测文件或者文件夹名称是否合法 |
29 |
--------------------------------------------------------------------------------
/Standard/Helpers/BitHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Standard.Helpers
9 | {
10 | public static class BitHelper
11 | {
12 | public static void SetBit(byte[] data, int bitIndex, bool value)
13 | {
14 | if (data == null || bitIndex < 0 || bitIndex >= data.Length * 8)
15 | {
16 | throw new ArgumentException("Invalid parameters.");
17 | }
18 |
19 | int byteIndex = bitIndex / 8;
20 | int bitPosition = bitIndex % 8;
21 |
22 | if (value)
23 | {
24 | // Set the bit at bitPosition in data[byteIndex]
25 | data[byteIndex] |= (byte)(1 << bitPosition);
26 | }
27 | else
28 | {
29 | // Clear the bit at bitPosition in data[byteIndex]
30 | data[byteIndex] &= (byte)~(1 << bitPosition);
31 | }
32 | }
33 |
34 | public static byte SetBit(byte data, int bitIndex, bool value)
35 | {
36 | if (bitIndex < 0 || bitIndex >= 8)
37 | {
38 | throw new ArgumentException("Invalid parameters.");
39 | }
40 |
41 | if (value)
42 | {
43 | // Set the bit at bitPosition in data[byteIndex]
44 | data |= (byte)(1 << bitIndex);
45 | }
46 | else
47 | {
48 | // Clear the bit at bitPosition in data[byteIndex]
49 | data &= (byte)~(1 << bitIndex);
50 | }
51 |
52 | return data;
53 | }
54 |
55 | public static bool GetBit(byte[] data, int bitIndex)
56 | {
57 | if (data == null || bitIndex < 0 || bitIndex >= data.Length * 8)
58 | {
59 | throw new ArgumentException("Invalid parameters.");
60 | }
61 |
62 | int byteIndex = bitIndex / 8;
63 | int bitPosition = bitIndex % 8;
64 |
65 | return GetBit(data[byteIndex], bitPosition);
66 | }
67 |
68 | public static bool GetBit(byte data, int bitIndex)
69 | {
70 | if (bitIndex < 0 || bitIndex >= 8)
71 | {
72 | throw new ArgumentException("Invalid parameters.");
73 | }
74 |
75 | bool bit = (data & (1 << bitIndex)) != 0;
76 | return bit;
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Standard/Helpers/ColorHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Text;
5 |
6 | namespace Standard.Helpers
7 | {
8 | public static class ColorHelper
9 | {
10 | ///
11 | /// 生成指定数量的高区分度颜色
12 | ///
13 | /// 调整 count 参数即可适应不同需求
14 | /// seed 参数控制随机性,方便调试和一致性需求
15 | ///
16 | public static List GenerateDistinctColors(int count, int seed = 0)
17 | {
18 | Random random = seed == 0 ? new Random() : new Random(seed);
19 | List colors = new List();
20 |
21 | for (int i = 0; i < count; i++)
22 | {
23 | // 计算色相(均匀分布)
24 | double hue = (i * (360.0 / count)) % 360;
25 |
26 | // 高饱和度(80%~100%)
27 | double saturation = random.Next(80, 101);
28 |
29 | // 低亮度(20%~40%):颜色更暗但保留鲜艳度
30 | double lightness = random.Next(40, 41);
31 |
32 | // 转换为RGB颜色
33 | Color color = HSLToRGB(hue, saturation, lightness);
34 | colors.Add(color);
35 | }
36 |
37 | return colors;
38 | }
39 |
40 | ///
41 | /// HSL转RGB核心函数
42 | ///
43 | ///
44 | ///
45 | ///
46 | ///
47 | private static Color HSLToRGB(double h, double s, double l)
48 | {
49 | h %= 360;
50 | s = Math.Min(100, Math.Max(0, s));
51 | l = Math.Min(100, Math.Max(0, l));
52 |
53 | double c = (1 - Math.Abs(2 * l / 100 - 1)) * (s / 100);
54 | double hPrime = h / 60;
55 | double x = c * (1 - Math.Abs(hPrime % 2 - 1));
56 | double r1, g1, b1;
57 |
58 | if (0 <= hPrime && hPrime < 1)
59 | {
60 | r1 = c; g1 = x; b1 = 0;
61 | }
62 | else if (1 <= hPrime && hPrime < 2)
63 | {
64 | r1 = x; g1 = c; b1 = 0;
65 | }
66 | else if (2 <= hPrime && hPrime < 3)
67 | {
68 | r1 = 0; g1 = c; b1 = x;
69 | }
70 | else if (3 <= hPrime && hPrime < 4)
71 | {
72 | r1 = 0; g1 = x; b1 = c;
73 | }
74 | else if (4 <= hPrime && hPrime < 5)
75 | {
76 | r1 = x; g1 = 0; b1 = c;
77 | }
78 | else
79 | {
80 | r1 = c; g1 = 0; b1 = x;
81 | }
82 |
83 | double m = l / 100 - c / 2;
84 | byte r = (byte)Math.Round((r1 + m) * 255);
85 | byte g = (byte)Math.Round((g1 + m) * 255);
86 | byte b = (byte)Math.Round((b1 + m) * 255);
87 |
88 | return Color.FromArgb(255, r, g, b);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Standard/Helpers/EnumHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Text;
5 |
6 | namespace Standard.Helpers
7 | {
8 | public static class EnumHelper
9 | {
10 | public static ObservableCollection GetEnumList() where TEnum : Enum
11 | {
12 | var cols = new ObservableCollection();
13 | var items = Enum.GetValues(typeof(TEnum));
14 | foreach (var item in items)
15 | {
16 | cols.Add((TEnum)item);
17 | }
18 | return cols;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Standard/Helpers/FileHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Standard.Helpers
8 | {
9 | public static class FileHelper
10 | {
11 | public static bool CheckFileOrDirectoryNameValidity(string name)
12 | {
13 | string[] strList = new string[] { " ", "/", "\"", @"\", @"\/", ":", "*", "?", "<", ">", "|", "\r\n" };
14 |
15 | return !string.IsNullOrEmpty(name) && !strList.Any(p => name.Contains(p));
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Standard/Helpers/ZipHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO.Compression;
4 | using System.Text;
5 |
6 | namespace Standard.Helpers
7 | {
8 | public static class ZipHelper
9 | {
10 | public static bool Create()
11 | {
12 | //ZipFile.CreateFromDirectory
13 | return true;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Standard/Standard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/StandardUnitTest/BitHelperUnitTest.cs:
--------------------------------------------------------------------------------
1 | namespace StandardUnitTest
2 | {
3 | public class BitHelperUnitTest
4 | {
5 | [SetUp]
6 | public void Setup()
7 | {
8 |
9 | }
10 |
11 | [Test]
12 | public void SetBit()
13 | {
14 | byte[] data1 = [0x00,0x00];
15 | Standard.Helpers.BitHelper.SetBit(data1, 8, true);
16 | Assert.That(data1[1], Is.EqualTo(0x01));
17 |
18 | byte data2 = 0x00;
19 | data2 = Standard.Helpers.BitHelper.SetBit(data2, 0, true);
20 | Assert.That(data2, Is.EqualTo(0x01));
21 | }
22 |
23 | [Test]
24 | public void GetBit()
25 | {
26 | byte[] data1 = [0x00, 0x00];
27 | bool result = Standard.Helpers.BitHelper.GetBit(data1, 8);
28 | Assert.That(result, Is.EqualTo(false));
29 |
30 | byte data2 = 0x00;
31 | result = Standard.Helpers.BitHelper.GetBit(data2, 0);
32 | Assert.That(result, Is.EqualTo(false));
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/StandardUnitTest/StandardUnitTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 | false
9 | true
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Utils.Standard/Helpers/BitHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Utils.Standard.Helpers
6 | {
7 | public static class BitHelper
8 | {
9 | public static void SetBit(byte[] data, int bitIndex, bool value)
10 | {
11 | if (data == null || bitIndex < 0 || bitIndex >= data.Length * 8)
12 | {
13 | throw new ArgumentException("Invalid parameters.");
14 | }
15 |
16 | int byteIndex = bitIndex / 8;
17 | int bitPosition = bitIndex % 8;
18 |
19 | if (value)
20 | {
21 | // Set the bit at bitPosition in data[byteIndex]
22 | data[byteIndex] |= (byte)(1 << bitPosition);
23 | }
24 | else
25 | {
26 | // Clear the bit at bitPosition in data[byteIndex]
27 | data[byteIndex] &= (byte)~(1 << bitPosition);
28 | }
29 | }
30 |
31 | public static byte SetBit(byte data, int bitIndex, bool value)
32 | {
33 | if (bitIndex < 0 || bitIndex >= 8)
34 | {
35 | throw new ArgumentException("Invalid parameters.");
36 | }
37 |
38 | if (value)
39 | {
40 | // Set the bit at bitPosition in data[byteIndex]
41 | data |= (byte)(1 << bitIndex);
42 | }
43 | else
44 | {
45 | // Clear the bit at bitPosition in data[byteIndex]
46 | data &= (byte)~(1 << bitIndex);
47 | }
48 |
49 | return data;
50 | }
51 |
52 | public static bool GetBit(byte[] data, int bitIndex)
53 | {
54 | if (data == null || bitIndex < 0 || bitIndex >= data.Length * 8)
55 | {
56 | throw new ArgumentException("Invalid parameters.");
57 | }
58 |
59 | int byteIndex = bitIndex / 8;
60 | int bitPosition = bitIndex % 8;
61 |
62 | return GetBit(data[byteIndex], bitPosition);
63 | }
64 |
65 | public static bool GetBit(byte data, int bitIndex)
66 | {
67 | if (bitIndex < 0 || bitIndex >= 8)
68 | {
69 | throw new ArgumentException("Invalid parameters.");
70 | }
71 |
72 | bool bit = (data & (1 << bitIndex)) != 0;
73 | return bit;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Utils.Standard/Helpers/EnumHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Text;
5 |
6 | namespace Utils.Standard.Helpers
7 | {
8 | public static class EnumHelper
9 | {
10 | public static ObservableCollection GetEnumList() where TEnum : Enum
11 | {
12 | var cols = new ObservableCollection();
13 | var items = Enum.GetValues(typeof(TEnum));
14 | foreach (var item in items)
15 | {
16 | cols.Add((TEnum)item);
17 | }
18 | return cols;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Utils.Standard/Helpers/FileHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.Standard.Helpers
8 | {
9 | public static class FileHelper
10 | {
11 | public static bool CheckFileOrDirectoryNameValidity(string name)
12 | {
13 | string[] strList = new string[] { " ", "/", "\"", @"\", @"\/", ":", "*", "?", "<", ">", "|", "\r\n" };
14 |
15 | return !string.IsNullOrEmpty(name) && !strList.Any(p => name.Contains(p));
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Utils.Standard/Helpers/ZipHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO.Compression;
4 | using System.Text;
5 |
6 | namespace Utils.Standard.Helpers
7 | {
8 | public static class ZipHelper
9 | {
10 | public static bool Create()
11 | {
12 | //ZipFile.CreateFromDirectory
13 | return true;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Utils.Standard/Utils.Standard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Utils.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34616.47
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Utils\Utils.csproj", "{52B9C6B5-DA34-4B13-A2BA-5A13F97D0386}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtilsDemo", "UtilsDemo\UtilsDemo.csproj", "{6A1B5E4B-0650-4E1F-AB48-2DEAFE40D6E8}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Standard", "Standard\Standard.csproj", "{372B45ED-4642-4EAC-80FC-B151A0B50732}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StandardUnitTest", "StandardUnitTest\StandardUnitTest.csproj", "{30C53753-E025-485A-873C-640B1E44C792}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils.Standard", "Utils.Standard\Utils.Standard.csproj", "{209AF7BD-A1D8-4C47-BDA7-71BB285255FD}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {52B9C6B5-DA34-4B13-A2BA-5A13F97D0386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {52B9C6B5-DA34-4B13-A2BA-5A13F97D0386}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {52B9C6B5-DA34-4B13-A2BA-5A13F97D0386}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {52B9C6B5-DA34-4B13-A2BA-5A13F97D0386}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {6A1B5E4B-0650-4E1F-AB48-2DEAFE40D6E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {6A1B5E4B-0650-4E1F-AB48-2DEAFE40D6E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {6A1B5E4B-0650-4E1F-AB48-2DEAFE40D6E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {6A1B5E4B-0650-4E1F-AB48-2DEAFE40D6E8}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {372B45ED-4642-4EAC-80FC-B151A0B50732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {372B45ED-4642-4EAC-80FC-B151A0B50732}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {372B45ED-4642-4EAC-80FC-B151A0B50732}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {372B45ED-4642-4EAC-80FC-B151A0B50732}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {30C53753-E025-485A-873C-640B1E44C792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {30C53753-E025-485A-873C-640B1E44C792}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {30C53753-E025-485A-873C-640B1E44C792}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {30C53753-E025-485A-873C-640B1E44C792}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {209AF7BD-A1D8-4C47-BDA7-71BB285255FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {209AF7BD-A1D8-4C47-BDA7-71BB285255FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {209AF7BD-A1D8-4C47-BDA7-71BB285255FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {209AF7BD-A1D8-4C47-BDA7-71BB285255FD}.Release|Any CPU.Build.0 = Release|Any CPU
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | GlobalSection(ExtensibilityGlobals) = postSolution
47 | SolutionGuid = {7B9E596A-8B3F-4589-95C8-0FD2836BC353}
48 | EndGlobalSection
49 | EndGlobal
50 |
--------------------------------------------------------------------------------
/Utils/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Utils/Helpers/AppConfigHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.Helpers
9 | {
10 | public class AppConfigHelper
11 | {
12 | static Configuration _config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
13 |
14 | public static string GetAppSettingsValue(string key)
15 | {
16 | return _config.AppSettings.Settings[key].Value;
17 | }
18 |
19 | public static void UpdateAppSettingsValue(string key, string value)
20 | {
21 | _config.AppSettings.Settings[key].Value = value;
22 | _config.Save(ConfigurationSaveMode.Modified);
23 | ConfigurationManager.RefreshSection("appSettings");
24 | }
25 |
26 | public static void AddAppSettingsValue(string newKey, string newValue)
27 | {
28 | _config.AppSettings.Settings.Add(newKey, newValue);
29 | _config.Save(ConfigurationSaveMode.Modified);
30 | ConfigurationManager.RefreshSection("appSettings");
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Utils/Helpers/CheckNameHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.Helpers
8 | {
9 | public static class CheckNameHelper
10 | {
11 | ///
12 | /// 文件或文件夹名称
13 | ///
14 | ///
15 | ///
16 | public static bool CheckFileOrDirectory(string name)
17 | {
18 | bool isValid = true;
19 | string[] strList = new string[] { " ", "/", "\"", @"\", @"\/", ":", "*", "?", "<", ">", "|", "\r\n" };
20 |
21 | if (string.IsNullOrEmpty(name))
22 | {
23 | isValid = false;
24 | }
25 | else
26 | {
27 | foreach (string errStr in strList)
28 | {
29 | if (name.Contains(errStr))
30 | {
31 | isValid = false;
32 | break;
33 | }
34 | }
35 | }
36 |
37 | return isValid;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Utils/Helpers/ExplorerSizeHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.Helpers
9 | {
10 | public class ExplorerSizeHelper
11 | {
12 | ///
13 | /// 获取文件大小
14 | ///
15 | ///
16 | ///
17 | ///
18 | public static bool GetFileSize(string filePath, out long fileLength)
19 | {
20 | fileLength = -1;
21 | if (File.Exists(filePath))
22 | {
23 | FileInfo fileInfo = new FileInfo(filePath);
24 | fileLength = fileInfo.Length;
25 | return true;
26 | }
27 | return false;
28 | }
29 |
30 | ///
31 | /// 获取文件夹及子目录文件大小
32 | ///
33 | ///
34 | ///
35 | ///
36 | public static bool GetDirectorySize(string directoryPath, out long directoryLength)
37 | {
38 | directoryLength= -1;
39 | if (Directory.Exists(directoryPath))
40 | {
41 | //一级目录
42 | DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath);
43 | foreach (var item in directoryInfo.GetFiles())
44 | {
45 | directoryLength += item.Length;
46 | }
47 | //子目录
48 | foreach (var item in directoryInfo.GetDirectories())
49 | {
50 | if (GetDirectorySize(item.FullName,out long dirLength))
51 | {
52 | directoryLength += dirLength;
53 | }
54 | }
55 |
56 | return true;
57 | }
58 | return false;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Utils/Helpers/ImageHelper/Gif/GifHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Media.Animation;
9 | using System.Windows.Media.Imaging;
10 |
11 | namespace Utils.Helpers
12 | {
13 | public static class GifHelper
14 | {
15 | ///
16 | /// 用Image播放GIF
17 | ///
18 | /// GIF图片URI
19 | /// GIF图片播放一次的秒数
20 | /// 承载GIF的Image控件
21 | /// 错误信息
22 | ///
23 | public static bool GifToImageByAnimate(Uri gif, int gifPlaySeconds,Image imageControl,out string errorMsg)
24 | {
25 | errorMsg = string.Empty;
26 | //确实是GIF
27 | if (!gif.IsFile || !gif.AbsolutePath.EndsWith(".gif"))
28 | {
29 | errorMsg = "Is not gif file!";
30 | return false;
31 | }
32 | try
33 | {
34 | List frameList = new List();
35 | //将gif解码
36 | GifBitmapDecoder decoder = new GifBitmapDecoder(gif
37 | ,BitmapCreateOptions.PreservePixelFormat
38 | ,BitmapCacheOption.Default);
39 | if (!Equals(decoder, null) && decoder.Frames != null)
40 | {
41 | //将每一帧添加到列表
42 | frameList.AddRange(decoder.Frames);
43 | ObjectAnimationUsingKeyFrames objKeyAnimate = new ObjectAnimationUsingKeyFrames
44 | {
45 | Duration = new Duration(TimeSpan.FromSeconds(gifPlaySeconds))
46 | };
47 | foreach (var item in frameList)
48 | {
49 | DiscreteObjectKeyFrame k1_img1 = new DiscreteObjectKeyFrame(item);
50 | objKeyAnimate.KeyFrames.Add(k1_img1);
51 | }
52 | //添加第一帧为图片的开始画面
53 | imageControl.Source = frameList[0];
54 | //循环动画
55 | Storyboard board = new Storyboard
56 | {
57 | RepeatBehavior = RepeatBehavior.Forever,
58 | FillBehavior = FillBehavior.HoldEnd
59 | };
60 | board.Children.Add(objKeyAnimate);
61 | //将动画设置给ImageControl
62 | Storyboard.SetTarget(objKeyAnimate, imageControl);
63 | Storyboard.SetTargetProperty(objKeyAnimate, new PropertyPath(nameof(Image.Source)));
64 | //开始动画
65 | board.Begin();
66 | return true;
67 | }
68 | return false;
69 | }
70 | catch (Exception ex)
71 | {
72 | errorMsg = ex.Message;
73 | return false;
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Utils/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | namespace Utils
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 |
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Utils/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("Utils")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Utils")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("52b9c6b5-da34-4b13-a2ba-5a13f97d0386")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Utils/Utils.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {52B9C6B5-DA34-4B13-A2BA-5A13F97D0386}
8 | Library
9 | Utils
10 | Utils
11 | v4.8
12 | 512
13 | true
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 |
39 |
40 |
41 | False
42 | True
43 | WindowsApi\Lib\Interop.RDPCOMAPILib.dll
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | PreserveNewest
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Lib/Interop.RDPCOMAPILib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LcFireRabbit/Utils/249e975d54751d46d826506b8ba3194a4cdc00a7/Utils/WindowsApi/Lib/Interop.RDPCOMAPILib.dll
--------------------------------------------------------------------------------
/Utils/WindowsApi/ScreenSharing/AttendeeConnectInfoEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public class AttendeeConnectInfoEventArgs : AttendeeInfo
10 | {
11 | public AttendeeConnectInfoEventArgs(string name, string ip, int id, bool isContol)
12 | {
13 | RemoteName = name;
14 | PeerIP = ip;
15 | ID = id;
16 | IsControl = isContol;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/ScreenSharing/AttendeeDisConnectEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public class AttendeeDisConnectEventArgs
10 | {
11 | public int ID { get; set; }
12 |
13 | public AttendeeDisConnectEventArgs(int id)
14 | {
15 | ID = id;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/ScreenSharing/AttendeeInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public class AttendeeInfo
10 | {
11 | public string RemoteName { get; set; }
12 | public string PeerIP { get; set; }
13 | public int ID { get; set; }
14 | public bool IsControl { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/ScreenSharing/ScreenSharing.cs:
--------------------------------------------------------------------------------
1 | using RDPCOMAPILib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace Utils.WindowsApi
11 | {
12 | public class ScreenSharing
13 | {
14 | #region 属性
15 | ///
16 | /// ScreenSharingService
17 | ///
18 | public static ScreenSharing Instance = new Lazy(() => new ScreenSharing()).Value;
19 |
20 | ///
21 | /// 连接字符串
22 | ///
23 | public string ConnectString { get; private set; }
24 |
25 | ///
26 | /// 是否正在分享
27 | ///
28 | private bool _isOpen;
29 | public bool IsOpen
30 | {
31 | get => _isOpen;
32 | set
33 | {
34 | if (value != _isOpen)
35 | {
36 | _isOpen = value;
37 | if (_isOpen)
38 | {
39 | OnRdpShareOpen?.Invoke(nameof(ScreenSharing), null);
40 | }
41 | else
42 | {
43 | OnRdpShareClose?.Invoke(nameof(ScreenSharing), null);
44 | }
45 | }
46 | }
47 | }
48 |
49 | ///
50 | /// 是否暂停
51 | ///
52 | public bool IsPause { get; private set; }
53 |
54 | ///
55 | /// 是否加密
56 | ///
57 | public bool IsEncrypt { get; private set; }
58 |
59 | ///
60 | /// 错误信息
61 | ///
62 | public RDPErrorType ErrorMessage { get; private set; }
63 |
64 | ///
65 | /// 远程桌面错误类型
66 | ///
67 | public enum RDPErrorType
68 | {
69 | NoNetworkReady = 1,
70 | UnKnow = 0
71 | }
72 | #endregion
73 |
74 | #region 事件
75 | public event EventHandler OnAttendeeConnected;
76 | public event EventHandler OnAttendeeDisconnected;
77 | public event EventHandler OnGraphicsStreamPaused;
78 | public event EventHandler OnGraphicsStreamResumed;
79 | public event EventHandler OnRdpShareOpen;
80 | public event EventHandler OnRdpShareClose;
81 | #endregion
82 |
83 | #region 字段
84 | private string _authID = "Coder";
85 |
86 | private string _groupName = "ScreenSharing";
87 |
88 | private RDPSession m_pRdpSession = null;
89 |
90 | private CTRL_LEVEL _attendeeControlLevel;
91 |
92 | private List _attendees;
93 |
94 | private IRDPSRAPIInvitation _rDPSRAPIInvitation;
95 |
96 | protected object _lock = new object();
97 | #endregion
98 |
99 | #region 构造
100 | private ScreenSharing()
101 | {
102 | _attendees = new List();
103 | }
104 | #endregion
105 |
106 | #region 事件注册方法
107 | ///
108 | /// 错误
109 | ///
110 | ///
111 | private void OnError(object ErrorInfo)
112 | {
113 | ///待议
114 | }
115 |
116 | ///
117 | /// 远程桌面恢复
118 | ///
119 | private void GraphicsStreamResumed()
120 | {
121 | IsPause = false;
122 | OnGraphicsStreamResumed?.Invoke(this, null);
123 | }
124 |
125 | ///
126 | /// 远程桌面暂停
127 | ///
128 | private void GraphicsStreamPaused()
129 | {
130 | IsPause = true;
131 | OnGraphicsStreamPaused?.Invoke(this, null);
132 | }
133 |
134 | ///
135 | /// 连接着申请权限
136 | ///
137 | ///
138 | ///
139 | private void OnControlLevelChangeRequest(object pAttendee, CTRL_LEVEL RequestedLevel)
140 | {
141 | ///待议 -纠结点(1.完全由主机赋予 2.与会者可以申请)
142 | ///判断设置的与会者权限赋值方式
143 | }
144 |
145 | ///
146 | /// 连接者连入
147 | ///
148 | ///
149 | private void AttendeeConnected(object pAttendee)
150 | {
151 | IRDPSRAPIAttendee rDPSRAPIAttendee = pAttendee as IRDPSRAPIAttendee;
152 |
153 | rDPSRAPIAttendee.ControlLevel = _attendeeControlLevel;
154 |
155 | _attendees.Add(rDPSRAPIAttendee);
156 |
157 | OnAttendeeConnected?.Invoke(this, new AttendeeConnectInfoEventArgs(rDPSRAPIAttendee.RemoteName, rDPSRAPIAttendee.ConnectivityInfo.PeerIP, rDPSRAPIAttendee.Id, rDPSRAPIAttendee.ControlLevel == CTRL_LEVEL.CTRL_LEVEL_INTERACTIVE));
158 | }
159 |
160 | ///
161 | /// 连接者断开
162 | ///
163 | ///
164 | private void AttendeeDisconnected(object pDisconnectInfo)
165 | {
166 | IRDPSRAPIAttendeeDisconnectInfo pDiscInfo = pDisconnectInfo as IRDPSRAPIAttendeeDisconnectInfo;
167 |
168 | RemoveAndDisposeAttendee(pDiscInfo.Attendee);
169 |
170 | while (Marshal.ReleaseComObject(pDiscInfo) > 0) ;
171 | }
172 | #endregion
173 |
174 | #region 私有方法
175 | ///
176 | /// 注册所需要的事件
177 | ///
178 | private void RegistEvent()
179 | {
180 | m_pRdpSession = new RDPSession();
181 |
182 | m_pRdpSession.OnAttendeeConnected += new _IRDPSessionEvents_OnAttendeeConnectedEventHandler(AttendeeConnected);
183 |
184 | m_pRdpSession.OnAttendeeDisconnected += new _IRDPSessionEvents_OnAttendeeDisconnectedEventHandler(AttendeeDisconnected);
185 |
186 | m_pRdpSession.OnControlLevelChangeRequest += new _IRDPSessionEvents_OnControlLevelChangeRequestEventHandler(OnControlLevelChangeRequest);
187 |
188 | m_pRdpSession.OnGraphicsStreamPaused += new _IRDPSessionEvents_OnGraphicsStreamPausedEventHandler(GraphicsStreamPaused);
189 |
190 | m_pRdpSession.OnGraphicsStreamResumed += new _IRDPSessionEvents_OnGraphicsStreamResumedEventHandler(GraphicsStreamResumed);
191 |
192 | m_pRdpSession.OnError += new _IRDPSessionEvents_OnErrorEventHandler(OnError);
193 |
194 | try
195 | {
196 | m_pRdpSession.Open();
197 | }
198 | catch (Exception ex)
199 | {
200 | Close();
201 | ErrorMessage = RDPErrorType.NoNetworkReady;
202 | }
203 | }
204 |
205 | ///
206 | /// 判读对象是否为空,为空抛出异常
207 | ///
208 | /// 检查对象
209 | /// 异常信息
210 | private void ObjIsNull(object parameter, string errorMsg)
211 | {
212 | if (object.Equals(parameter, null))
213 | {
214 | throw new Exception(errorMsg);
215 | }
216 | }
217 |
218 | ///
219 | /// 为私有列表消除对象并释放对象
220 | ///
221 | ///
222 | private void RemoveAndDisposeAttendee(IRDPSRAPIAttendee attendee)
223 | {
224 | for (int i = 0; i < _attendees.Count; i++)
225 | {
226 | if (_attendees[i].Id == attendee.Id)
227 | {
228 | OnAttendeeDisconnected?.Invoke(this, new AttendeeDisConnectEventArgs(attendee.Id));
229 |
230 | int id = _attendees[i].Id;
231 |
232 | IRDPSRAPIAttendee rDPSRAPI = _attendees[i];
233 |
234 | while (Marshal.FinalReleaseComObject(rDPSRAPI) > 0) ;
235 |
236 | _attendees.RemoveAt(i);
237 | }
238 | }
239 | }
240 |
241 | ///
242 | /// 得到对应的私有对象
243 | ///
244 | ///
245 | ///
246 | private IRDPSRAPIAttendee GetRealAttendee(int id)
247 | {
248 | for (int i = 0; i < _attendees.Count; i++)
249 | {
250 | if (_attendees[i].Id == id)
251 | {
252 | return _attendees[i];
253 | }
254 | }
255 | return null;
256 | }
257 |
258 | ///
259 | /// 将连接字符串以xml形式保存
260 | ///
261 | ///
262 | private void WriteToFile(string InviteString)
263 | {
264 | string exePath = Environment.CurrentDirectory;
265 | using (StreamWriter sw = File.CreateText(exePath + "\\inv.xml"))
266 | {
267 | sw.WriteLine(InviteString);
268 | }
269 | }
270 |
271 | ///
272 | /// 删除链接字符串文件
273 | ///
274 | private void DeleteConnectFile()
275 | {
276 | string exePath = Environment.CurrentDirectory;
277 | if (File.Exists(exePath + "\\inv.xml"))
278 | {
279 | File.Delete(exePath + "\\inv.xml");
280 | }
281 | }
282 |
283 | ///
284 | /// 是否是Windows7
285 | ///
286 | ///
287 | private bool IsWindows7()
288 | {
289 | Version currentVersion = Environment.OSVersion.Version;
290 |
291 | if (currentVersion >= new Version(6, 1) && currentVersion < new Version(6, 2))
292 | {
293 | return true;
294 | }
295 |
296 | return false;
297 | }
298 | #endregion
299 |
300 | #region 公有方法
301 | ///
302 | /// 创建会话
303 | ///
304 | /// 会话连接密码
305 | /// 会话最多加入人数
306 | /// 会话连接字符串
307 | public void CreateInvitation(string password, int attendeeLimit, bool isControl)
308 | {
309 | lock (_lock)
310 | {
311 | ///判空
312 | if (!object.Equals(m_pRdpSession, null))
313 | return;
314 |
315 | RegistEvent();
316 |
317 | if (m_pRdpSession != null)
318 | {
319 | if (isControl)
320 | {
321 | _attendeeControlLevel = CTRL_LEVEL.CTRL_LEVEL_INTERACTIVE;
322 | }
323 | else
324 | {
325 | _attendeeControlLevel = CTRL_LEVEL.CTRL_LEVEL_VIEW;
326 | }
327 |
328 | _rDPSRAPIInvitation = m_pRdpSession.Invitations.CreateInvitation(_authID, _groupName, password, attendeeLimit);
329 |
330 | ConnectString = _rDPSRAPIInvitation.ConnectionString;
331 |
332 | //WriteToFile(LinkString);
333 |
334 | IsPause = false;
335 |
336 | IsEncrypt = password != string.Empty;
337 |
338 | IsOpen = true;
339 | }
340 | }
341 | }
342 |
343 | ///
344 | /// 暂停会话
345 | ///
346 | public void Pause()
347 | {
348 | if (object.Equals(m_pRdpSession, null))
349 | return;
350 |
351 | m_pRdpSession.Pause();
352 | }
353 |
354 | ///
355 | /// 恢复会话
356 | ///
357 | public void Resume()
358 | {
359 | if (object.Equals(m_pRdpSession, null))
360 | return;
361 |
362 | m_pRdpSession.Resume();
363 | }
364 |
365 | ///
366 | /// 关闭会话(PC)
367 | ///
368 | public void Close()
369 | {
370 | lock (_lock)
371 | {
372 | if (object.Equals(m_pRdpSession, null))
373 | return;
374 |
375 | foreach (var p in _attendees)
376 | {
377 | p.TerminateConnection();
378 | }
379 |
380 | if (_attendees.Count > 0)
381 | {
382 | foreach (var p in _attendees)
383 | {
384 | while (Marshal.FinalReleaseComObject(p) > 0) ;
385 | }
386 | }
387 |
388 | _attendees.Clear();
389 |
390 | m_pRdpSession.Close();
391 |
392 | if (IsWindows7())
393 | {
394 | while (Marshal.FinalReleaseComObject(_rDPSRAPIInvitation) > 0) ;
395 |
396 | while (Marshal.FinalReleaseComObject(m_pRdpSession) > 0) ;
397 | }
398 |
399 | m_pRdpSession = null;
400 |
401 | GC.Collect();
402 |
403 | //DeleteConnectFile();
404 |
405 | IsOpen = false;
406 | }
407 | }
408 |
409 | ///
410 | /// 获取连接者列表
411 | ///
412 | ///
413 | public List GetAttendeeInfos()
414 | {
415 | List attendeeInfos = new List();
416 |
417 | for (int i = 0; i < _attendees.Count; i++)
418 | {
419 | attendeeInfos.Add(new AttendeeInfo()
420 | {
421 | ID = _attendees[i].Id,
422 | RemoteName = _attendees[i].RemoteName,
423 | PeerIP = _attendees[i].ConnectivityInfo.PeerIP,
424 | IsControl = _attendees[i].ControlLevel == CTRL_LEVEL.CTRL_LEVEL_INTERACTIVE
425 | });
426 | }
427 |
428 | return attendeeInfos;
429 | }
430 |
431 | ///
432 | /// 单独修改某个连接的控制权限
433 | ///
434 | /// 与会者对象
435 | /// 想要赋予的权限
436 | public void SetInterActiveControlLevel(int id)
437 | {
438 | ///判空
439 | if (object.Equals(m_pRdpSession, null))
440 | return;
441 |
442 | IRDPSRAPIAttendee realAttendee = GetRealAttendee(id);
443 |
444 | if (object.Equals(realAttendee, null))
445 | return;
446 |
447 | realAttendee.ControlLevel = CTRL_LEVEL.CTRL_LEVEL_INTERACTIVE;
448 | }
449 |
450 | public void SetViewControlLevel(int id)
451 | {
452 | ///判空
453 | if (object.Equals(m_pRdpSession, null))
454 | return;
455 |
456 | IRDPSRAPIAttendee realAttendee = GetRealAttendee(id);
457 |
458 | if (object.Equals(realAttendee, null))
459 | return;
460 |
461 | realAttendee.ControlLevel = CTRL_LEVEL.CTRL_LEVEL_VIEW;
462 | }
463 |
464 | ///
465 | /// 关闭某个指定的与会者连接
466 | ///
467 | ///
468 | public void CloseAttendeeConnect(int id)
469 | {
470 | ///判空
471 | if (object.Equals(m_pRdpSession, null))
472 | return;
473 |
474 | IRDPSRAPIAttendee realAttendee = GetRealAttendee(id);
475 |
476 | if (object.Equals(realAttendee, null))
477 | return;
478 |
479 | realAttendee.TerminateConnection();
480 | }
481 | #endregion
482 | }
483 | }
484 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Theme/Theme.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public class Theme
10 | {
11 | ///
12 | /// 获取当前操作系统 是浅色还是暗色
13 | ///
14 | ///
15 | public static bool IsLight()
16 | {
17 | bool isLightMode = true;
18 | try
19 | {
20 | var v = Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", "1");
21 | if (v != null && v.ToString() == "0")
22 | isLightMode = false;
23 | }
24 | catch { }
25 | return isLightMode;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/WLAN/IWlan.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public interface IWlan
10 | {
11 |
12 | }
13 | }
--------------------------------------------------------------------------------
/Utils/WindowsApi/WLAN/WlanHelpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | internal class WlanHelpers
11 | {
12 | internal static WlanConnectionNotificationData? ParseWlanConnectionNotification(ref WlanNotificationData notifyData)
13 | {
14 | int expectedSize = Marshal.SizeOf(typeof(WlanConnectionNotificationData));
15 | if (notifyData.DataSize < expectedSize)
16 | return null;
17 |
18 | WlanConnectionNotificationData connNotifyData = (WlanConnectionNotificationData)Marshal.PtrToStructure(notifyData.DataPtr, typeof(WlanConnectionNotificationData));
19 |
20 | if (connNotifyData.WlanReasonCode == WlanReasonCode.Success)
21 | {
22 | long profileXmlPtrValue = notifyData.DataPtr.ToInt64() + Marshal.OffsetOf(typeof(WlanConnectionNotificationData), "profileXml").ToInt64();
23 | connNotifyData.ProfileXml = Marshal.PtrToStringUni(new IntPtr(profileXmlPtrValue));
24 | }
25 |
26 | return connNotifyData;
27 | }
28 |
29 | ///
30 | /// Gets a string that describes a specified reason code. NOTE: Not used!
31 | /// 获取描述指定原因代码的字符串。注意:未使用!
32 | ///
33 | /// The reason code.
34 | /// The string.
35 | internal static string GetStringForReasonCode(WlanReasonCode reasonCode)
36 | {
37 | // the 1024 size here is arbitrary; the WlanReasonCodeToString docs fail to specify a recommended size
38 | // 这里的1024大小是任意的;WlanReasonCodeToString文档无法指定建议的大小
39 | StringBuilder sb = new StringBuilder(1024);
40 |
41 | if (WlanapiBase.WlanReasonCodeToString(reasonCode, sb.Capacity, sb, IntPtr.Zero) != 0)
42 | {
43 | // Not sure if we get junk in the stringbuilder buffer from WlanReasonCodeToString, clearing it to be sure.
44 | // 不确定是否从WlanReasonCodeToString在stringbuilder缓冲区中得到垃圾,请清除它以确定。
45 | sb.Clear();
46 | sb.Append("Failed to retrieve reason code, probably too small buffer.");
47 | }
48 |
49 | return sb.ToString();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/WLAN/WlanManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | ///
11 | /// System WLAN Manager
12 | ///
13 | public class WlanManager
14 | {
15 | #region Fields
16 | ///
17 | /// 客户端在此会话中使用的句柄
18 | ///
19 | internal IntPtr _clientHandle;
20 |
21 | ///
22 | /// 将在此会话中使用的 WLAN API 版本
23 | ///
24 | internal uint _negotiatedVersion;
25 |
26 | ///
27 | /// 通知事件回调
28 | ///
29 | internal WlanapiBase.WlanNotificationCallbackDelegate _wlanNotificationCallback;
30 |
31 | ///
32 | /// 无线网卡列表
33 | ///
34 | private Dictionary _ifaces = new Dictionary();
35 | #endregion
36 |
37 | #region Properties
38 | ///
39 | /// 没有WIFI
40 | ///
41 | public bool NoWifiAvailable { get; set; }
42 |
43 | ///
44 | /// Gets the WLAN interfaces.
45 | /// 获取WLAN接口
46 | ///
47 | /// Possible Win32 exceptions:
48 | /// 可能的Win32异常:
49 | ///
50 | /// ERROR_INVALID_PARAMETER: A parameter is incorrect. This error is returned if the hClientHandle or ppInterfaceList parameter is NULL. This error is returned if the pReserved is not NULL. This error is also returned if the hClientHandle parameter is not valid.
51 | /// ERROR_INVALID_HANDLE: The handle hClientHandle was not found in the handle table.
52 | /// RPC_STATUS: Various error codes.
53 | /// ERROR_NOT_ENOUGH_MEMORY: Not enough memory is available to process this request and allocate memory for the query results.
54 | ///
55 | /// The WLAN interfaces.
56 | public WlanInterface[] Interfaces
57 | {
58 | get
59 | {
60 | if (NoWifiAvailable)
61 | return null;
62 |
63 | WlanapiBase.ThrowIfError(WlanapiBase.WlanEnumInterfaces(_clientHandle, IntPtr.Zero, out IntPtr ifaceList));
64 |
65 | try
66 | {
67 | WlanInterfaceInfoListHeader header = (WlanInterfaceInfoListHeader)Marshal.PtrToStructure(ifaceList, typeof(WlanInterfaceInfoListHeader));
68 |
69 | Int64 listIterator = ifaceList.ToInt64() + Marshal.SizeOf(header);
70 | WlanInterface[] interfaces = new WlanInterface[header.NumberOfItems];
71 | List currentIfaceGuids = new List();
72 |
73 | for (int i = 0; i < header.NumberOfItems; ++i)
74 | {
75 | WlanInterfaceInfo info = (WlanInterfaceInfo)Marshal.PtrToStructure(new IntPtr(listIterator), typeof(WlanInterfaceInfo));
76 |
77 | listIterator += Marshal.SizeOf(info);
78 | currentIfaceGuids.Add(info.InterfaceGuid);
79 |
80 | WlanInterface wlanIface;
81 | if (_ifaces.ContainsKey(info.InterfaceGuid))
82 | wlanIface = _ifaces[info.InterfaceGuid];
83 | else
84 | wlanIface = new WlanInterface(this, info);
85 |
86 | interfaces[i] = wlanIface;
87 | _ifaces[info.InterfaceGuid] = wlanIface;
88 | }
89 |
90 | // Remove stale interfaces
91 | Queue deadIfacesGuids = new Queue();
92 | foreach (Guid ifaceGuid in _ifaces.Keys)
93 | {
94 | if (!currentIfaceGuids.Contains(ifaceGuid))
95 | deadIfacesGuids.Enqueue(ifaceGuid);
96 | }
97 |
98 | while (deadIfacesGuids.Count != 0)
99 | {
100 | Guid deadIfaceGuid = deadIfacesGuids.Dequeue();
101 | _ifaces.Remove(deadIfaceGuid);
102 | }
103 |
104 | return interfaces;
105 | }
106 | finally
107 | {
108 | WlanapiBase.WlanFreeMemory(ifaceList);
109 | }
110 | }
111 | }
112 | #endregion
113 |
114 | #region Constructor
115 | public WlanManager()
116 | {
117 | int errorCode = 0;
118 | //限制条件
119 | OperatingSystem osVersion = Environment.OSVersion;
120 | bool isWinXP = osVersion.Platform == PlatformID.Win32NT && osVersion.Version.Major == 5 && osVersion.Version.Minor != 0;
121 | // wlanapi not supported in sp1 (or sp2 without hotfix)
122 | if (isWinXP && osVersion.ServicePack == "Service Pack 1")
123 | {
124 | errorCode = Win32ErrorCodes.ERROR_SERVICE_NOT_ACTIVE;
125 | }
126 | else
127 | {
128 | //连接WLAN服务
129 | try
130 | {
131 | errorCode = WlanapiBase.WlanOpenHandle(WlanapiBase.WLAN_CLIENT_VERSION_XP_SP2, IntPtr.Zero, out _negotiatedVersion, out _clientHandle);
132 | }
133 | catch
134 | {
135 | errorCode = Win32ErrorCodes.ERROR_SERVICE_NOT_ACTIVE;
136 | }
137 | }
138 | //判断是否开启成功
139 | if (errorCode != Win32ErrorCodes.ERROR_SUCCESS)
140 | {
141 | NoWifiAvailable = true;
142 | return;
143 | }
144 | //注册WLAN的通知
145 | try
146 | {
147 | // Interop callback
148 | _wlanNotificationCallback = new WlanapiBase.WlanNotificationCallbackDelegate(OnWlanNotification);
149 |
150 | WlanapiBase.ThrowIfError(WlanapiBase.WlanRegisterNotification(_clientHandle,
151 | WlanNotificationSource.WLAN_NOTIFICATION_SOURCE_ALL, false,
152 | _wlanNotificationCallback, IntPtr.Zero, IntPtr.Zero, out WlanNotificationSource prevSrc));
153 | }
154 | catch
155 | {
156 | WlanapiBase.WlanCloseHandle(_clientHandle, IntPtr.Zero);
157 | throw new Exception();
158 | }
159 | }
160 |
161 | ~WlanManager()
162 | {
163 | // Free the handle when deconstructing the client. There won't be a handle if its xp sp 2 without wlanapi installed
164 | // 释放实例
165 | try
166 | {
167 | WlanapiBase.WlanCloseHandle(_clientHandle, IntPtr.Zero);
168 | }
169 | catch
170 | { }
171 | }
172 | #endregion
173 |
174 | #region Fuc
175 | ///
176 | /// 当无线通知时
177 | ///
178 | ///
179 | ///
180 | private void OnWlanNotification(ref WlanNotificationData notifyData, IntPtr context)
181 | {
182 | if (NoWifiAvailable)
183 | return;
184 |
185 | WlanInterface wlanIface = _ifaces.ContainsKey(notifyData.InterfaceGuid) ? _ifaces[notifyData.InterfaceGuid] : null;
186 |
187 | switch (notifyData.NotificationSource)
188 | {
189 | case WlanNotificationSource.WLAN_NOTIFICATION_SOURCE_ACM:
190 | switch ((WlanNotificationCodeAcm)notifyData.NotificationCode)
191 | {
192 | case WlanNotificationCodeAcm.ConnectionStart:
193 | case WlanNotificationCodeAcm.ConnectionComplete:
194 | case WlanNotificationCodeAcm.ConnectionAttemptFail:
195 | case WlanNotificationCodeAcm.Disconnecting:
196 | case WlanNotificationCodeAcm.Disconnected:
197 | WlanConnectionNotificationData? connNotifyData = WlanHelpers.ParseWlanConnectionNotification(ref notifyData);
198 |
199 | if (connNotifyData.HasValue && wlanIface != null)
200 | wlanIface.OnWlanConnection(notifyData, connNotifyData.Value);
201 |
202 | break;
203 | case WlanNotificationCodeAcm.ScanFail:
204 | int expectedSize = Marshal.SizeOf(typeof(int));
205 |
206 | if (notifyData.DataSize >= expectedSize)
207 | {
208 | int reasonInt = Marshal.ReadInt32(notifyData.DataPtr);
209 |
210 | // Want to make sure this doesn't crash if windows sends a reasoncode not defined in the enum.
211 | // 希望确保在windows发送枚举中未定义的推理码时不会崩溃。
212 | if (Enum.IsDefined(typeof(WlanReasonCode), reasonInt))
213 | {
214 | WlanReasonCode reasonCode = (WlanReasonCode)reasonInt;
215 |
216 | if (wlanIface != null)
217 | wlanIface.OnWlanReason(notifyData, reasonCode);
218 | }
219 | }
220 | break;
221 | }
222 | break;
223 | case WlanNotificationSource.WLAN_NOTIFICATION_SOURCE_MSM:
224 | switch ((WlanNotificationCodeMsm)notifyData.NotificationCode)
225 | {
226 | case WlanNotificationCodeMsm.Associating:
227 | case WlanNotificationCodeMsm.Associated:
228 | case WlanNotificationCodeMsm.Authenticating:
229 | case WlanNotificationCodeMsm.Connected:
230 | case WlanNotificationCodeMsm.RoamingStart:
231 | case WlanNotificationCodeMsm.RoamingEnd:
232 | case WlanNotificationCodeMsm.Disassociating:
233 | case WlanNotificationCodeMsm.Disconnected:
234 | case WlanNotificationCodeMsm.PeerJoin:
235 | case WlanNotificationCodeMsm.PeerLeave:
236 | case WlanNotificationCodeMsm.AdapterRemoval:
237 | WlanConnectionNotificationData? connNotifyData = WlanHelpers.ParseWlanConnectionNotification(ref notifyData);
238 |
239 | if (connNotifyData.HasValue && wlanIface != null)
240 | wlanIface.OnWlanConnection(notifyData, connNotifyData.Value);
241 |
242 | break;
243 | }
244 | break;
245 | }
246 |
247 | if (wlanIface != null)
248 | wlanIface.OnWlanNotification(notifyData);
249 | }
250 | #endregion
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/WLAN/WlanNotificationStructs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | internal struct WlanConnectionNotificationEventData
10 | {
11 | public WlanNotificationData NotifyData;
12 | public WlanConnectionNotificationData ConnNotifyData;
13 | }
14 |
15 | internal struct WlanReasonNotificationData
16 | {
17 | public WlanNotificationData NotifyData;
18 | public WlanReasonCode ReasonCode;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/WMI/Drive/Drive.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Management;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class Drive
11 | {
12 | ///
13 | /// 分区是否在外部磁盘上
14 | ///
15 | /// 分区盘符
16 | ///
17 | public static bool IsDriveOnExternalDisk(string driveLetter)
18 | {
19 | bool retVal = false;
20 | driveLetter = driveLetter.TrimEnd('\\');
21 |
22 | // browse all USB WMI physical disks
23 | foreach (ManagementObject drive
24 | in new ManagementObjectSearcher("select DeviceID, MediaType,InterfaceType from Win32_DiskDrive")
25 | .Get()
26 | .Cast())
27 | {
28 | // associate physical disks with partitions
29 | ManagementObjectCollection partitionCollection = new ManagementObjectSearcher(String.Format("associators of {{Win32_DiskDrive.DeviceID='{0}'}} " + "where AssocClass = Win32_DiskDriveToDiskPartition", drive["DeviceID"])).Get();
30 |
31 | foreach (ManagementObject partition in partitionCollection.Cast())
32 | {
33 | if (partition != null)
34 | {
35 | // associate partitions with logical disks (drive letter volumes)
36 | ManagementObjectCollection logicalCollection = new ManagementObjectSearcher(String.Format("associators of {{Win32_DiskPartition.DeviceID='{0}'}} " + "where AssocClass= Win32_LogicalDiskToPartition", partition["DeviceID"])).Get();
37 |
38 | foreach (ManagementObject logical in logicalCollection.Cast())
39 | {
40 | if (logical != null)
41 | {
42 | // finally find the logical disk entry
43 | ManagementObjectCollection.ManagementObjectEnumerator volumeEnumerator = new ManagementObjectSearcher(String.Format("select DeviceID from Win32_LogicalDisk " + "where Name='{0}'", logical["Name"])).Get().GetEnumerator();
44 |
45 | volumeEnumerator.MoveNext();
46 |
47 | ManagementObject volume = (ManagementObject)volumeEnumerator.Current;
48 |
49 | if (driveLetter.ToLowerInvariant().Equals(volume["DeviceID"].ToString().ToLowerInvariant()) &&
50 | (drive["MediaType"].ToString().ToLowerInvariant().Contains("external") || drive["InterfaceType"].ToString().ToLowerInvariant().Contains("usb")))
51 | {
52 | retVal = true;
53 | break;
54 | }
55 | }
56 | }
57 | }
58 | }
59 | }
60 |
61 | return retVal;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/WMI/Monitor/Monitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Management;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class Monitor
11 | {
12 | public static int GetDesktopMonitorNumber()
13 | {
14 | int number = 0;
15 | try
16 | {
17 | ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DesktopMonitor");
18 |
19 | foreach (ManagementObject queryObj in searcher.Get())
20 | {
21 | number++;
22 | }
23 | }
24 | catch (ManagementException e)
25 | {
26 | Console.WriteLine(e.Message);
27 | }
28 |
29 | return number;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/WMI/USBDeviceWatcher/UsbDeviceWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Management;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace Utils.WindowsApi
11 | {
12 | public class UsbDeviceWatcher
13 | {
14 | ///
15 | /// Keyboard
16 | ///
17 | private static readonly Guid Keyboard = new Guid("{4d36e96b-e325-11ce-bfc1-08002be10318}");
18 |
19 | ///
20 | /// Mouse
21 | ///
22 | private static readonly Guid Mouse = new Guid("{4d36e96f-e325-11ce-bfc1-08002be10318}");
23 |
24 | ///
25 | /// USB存储设备上线
26 | ///
27 | public event EventHandler UsbStorageInserted;
28 | ///
29 | /// USB存储设备下线
30 | ///
31 | public event EventHandler UsbStorageRemoved;
32 |
33 | ///
34 | /// HID鼠标上线
35 | ///
36 | public event EventHandler HIDMouseInserted;
37 | ///
38 | /// HID鼠标下线无需求,可以通过验证PnpDeviceId来确定设备
39 | ///
40 | //public event EventHandler HIDMouseRemoved;
41 |
42 | ///
43 | /// HID键盘上线
44 | ///
45 | public event EventHandler HIDKeyboardInserted;
46 | ///
47 | /// HID键盘下线,无需求,可以通过验证PnpDeviceId来确定设备
48 | ///
49 | //public event EventHandler HIDKeyboardRemoved;
50 |
51 |
52 | private ManagementEventWatcher _insertWatcher;
53 |
54 | private ManagementEventWatcher _removeWatcher;
55 |
56 | public class UsbStorageCreatEventArgs : EventArgs
57 | {
58 | public StringCollection DiskRoot { get; set; }
59 |
60 | public DriveType DriveType { get; set; }
61 |
62 | public string PNPDeviceID { get; set; }
63 |
64 | ///
65 | /// 通过得到的设备描述,来查询需要的信息
66 | ///
67 | ///
68 | ///
69 | public UsbStorageCreatEventArgs(string text, string dependent)
70 | {
71 | DiskRoot = UsbDeviceInfo.WMI_GetDiskRoot(dependent);
72 |
73 | DriveType = UsbDeviceInfo.WMI_GetDiskType(dependent);
74 |
75 | PNPDeviceID = text;
76 | }
77 | }
78 |
79 | public class UsbStorageDeleteEventArgs : EventArgs
80 | {
81 | ///
82 | /// 设备的唯一标识
83 | ///
84 | public string PNPDeviceID { get; set; }
85 |
86 | public UsbStorageDeleteEventArgs(string text)
87 | {
88 | PNPDeviceID = text;
89 | }
90 | }
91 |
92 | ///
93 | /// 获取UsbDeviceWatcher的实例
94 | ///
95 | public static UsbDeviceWatcher Instance = new Lazy(() => new UsbDeviceWatcher()).Value;
96 |
97 | ///
98 | /// 单例模式
99 | ///
100 | private UsbDeviceWatcher()
101 | {
102 | AddUSBEventWatcher();
103 | }
104 |
105 | ///
106 | /// 添加USB设备监视
107 | ///
108 | ///
109 | private bool AddUSBEventWatcher()
110 | {
111 | try
112 | {
113 | var scope = new ManagementScope("root\\CIMV2");
114 | var insert = new WqlEventQuery("__InstanceCreationEvent", TimeSpan.FromSeconds(1), "TargetInstance isa 'Win32_USBControllerDevice'");
115 | var remove = new WqlEventQuery("__InstanceDeletionEvent", TimeSpan.FromSeconds(1), "TargetInstance isa 'Win32_USBControllerDevice'");
116 |
117 | _insertWatcher = new ManagementEventWatcher(scope, insert);
118 | _removeWatcher = new ManagementEventWatcher(scope, remove);
119 |
120 | ///WMI服务USB加载响应事件
121 | _insertWatcher.EventArrived += OnUSBInserted;
122 | ///WMI服务USB移除响应事件
123 | _removeWatcher.EventArrived += OnUSBRemoved;
124 |
125 | ///开启监听
126 | _insertWatcher.Start();
127 | _removeWatcher.Start();
128 |
129 | return true;
130 | }
131 | catch (Exception)
132 | {
133 | Dispose();
134 | return false;
135 | }
136 | }
137 |
138 | ///
139 | /// 注销Usb设备监视
140 | ///
141 | public void Dispose()
142 | {
143 | if (_insertWatcher != null)
144 | {
145 | _insertWatcher.Stop();
146 | _insertWatcher.Dispose();
147 | }
148 | if (_removeWatcher != null)
149 | {
150 | _removeWatcher.Stop();
151 | _removeWatcher.Dispose();
152 | }
153 | }
154 |
155 | ///
156 | /// Usb设备下线处理方法
157 | ///
158 | ///
159 | ///
160 | private void OnUSBRemoved(object sender, EventArrivedEventArgs e)
161 | {
162 | string dependent = UsbDeviceInfo.WhoUsbControllerDevice(e).Dependent;
163 | string text = dependent.Replace("\\\\", "\\");
164 |
165 | ///Usb存储类设备标志
166 | if (text.StartsWith("USBSTOR\\"))
167 | {
168 | UsbStorageRemoved?.Invoke(this, new UsbStorageDeleteEventArgs(text));
169 | }
170 | }
171 |
172 | ///
173 | /// Usb设备上线处理方法
174 | ///
175 | ///
176 | ///
177 | private void OnUSBInserted(object sender, EventArrivedEventArgs e)
178 | {
179 | string dependent = UsbDeviceInfo.WhoUsbControllerDevice(e).Dependent;
180 | string text = dependent.Replace("\\\\", "\\");
181 |
182 | ///Usb存储类设备标志
183 | if (text.StartsWith("USBSTOR\\"))
184 | {
185 | UsbStorageInserted?.Invoke(this, new UsbStorageCreatEventArgs(text, dependent));
186 | }
187 | else if (text.StartsWith("HID\\"))
188 | {
189 | PnPEntityInfo[] pnPEntityInfos = UsbDeviceInfo.WhoPnPEntity(text);
190 |
191 | for (int i = 0; !(pnPEntityInfos == null) && i < pnPEntityInfos.Length; i++)
192 | {
193 | ///通过guid去判定当前上线设备是什么类别的设备
194 | if (pnPEntityInfos[i].ClassGuid == Mouse)
195 | {
196 | HIDMouseInserted?.Invoke(this, pnPEntityInfos[i]);
197 | }
198 | else if (pnPEntityInfos[i].ClassGuid == Keyboard)
199 | {
200 | HIDKeyboardInserted?.Invoke(this, pnPEntityInfos[i]);
201 | }
202 | }
203 | }
204 | }
205 |
206 | ///
207 | /// 获取U盘在线状态
208 | ///
209 | public bool UDiskIsOnline
210 | {
211 | get
212 | {
213 | return false;
214 | }
215 | }
216 |
217 | ///
218 | /// 获取键盘在线状态
219 | ///
220 | public bool KeyboardIsOnline
221 | {
222 | get
223 | {
224 | return false;
225 | }
226 | }
227 |
228 | ///
229 | /// 获取鼠标在线状态
230 | ///
231 | public bool MouseIsOnline
232 | {
233 | get
234 | {
235 | return false;
236 | }
237 | }
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Advapi32/Advapi32Base.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class Advapi32Base
11 | {
12 | private const string Advapi32 = "Advapi32.dll";
13 |
14 | // 如果进程的访问令牌中没有关联某权限,则AdjustTokenPrivileges函数调用将会返回错误码ERROR_NOT_ALL_ASSIGNED(值为1300)
15 | public const int ERROR_NOT_ALL_ASSIGNED = 1300;
16 |
17 | #region TokenAccess
18 | internal const uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
19 | internal const uint STANDARD_RIGHTS_READ = 0x00020000;
20 | internal const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
21 | internal const uint TOKEN_DUPLICATE = 0x0002;
22 | internal const uint TOKEN_IMPERSONATE = 0x0004;
23 | internal const uint TOKEN_QUERY = 0x0008;
24 | internal const uint TOKEN_QUERY_SOURCE = 0x0010;
25 | internal const uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
26 | internal const uint TOKEN_ADJUST_GROUPS = 0x0040;
27 | internal const uint TOKEN_ADJUST_DEFAULT = 0x0080;
28 | internal const uint TOKEN_ADJUST_SESSIONID = 0x0100;
29 | internal const uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
30 | internal const uint TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
31 | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
32 | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
33 | TOKEN_ADJUST_SESSIONID);
34 | #endregion
35 |
36 | #region PrivilegeAttributes
37 | internal const uint SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
38 | internal const uint SE_PRIVILEGE_ENABLED = 0x00000002;
39 | internal const uint SE_PRIVILEGE_REMOVED = 0x00000004;
40 | internal const uint SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;
41 | #endregion
42 |
43 | #region PrivilegeConstants
44 | internal const string SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";
45 | internal const string SE_AUDIT_NAME = "SeAuditPrivilege";
46 | internal const string SE_BACKUP_NAME = "SeBackupPrivilege";
47 | internal const string SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege";
48 | internal const string SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege";
49 | internal const string SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege";
50 | internal const string SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege";
51 | internal const string SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege";
52 | internal const string SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege";
53 | internal const string SE_DEBUG_NAME = "SeDebugPrivilege";
54 | internal const string SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege";
55 | internal const string SE_IMPERSONATE_NAME = "SeImpersonatePrivilege";
56 | internal const string SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege";
57 | internal const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
58 | internal const string SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege";
59 | internal const string SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege";
60 | internal const string SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege";
61 | internal const string SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege";
62 | internal const string SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege";
63 | internal const string SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege";
64 | internal const string SE_RELABEL_NAME = "SeRelabelPrivilege";
65 | internal const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege";
66 | internal const string SE_RESTORE_NAME = "SeRestorePrivilege";
67 | internal const string SE_SECURITY_NAME = "SeSecurityPrivilege";
68 | internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
69 | internal const string SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege";
70 | internal const string SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege";
71 | internal const string SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege";
72 | internal const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
73 | internal const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
74 | internal const string SE_TCB_NAME = "SeTcbPrivilege";
75 | internal const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";
76 | internal const string SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege";
77 | internal const string SE_UNDOCK_NAME = "SeUndockPrivilege";
78 | internal const string SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege";
79 | #endregion
80 |
81 | #region Struct
82 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
83 | public struct LUID
84 | {
85 | public int LowPart;
86 | public uint HighPart;
87 | }
88 |
89 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
90 | public struct LUID_AND_ATTRIBUTES
91 | {
92 | public LUID Luid;
93 | public uint Attributes;
94 | }
95 |
96 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
97 | public struct TOKEN_PRIVILEGES
98 | {
99 | public int PrivilegeCount;
100 | public LUID_AND_ATTRIBUTES Privilege;
101 | }
102 | #endregion
103 |
104 | #region P/Invoke Functions
105 | //提升进程权限的Windows API
106 | [DllImport(Advapi32, CharSet = CharSet.Auto, SetLastError = true)]
107 | [return: MarshalAs(UnmanagedType.Bool)]
108 | internal static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccesss, out IntPtr TokenHandle);
109 |
110 | [DllImport(Advapi32, CharSet = CharSet.Unicode, SetLastError = true)]
111 | [return: MarshalAs(UnmanagedType.Bool)]
112 | internal static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
113 |
114 | [DllImport(Advapi32, SetLastError = true)]
115 | internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
116 |
117 | [DllImport(Advapi32, CharSet = CharSet.Unicode, SetLastError = true)]
118 | [return: MarshalAs(UnmanagedType.Bool)]
119 | internal static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, [MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES NewState, uint BufferLength, IntPtr PreviousState, uint ReturnLength);
120 |
121 | [DllImport(Advapi32, ExactSpelling = true, SetLastError = true)]
122 | internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref User32Base.TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
123 |
124 | [DllImport(Advapi32, SetLastError = true, CharSet = CharSet.Unicode)]
125 | [return: MarshalAs(UnmanagedType.VariantBool)]
126 | internal static extern bool InitializeSecurityDescriptor(out object pSecurityDescriptor, uint dwRevision);
127 |
128 | [DllImport(Advapi32, SetLastError = true, CharSet = CharSet.Unicode)]
129 | [return: MarshalAs(UnmanagedType.VariantBool)]
130 | internal static extern bool SetSecurityDescriptorDacl(ref object pSecurityDescriptor, [MarshalAs(UnmanagedType.VariantBool)] bool bDaclPresent, object pDacl, [MarshalAs(UnmanagedType.VariantBool)] bool bDaclDefaulted);
131 | #endregion
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Advapi32/Advapi32Extension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class Advapi32Extension : Advapi32Base
11 | {
12 | ///
13 | /// 授予权限
14 | /// 参数取值为文件PrivilegeAPI中的类PrivilegeConstants中的字段
15 | ///
16 | /// PrivilegeConstants类中的字段
17 | ///
18 | public static bool GrantPrivilege(string privilegeName)
19 | {
20 | try
21 | {
22 | LUID locallyUniqueIdentifier = new LUID();
23 | if (LookupPrivilegeValue(null, privilegeName, ref locallyUniqueIdentifier))
24 | {
25 | TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();
26 | tokenPrivileges.PrivilegeCount = 1;
27 |
28 | LUID_AND_ATTRIBUTES luidAndAtt = new LUID_AND_ATTRIBUTES();
29 | // luidAndAtt.Attributes should be SE_PRIVILEGE_ENABLED to enable privilege
30 | luidAndAtt.Attributes = SE_PRIVILEGE_ENABLED;
31 | luidAndAtt.Luid = locallyUniqueIdentifier;
32 | tokenPrivileges.Privilege = luidAndAtt;
33 |
34 | IntPtr tokenHandle = IntPtr.Zero;
35 | try
36 | {
37 | if (OpenProcessToken(Kernel32Base.GetCurrentProcess(),
38 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out tokenHandle))
39 | {
40 | if (AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, 1024, IntPtr.Zero, 0))
41 | {
42 | // 当前用户没有关联该权限
43 | // 需要在windows系统(本地安全策略——本地策略——用户权限分配)中设置为该权限添加当前用户
44 | if (Marshal.GetLastWin32Error() != ERROR_NOT_ALL_ASSIGNED)
45 | {
46 | return true;
47 | }
48 | }
49 | }
50 | }
51 | finally
52 | {
53 | if (tokenHandle != IntPtr.Zero)
54 | {
55 | Kernel32Base.CloseHandle(tokenHandle);
56 | }
57 | }
58 | }
59 | return false;
60 | }
61 | catch (Exception)
62 | {
63 | return false;
64 | }
65 | }
66 |
67 | ///
68 | /// 撤销权限
69 | /// 参数取值为文件PrivilegeAPI中的类PrivilegeConstants中的字段
70 | ///
71 | /// PrivilegeConstants类中的字段
72 | ///
73 | public static bool RevokePrivilege(string privilegeName)
74 | {
75 | try
76 | {
77 | LUID locallyUniqueIdentifier = new LUID();
78 |
79 | if (LookupPrivilegeValue(null, privilegeName, ref locallyUniqueIdentifier))
80 | {
81 | TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();
82 | tokenPrivileges.PrivilegeCount = 1;
83 |
84 | LUID_AND_ATTRIBUTES luidAndAtt = new LUID_AND_ATTRIBUTES();
85 | // luidAndAtt.Attributes should be none (not set) to disable privilege
86 | luidAndAtt.Luid = locallyUniqueIdentifier;
87 | tokenPrivileges.Privilege = luidAndAtt;
88 |
89 | IntPtr tokenHandle = IntPtr.Zero;
90 | try
91 | {
92 | if (OpenProcessToken(Kernel32Base.GetCurrentProcess(),
93 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out tokenHandle))
94 | {
95 | if (AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, 1024, IntPtr.Zero, 0))
96 | {
97 | // 当前用户没有关联该权限
98 | // 需要在windows系统(本地安全策略——本地策略——用户权限分配)中设置为该权限添加当前用户
99 | if (Marshal.GetLastWin32Error() != ERROR_NOT_ALL_ASSIGNED)
100 | {
101 | return true;
102 | }
103 | }
104 | }
105 | }
106 | finally
107 | {
108 | if (tokenHandle != IntPtr.Zero)
109 | {
110 | Kernel32Base.CloseHandle(tokenHandle);
111 | }
112 | }
113 | }
114 | return false;
115 | }
116 | catch (Exception)
117 | {
118 | return false;
119 | }
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Common/ExecuteResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public enum ExecuteResult
10 | {
11 | Success=0,
12 | Failed=1,
13 | ReStart=2,
14 | }
15 |
16 | public class Common
17 | {
18 | ///
19 | /// 判断Windows系统是否为旧版本
20 | ///
21 | ///
22 | public static bool IsOldOsVersion()
23 | {
24 | OperatingSystem os = Environment.OSVersion;
25 | return os.Platform != PlatformID.Win32NT || os.Version.Major < 6;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Kernel32/Kernel32Base.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class Kernel32Base
11 | {
12 | private const string Kernel32 = "kernel32.dll";
13 |
14 | #region Struct
15 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
16 | public struct TimeZoneInformation
17 | {
18 | [MarshalAs(UnmanagedType.I4)]
19 | internal int bias; // 以分钟为单位
20 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
21 | internal string standardName; // 标准时间的名称
22 | internal SystemTime standardDate;
23 | [MarshalAs(UnmanagedType.I4)]
24 | internal int standardBias; // 标准偏移
25 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
26 | internal string daylightName; // 夏令时的名称
27 | internal SystemTime daylightDate;
28 | [MarshalAs(UnmanagedType.I4)]
29 | internal int daylightBias; // 夏令时偏移
30 | }
31 |
32 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
33 | public struct DynamicTimeZoneInformation
34 | {
35 | [MarshalAs(UnmanagedType.I4)]
36 | internal int bias; // 偏移,以分钟为单位
37 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
38 | internal string standardName; // 标准时间的名称
39 | internal SystemTime standardDate;
40 | [MarshalAs(UnmanagedType.I4)]
41 | internal int standardBias; // 标准偏移
42 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
43 | internal string daylightName; // 夏令时的名称
44 | internal SystemTime daylightDate;
45 | [MarshalAs(UnmanagedType.I4)]
46 | internal int daylightBias; // 夏令时偏移
47 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x80)]
48 | internal string timeZoneKeyName; // 时区名
49 | [MarshalAs(UnmanagedType.Bool)]
50 | internal bool dynamicDaylightTimeDisabled; // 是否自动调整时钟的夏令时
51 | }
52 |
53 | [StructLayout(LayoutKind.Sequential)]
54 | public struct SystemTime
55 | {
56 | [MarshalAs(UnmanagedType.U2)]
57 | internal ushort year; // 年
58 | [MarshalAs(UnmanagedType.U2)]
59 | internal ushort month; // 月
60 | [MarshalAs(UnmanagedType.U2)]
61 | internal ushort dayOfWeek; // 星期
62 | [MarshalAs(UnmanagedType.U2)]
63 | internal ushort day; // 日
64 | [MarshalAs(UnmanagedType.U2)]
65 | internal ushort hour; // 时
66 | [MarshalAs(UnmanagedType.U2)]
67 | internal ushort minute; // 分
68 | [MarshalAs(UnmanagedType.U2)]
69 | internal ushort second; // 秒
70 | [MarshalAs(UnmanagedType.U2)]
71 | internal ushort milliseconds; // 毫秒
72 | }
73 |
74 | [StructLayout(LayoutKind.Sequential)]
75 | internal class SecurityAttributes
76 | {
77 | public SecurityAttributes(object securityDescriptor)
78 | {
79 | this.lpSecurityDescriptor = securityDescriptor;
80 | }
81 |
82 | uint nLegnth = 12;
83 | object lpSecurityDescriptor;
84 | [MarshalAs(UnmanagedType.VariantBool)]
85 | bool bInheritHandle = true;
86 | }
87 | #endregion
88 |
89 | #region P/Invoke Functions
90 | //General
91 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
92 | [return: MarshalAs(UnmanagedType.VariantBool)]
93 | internal static extern bool CloseHandle(uint hHandle);
94 |
95 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
96 | internal static extern uint GetLastError();
97 |
98 | //Semaphore
99 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
100 | internal static extern uint CreateSemaphore(SecurityAttributes auth, int initialCount, int maximumCount, string name);
101 |
102 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
103 | internal static extern uint WaitForSingleObject(uint hHandle, uint dwMilliseconds);
104 |
105 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
106 | [return: MarshalAs(UnmanagedType.VariantBool)]
107 | internal static extern bool ReleaseSemaphore(uint hHandle, int lReleaseCount, out int lpPreviousCount);
108 |
109 | //Memory Mapped Files
110 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
111 | internal static extern IntPtr CreateFileMapping(uint hFile, SecurityAttributes lpAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);
112 |
113 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
114 | internal static extern IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName);
115 |
116 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
117 | internal static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);
118 |
119 | [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
120 | [return: MarshalAs(UnmanagedType.VariantBool)]
121 | internal static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
122 |
123 | //PrivateProfile
124 | [DllImport(Kernel32, CharSet = CharSet.Unicode)]
125 | internal static extern int WritePrivateProfileString(string section, string key, string val, string filePath);
126 |
127 | [DllImport(Kernel32, CharSet = CharSet.Unicode)]
128 | internal static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
129 |
130 | [DllImport(Kernel32, EntryPoint = "GetPrivateProfileString")]
131 | internal static extern uint GetPrivateProfileStringA(string section, string key, string def, Byte[] retVal, int size, string filePath);
132 |
133 | //读取和设置时区
134 | // 针对于旧Windows系统,如Windows XP
135 | [DllImport(Kernel32, CharSet = CharSet.Auto)]
136 | internal static extern int GetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation);
137 |
138 | [DllImport(Kernel32, CharSet = CharSet.Auto)]
139 | internal static extern bool SetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation);
140 |
141 | // 针对于新Windows系统,如Windows 7, Windows8, Windows10
142 | [DllImport(Kernel32, CharSet = CharSet.Auto)]
143 | internal static extern int GetDynamicTimeZoneInformation(ref DynamicTimeZoneInformation lpDynamicTimeZoneInformation);
144 |
145 | [DllImport(Kernel32, CharSet = CharSet.Auto)]
146 | internal static extern bool SetDynamicTimeZoneInformation(ref DynamicTimeZoneInformation lpDynamicTimeZoneInformation);
147 |
148 | // 提升进程权限的Windows API
149 | [DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
150 | internal static extern IntPtr GetCurrentProcess();
151 |
152 | [DllImport(Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
153 | [return: MarshalAs(UnmanagedType.Bool)]
154 | internal static extern Boolean CloseHandle(IntPtr hObject);
155 |
156 | // 系统时间相关
157 | [DllImport(Kernel32)]
158 | internal static extern void GetLocalTime(ref SystemTime lpSystemTime);
159 |
160 | [DllImport(Kernel32)]
161 | internal static extern bool SetLocalTime(ref SystemTime lpSystemTime);
162 |
163 | [DllImport(Kernel32)]
164 | internal static extern void GetSystemTime(ref SystemTime lpSystemTime);
165 |
166 | [DllImport(Kernel32)]
167 | internal static extern bool SetSystemTime(ref SystemTime lpSystemTime);
168 | #endregion
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Kernel32/Kernel32Extension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class Kernel32Extension:Kernel32Base
11 | {
12 | #region 公共方法
13 | ///
14 | /// 写INI文件
15 | ///
16 | /// INI文件地址
17 | /// 节名称
18 | /// 键值
19 | /// 值
20 | public static void WriteINIValue(string FilePath, string Section, string Key, string Value)
21 | {
22 | if (!Directory.Exists(FilePath))
23 | {
24 | Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
25 | }
26 | int n = WritePrivateProfileString(Section, Key, Value, FilePath);
27 | }
28 |
29 | ///
30 | /// 读INI文件
31 | ///
32 | /// INI文件地址
33 | /// 节名称
34 | /// 键值
35 | ///
36 | public static string ReadINIValue(string FilePath, string Section, string Key)
37 | {
38 | StringBuilder temp = new StringBuilder(4096);
39 | GetPrivateProfileString(Section, Key, "", temp, 4096, FilePath);
40 | return temp.ToString();
41 | }
42 |
43 | ///
44 | /// 获取本地时区
45 | ///
46 | ///
47 | public static string GetLocalTimeZone()
48 | {
49 | // 检测当前系统是否为旧系统
50 | if (Common.IsOldOsVersion())
51 | {
52 | TimeZoneInformation tzi = new TimeZoneInformation();
53 | GetTimeZoneInformation(ref tzi);
54 | return TimeZoneInfo2CustomString(tzi);
55 | }
56 | DynamicTimeZoneInformation dtzi = new DynamicTimeZoneInformation();
57 | GetDynamicTimeZoneInformation(ref dtzi);
58 | return DynamicTimeZoneInfo2CustomString(dtzi);
59 | }
60 |
61 | ///
62 | /// 设置本地时区
63 | /// 参数取值"China Standard Time",即可设置为中国时区
64 | ///
65 | ///
66 | ///
67 | public static bool SetLocalTimeZone(string timeZoneName_en)
68 | {
69 | if (Advapi32Extension.GrantPrivilege(Advapi32Base.SE_TIME_ZONE_NAME))
70 | {
71 | DynamicTimeZoneInformation dtzi = TimeZoneName2DynamicTimeZoneInformation(timeZoneName_en);
72 | bool success = false;
73 | // 检测当前系统是否为旧系统
74 | if (Common.IsOldOsVersion())
75 | {
76 | TimeZoneInformation tzi = DynamicTimeZoneInformation2TimeZoneInformation(dtzi);
77 | success = SetTimeZoneInformation(ref tzi);
78 | }
79 | else
80 | {
81 | success = SetDynamicTimeZoneInformation(ref dtzi);
82 | }
83 | if (success)
84 | {
85 | TimeZoneInfo.ClearCachedData(); // 清除缓存
86 | }
87 | if (!Advapi32Extension.RevokePrivilege(Advapi32Base.SE_TIME_ZONE_NAME))
88 | {
89 | // 撤权失败
90 | }
91 | return success;
92 | }
93 | // 授权失败
94 | return false;
95 | }
96 |
97 | ///
98 | /// 获取本地时间
99 | ///
100 | ///
101 | public static DateTime GetLocalTime()
102 | {
103 | SystemTime sysTime = new SystemTime();
104 | GetLocalTime(ref sysTime);
105 | return SystemTime2DateTime(sysTime);
106 | }
107 |
108 | ///
109 | /// 设置本地时间
110 | ///
111 | ///
112 | ///
113 | public static bool SetLocalTime(SystemTime dateTime)
114 | {
115 | bool success = SetLocalTime(ref dateTime);
116 | return success;
117 | }
118 |
119 | ///
120 | /// 获取系统时间
121 | ///
122 | ///
123 | public static DateTime GetSystemTime()
124 | {
125 | SystemTime sysTime = new SystemTime();
126 | GetSystemTime(ref sysTime);
127 | return SystemTime2DateTime(sysTime);
128 | }
129 |
130 | ///
131 | /// 设置系统时间(UTC)
132 | ///
133 | ///
134 | ///
135 | public static bool SetSystemTime(DateTime dateTime)
136 | {
137 | SystemTime sysTime = DateTime2SystemTime(dateTime);
138 | bool success = SetSystemTime(ref sysTime);
139 | return success;
140 | }
141 |
142 | ///
143 | /// 将SystemTime转换为DateTime
144 | ///
145 | ///
146 | ///
147 | public static DateTime SystemTime2DateTime(SystemTime sysTime)
148 | {
149 | return new DateTime(sysTime.year, sysTime.month, sysTime.day, sysTime.hour, sysTime.minute, sysTime.second, sysTime.milliseconds);
150 | }
151 |
152 | ///
153 | /// 将DateTime转换为SystemTime
154 | ///
155 | ///
156 | ///
157 | public static SystemTime DateTime2SystemTime(DateTime dateTime)
158 | {
159 | SystemTime sysTime = new SystemTime
160 | {
161 | year = Convert.ToUInt16(dateTime.Year),
162 | month = Convert.ToUInt16(dateTime.Month),
163 | day = Convert.ToUInt16(dateTime.Day),
164 | hour = Convert.ToUInt16(dateTime.Hour),
165 | minute = Convert.ToUInt16(dateTime.Minute),
166 | second = Convert.ToUInt16(dateTime.Second),
167 | milliseconds = Convert.ToUInt16(dateTime.Millisecond)
168 | };
169 | return sysTime;
170 | }
171 | #endregion
172 |
173 | #region 私有方法
174 | ///
175 | /// 将TimeZoneInformation转换为自定义string
176 | ///
177 | ///
178 | ///
179 | private static string TimeZoneInfo2CustomString(TimeZoneInformation tzi)
180 | {
181 | return tzi.standardName + "(" + tzi.bias + ")";
182 | }
183 |
184 | ///
185 | /// 将DynamicTimeZoneInformation转换为自定义string
186 | ///
187 | ///
188 | ///
189 | private static string DynamicTimeZoneInfo2CustomString(DynamicTimeZoneInformation dtzi)
190 | {
191 | return dtzi.standardName + "(" + dtzi.bias + ")";
192 | }
193 |
194 | ///
195 | /// 根据时区名获取对应的DynamicTimeZoneInformation
196 | ///
197 | ///
198 | ///
199 | private static DynamicTimeZoneInformation TimeZoneName2DynamicTimeZoneInformation(string timeZoneName)
200 | {
201 | TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
202 |
203 | DynamicTimeZoneInformation dtzi = new DynamicTimeZoneInformation
204 | {
205 | standardName = timeZoneInfo.StandardName,
206 | standardDate = new SystemTime(),
207 | daylightName = timeZoneInfo.DaylightName,
208 | daylightDate = new SystemTime(),
209 | timeZoneKeyName = timeZoneInfo.Id,
210 | dynamicDaylightTimeDisabled = false,
211 | bias = -Convert.ToInt32(timeZoneInfo.BaseUtcOffset.TotalMinutes)
212 | };
213 | return dtzi;
214 | }
215 |
216 | ///
217 | /// 将DynamicTimeZoneInformation转换为TimeZoneInformation
218 | ///
219 | ///
220 | ///
221 | private static TimeZoneInformation DynamicTimeZoneInformation2TimeZoneInformation(DynamicTimeZoneInformation dtzi)
222 | {
223 | return new TimeZoneInformation
224 | {
225 | bias = dtzi.bias,
226 | standardName = dtzi.standardName,
227 | standardDate = dtzi.standardDate,
228 | standardBias = dtzi.standardBias,
229 | daylightName = dtzi.daylightName,
230 | daylightDate = dtzi.daylightDate,
231 | daylightBias = dtzi.daylightBias
232 | };
233 | }
234 | #endregion
235 | }
236 | }
237 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Shell32/Shell32Base.Struct.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace Utils.WindowsApi
10 | {
11 | public partial class Shell32Base
12 | {
13 | ///
14 | /// 文件信息标识枚举类,所有枚举定义值前省略SHGFI投标,比如Icon 完整名称应为SHGFI_ICON
15 | ///
16 | [Flags]
17 | public enum SHFileInfoFlags : uint
18 | {
19 | ///
20 | /// 允许有叠加图案的文件图标,该标识必须和Icon同时使用
21 | ///
22 | AddOveylays = 0x20, // SHGFI_AddOverlays = 0x000000020
23 | ///
24 | /// 只获取由参数FileAttribute指定的文件信息,并将其写入SHFileInfo结构的dwAttributes属性,如果不指定该标识,将同时获取所有文件信息。该标志不能和Icon标识同时使用
25 | ///
26 | Attr_Specified = 0x20000, // SHGFI_SpecifiedAttributes = 0x000020000
27 | ///
28 | /// 将获取的文件属性复制到SHFileInfo结构的dwAttributes属性中
29 | ///
30 | Attributes = 0x800, // SHGFI_Attributes = 0x000000800
31 | ///
32 | /// 获取文件的显示名称(长文件名称),将其复制到SHFileInfo结构的dwAttributes属性中
33 | ///
34 | DisplayName = 0x200, // SHGFI_DisplayName = 0x000000200
35 | ///
36 | /// 如果文件是可执行文件,将检索其信息,并将信息作为返回值返回
37 | ///
38 | ExeType = 0x2000, // SHGFI_EXEType = 0x000002000
39 | ///
40 | /// 获得图标和索引,将图标句柄返回到SHFileInfo结构的hIcon属性中,索引返回到iIcon属性中
41 | ///
42 | Icon = 0x100, // SHGFI_Icon = 0x000000100
43 | ///
44 | /// 检索包含图标的文件,并将文件名,图标句柄,图标索引号,放回到SHFileInfo结构中
45 | ///
46 | IconLocation = 0x1000, // SHGFI_IconLocation = 0x000001000
47 | ///
48 | /// 获得大图标,该标识必须和Icon标识同时使用
49 | ///
50 | LargeIcon = 0x0, // SHGFI_LargeIcon = 0x000000000
51 | ///
52 | /// 获取链接覆盖文件图标,该标识必须和Icon标识同时使用。
53 | ///
54 | LinkOverlay = 0x8000, // SHGFI_LinkOverlay = 0x000008000
55 | ///
56 | /// 获取文件打开时的图标,该标识必须和Icon或SysIconIndex同时使用
57 | ///
58 | OpenIcon = 0x2, // SHGFI_OpenIcon = 0x000000002
59 | ///
60 | /// 获取链接覆盖文件图标索引,该标识必须和Icon标识同时使用。
61 | ///
62 | OverlayIndex = 0x40, // SHGFI_OverlayIndex = 0x000000040
63 | ///
64 | /// 指示传入的路径是一个ITEMIDLIST结构的文件地址而不是一个路径名。
65 | ///
66 | Pidl = 0x8, // SHGFI_PIDL = 0x000000008
67 | ///
68 | /// 获取系统的高亮显示图标,该标识必须和Icon标识同时使用。
69 | ///
70 | Selected = 0x10000, // SHGFI_SelectedState = 0x000010000
71 | ///
72 | /// 获取 Shell-sized icon ,该标志必须和Icon标识同时使用。
73 | ///
74 | ShellIconSize = 0x4, // SHGFI_ShellIconSize = 0x000000004
75 | ///
76 | /// 获得小图标,该标识必须和Icon或SysIconIndex同时使用。
77 | ///
78 | SmallIcon = 0x1, // SHGFI_SmallIcon = 0x000000001
79 | ///
80 | /// 获取系统图像列表图标索引,返回系统图像列表句柄
81 | ///
82 | SysIconIndex = 0x4000, // SHGFI_SysIconIndex = 0x000004000
83 | ///
84 | /// 获得文件类型,类型字符串被写入SHFileInfo结构的szTypeName属性中
85 | ///
86 | TypeName = 0x400, // SHGFI_TypeName = 0x000000400
87 | ///
88 | /// 指示如果由pszPath指定的路径不存在,SHGetFileInfo方法变不会试图去操作文件。指示返回与文件类型相关的信息。该标识不能和Attributes、ExeType和Pidl同时使用
89 | ///
90 | UseFileAttributes = 0x10 // SHGFI_UserFileAttributes = 0x000000010,
91 | }
92 |
93 | ///
94 | /// 文件属性枚举
95 | ///
96 | [Flags]
97 | public enum FileAttribute
98 | {
99 | ReadOnly = 0x00000001,
100 | Hidden = 0x00000002,
101 | System = 0x00000004,
102 | Directory = 0x00000010, //路径信息
103 | Archive = 0x00000020,
104 | Device = 0x00000040,
105 | Normal = 0x00000080, //普通文件信息
106 | Temporary = 0x00000100,
107 | Sparse_File = 0x00000200,
108 | Reparse_Point = 0x00000400,
109 | Compressed = 0x00000800,
110 | Offline = 0x00001000,
111 | Not_Content_Indexed = 0x00002000,
112 | Encrypted = 0x00004000
113 | }
114 |
115 | ///
116 | /// 定义返回的文件信息结构
117 | ///
118 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
119 | public struct SHFileInfo
120 | {
121 | ///
122 | /// 文件的图标句柄
123 | ///
124 | public IntPtr hIcon;
125 | ///
126 | /// 图标的系统索引号
127 | ///
128 | public IntPtr iIcon;
129 | ///
130 | /// 文件的属性值,由FileAttribute指定的属性。
131 | ///
132 | public uint dwAttributes;
133 | ///
134 | /// 文件的显示名,如果是64位系统,您可能需要制定SizeConst=258而非260才能够显示完整的 TypeName
135 | ///
136 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
137 | public string szDisplayName;
138 | ///
139 | /// 文件的类型名
140 | ///
141 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
142 | public string szTypeName;
143 | }
144 |
145 | ///
146 | /// 系统图标大小标识
147 | ///
148 | public enum IMAGELIST_SIZE_FLAG : int
149 | {
150 | ///
151 | /// Size(32,32)
152 | ///
153 | SHIL_LARGE = 0x0,
154 | ///
155 | /// Size(16,16)
156 | ///
157 | SHIL_SMALL = 0x1,
158 | ///
159 | /// Size(48,48)
160 | ///
161 | SHIL_EXTRALARGE = 0x2,
162 | ///
163 | /// Size(16,16)
164 | ///
165 | SHIL_SYSSMALL = 0x3,
166 | ///
167 | /// Size(256,256)
168 | ///
169 | SHIL_JUMBO = 0x4,
170 | ///
171 | /// 保留使用:目前测试效果为Size(256,256)
172 | ///
173 | SHIL_LAST = 0x4,
174 | }
175 |
176 |
177 | [ComImportAttribute()]
178 | [GuidAttribute("192B9D83-50FC-457B-90A0-2B82A8B5DAE1")]
179 | [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
180 | public interface IImageList
181 | {
182 | [PreserveSig]
183 | int Add(IntPtr hbmImage, IntPtr hbmMask, ref int pi);
184 |
185 | [PreserveSig]
186 | int ReplaceIcon(int i, IntPtr hicon, ref int pi);
187 |
188 | [PreserveSig]
189 | int SetOverlayImage(int iImage, int iOverlay);
190 |
191 | [PreserveSig]
192 | int Replace(int i, IntPtr hbmImage, IntPtr hbmMask);
193 |
194 | [PreserveSig]
195 | int AddMasked(IntPtr hbmImage, int crMask, ref int pi);
196 |
197 | [PreserveSig]
198 | int Draw(ref IMAGELISTDRAWPARAMS pimldp);
199 |
200 | [PreserveSig]
201 | int Remove(int i);
202 |
203 | [PreserveSig]
204 | int GetIcon(int i, int flags, ref IntPtr picon);
205 |
206 | [PreserveSig]
207 | int GetImageInfo(int i, ref IMAGEINFO pImageInfo);
208 |
209 | [PreserveSig]
210 | int Copy(int iDst, IImageList punkSrc, int iSrc, int uFlags);
211 |
212 | [PreserveSig]
213 | int Merge(int i1, IImageList punk2, int i2, int dx, int dy, ref Guid riid, ref IntPtr ppv);
214 |
215 | [PreserveSig]
216 | int Clone(ref Guid riid, ref IntPtr ppv);
217 |
218 | [PreserveSig]
219 | int GetImageRect(int i, ref RECT prc);
220 |
221 | [PreserveSig]
222 | int GetIconSize(ref int cx, ref int cy);
223 |
224 | [PreserveSig]
225 | int SetIconSize(int cx, int cy);
226 |
227 | [PreserveSig]
228 | int GetImageCount(ref int pi);
229 |
230 | [PreserveSig]
231 | int SetImageCount(int uNewCount);
232 |
233 | [PreserveSig]
234 | int SetBkColor(int clrBk, ref int pclr);
235 |
236 | [PreserveSig]
237 | int GetBkColor(ref int pclr);
238 |
239 | [PreserveSig]
240 | int BeginDrag(int iTrack, int dxHotspot, int dyHotspot);
241 |
242 | [PreserveSig]
243 | int EndDrag();
244 |
245 | [PreserveSig]
246 | int DragEnter(IntPtr hwndLock, int x, int y);
247 |
248 | [PreserveSig]
249 | int DragLeave(IntPtr hwndLock);
250 |
251 | [PreserveSig]
252 | int DragMove(int x, int y);
253 |
254 | [PreserveSig]
255 | int SetDragCursorImage(ref IImageList punk, int iDrag, int dxHotspot, int dyHotspot);
256 |
257 | [PreserveSig]
258 | int DragShowNolock(int fShow);
259 |
260 | [PreserveSig]
261 | int GetDragImage(ref POINT ppt, ref POINT pptHotspot, ref Guid riid, ref IntPtr ppv);
262 |
263 | [PreserveSig]
264 | int GetItemFlags(int i, ref int dwFlags);
265 |
266 | [PreserveSig]
267 | int GetOverlayImage(int iOverlay, ref int piIndex);
268 | };
269 |
270 | [StructLayout(LayoutKind.Sequential)]
271 | public struct IMAGELISTDRAWPARAMS
272 | {
273 | public int cbSize;
274 | public IntPtr himl;
275 | public int i;
276 | public IntPtr hdcDst;
277 | public int x;
278 | public int y;
279 | public int cx;
280 | public int cy;
281 | public int xBitmap; // x offest from the upperleft of bitmap
282 | public int yBitmap; // y offset from the upperleft of bitmap
283 | public int rgbBk;
284 | public int rgbFg;
285 | public int fStyle;
286 | public int dwRop;
287 | public int fState;
288 | public int Frame;
289 | public int crEffect;
290 | }
291 |
292 | [StructLayout(LayoutKind.Sequential)]
293 | public struct IMAGEINFO
294 | {
295 | public IntPtr hbmImage;
296 | public IntPtr hbmMask;
297 | public int Unused1;
298 | public int Unused2;
299 | public RECT rcImage;
300 | }
301 |
302 | [StructLayout(LayoutKind.Sequential)]
303 | public struct RECT
304 | {
305 | public int left, top, right, bottom;
306 | }
307 |
308 | [StructLayout(LayoutKind.Sequential)]
309 | public struct POINT
310 | {
311 | int x;
312 | int y;
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Shell32/Shell32Base.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace Utils.WindowsApi
10 | {
11 | public partial class Shell32Base
12 | {
13 | private const string Shell32 = "shell32.dll";
14 |
15 | ///
16 | /// 引用shell32文件的SHGetFileInfo API方法
17 | ///
18 | /// 指定的文件名,如果为""则返回文件夹的
19 | /// 文件属性
20 | /// 返回获得的文件信息,是一个记录类型
21 | /// 文件的类型名
22 | /// 文件信息标识
23 | /// -1失败
24 | [DllImport(Shell32, EntryPoint = "SHGetFileInfo", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
25 | public static extern IntPtr SHGetFileInfo(string pszPath, FileAttribute dwFileAttributes, ref SHFileInfo sfi, uint cbFileInfo, SHFileInfoFlags uFlags);
26 |
27 | ///
28 | /// 返回系统设置的图标
29 | ///
30 | /// 文件名,指定从exe文件或dll文件引入icon
31 | /// 文件的图表中的第几个,指定icon的索引如果为0则从指定的文件中引入第1个icon
32 | /// 返回的大图标的指针,大图标句柄如果为null则为没有大图标
33 | /// 返回的小图标的指针,小图标句柄如果为null则为没有小图标
34 | /// ico个数,找几个图标
35 | ///
15 | /// 当读取文件图标失败的默认图标索引号
16 | ///
17 | public static readonly long ErrorFileIndex = -2;
18 | ///
19 | /// 当读取文件夹图标失败的默认图标索引号
20 | ///
21 | public static readonly long ErrorFolderIndex = -4;
22 | ///
23 | /// 当读取磁盘驱动器图标失败的默认图标索引号
24 | ///
25 | public static readonly long ErrorDriverIndex = -8;
26 | ///
27 | /// 当读取可执行文件图标失败的默认图标索引号
28 | ///
29 | public static readonly long ErrorApplicationIndex = -16;
30 |
31 | ///
32 | /// 获取文件类型的关联图标
33 | ///
34 | /// 文件类型的扩展名或文件的绝对路径
35 | /// 是否返回小图标
36 | /// 返回一个Icon类型的文件图标对象
37 | public static Icon GetFileIcon(string fileName, bool isSmallIcon)
38 | {
39 | long imageIndex;
40 | return GetFileIcon(fileName, isSmallIcon, out imageIndex);
41 | }
42 |
43 | ///
44 | /// 获取系统文件图标
45 | ///
46 | /// 文件类型的扩展名或文件的绝对路径,如果是一个exe可执行文件,请提供完整的文件名(包含路径信息)
47 | /// 是否返回小图标
48 | /// 输出与返回图标对应的系统图标索引号
49 | /// 返回一个Icon类型的文件图标对象
50 | public static Icon GetFileIcon(string fileName, bool isSmallIcon, out long imageIndex)
51 | {
52 | imageIndex = ErrorFileIndex;
53 | if (String.IsNullOrEmpty(fileName))
54 | return null;
55 |
56 | SHFileInfo shfi = new SHFileInfo();
57 | SHFileInfoFlags uFlags = SHFileInfoFlags.Icon | SHFileInfoFlags.ShellIconSize;
58 | if (isSmallIcon)
59 | uFlags |= SHFileInfoFlags.SmallIcon;
60 | else
61 | uFlags |= SHFileInfoFlags.LargeIcon;
62 | FileInfo fi = new FileInfo(fileName);
63 | if (fi.Name.ToUpper().EndsWith(".EXE"))
64 | uFlags |= SHFileInfoFlags.ExeType;
65 | else
66 | uFlags |= SHFileInfoFlags.UseFileAttributes;
67 |
68 | int iTotal = (int)SHGetFileInfo(fileName, FileAttribute.Normal, ref shfi, (uint)Marshal.SizeOf(shfi), uFlags);
69 | //或int iTotal = (int)SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), uFlags);
70 | Icon icon = null;
71 | if (iTotal > 0)
72 | {
73 | icon = Icon.FromHandle(shfi.hIcon).Clone() as Icon;
74 | imageIndex = shfi.iIcon.ToInt64();
75 | }
76 | User32Base.DestroyIcon(shfi.hIcon); //释放资源
77 | return icon;
78 | }
79 |
80 | ///
81 | /// 获取系统文件夹默认图标
82 | ///
83 | /// 是否返回小图标
84 | /// 返回一个Icon类型的文件夹图标对象
85 | public static Icon GetFolderIcon(bool isSmallIcon)
86 | {
87 | long imageIndex;
88 | return GetFolderIcon(isSmallIcon, out imageIndex);
89 | }
90 |
91 | ///
92 | /// 获取系统文件夹默认图标
93 | ///
94 | /// 是否返回小图标
95 | /// 输出与返回图标对应的系统图标索引号
96 | /// 返回一个Icon类型的文件夹图标对象
97 | public static Icon GetFolderIcon(bool isSmallIcon, out long imageIndex)
98 | {
99 | return GetFolderIcon(Environment.SystemDirectory, isSmallIcon, out imageIndex);
100 | }
101 |
102 | ///
103 | /// 获取系统文件夹默认图标
104 | ///
105 | /// 文件夹名称,如果想获取自定义文件夹图标,请指定完整的文件夹名称(如 F:\test)
106 | /// 是否返回小图标
107 | /// 输出与返回图标对应的系统图标索引号
108 | /// 返回一个Icon类型的文件夹图标对象
109 | public static Icon GetFolderIcon(string folderName, bool isSmallIcon, out long imageIndex)
110 | {
111 | imageIndex = ErrorFolderIndex;
112 | if (String.IsNullOrEmpty(folderName))
113 | return null;
114 |
115 | SHFileInfo shfi = new SHFileInfo();
116 | SHFileInfoFlags uFlags = SHFileInfoFlags.Icon | SHFileInfoFlags.ShellIconSize | SHFileInfoFlags.UseFileAttributes;
117 | if (isSmallIcon)
118 | uFlags |= SHFileInfoFlags.SmallIcon;
119 | else
120 | uFlags |= SHFileInfoFlags.LargeIcon;
121 |
122 | int iTotal = (int)SHGetFileInfo(folderName, FileAttribute.Directory, ref shfi, (uint)Marshal.SizeOf(shfi), uFlags);
123 | //或int iTotal = (int)SHGetFileInfo("", 0, ref shfi, (uint)Marshal.SizeOf(shfi), SHFileInfoFlags.Icon | SHFileInfoFlags.SmallIcon);
124 | Icon icon = null;
125 | if (iTotal > 0)
126 | {
127 | icon = Icon.FromHandle(shfi.hIcon).Clone() as Icon;
128 | imageIndex = shfi.iIcon.ToInt64();
129 | }
130 | User32Base.DestroyIcon(shfi.hIcon); //释放资源
131 | return icon;
132 | }
133 |
134 | ///
135 | /// 获取磁盘驱动器图标
136 | ///
137 | /// 有效的磁盘标号,如C、D、I等等,不区分大小写
138 | /// 标识是获取小图标还是获取大图标
139 | /// 输出与返回图标对应的系统图标索引号
140 | /// 返回一个Icon类型的磁盘驱动器图标对象
141 | public static Icon GetDriverIcon(char driverMark, bool isSmallIcon)
142 | {
143 | long imageIndex;
144 | return GetDriverIcon(driverMark, isSmallIcon, out imageIndex);
145 | }
146 |
147 | ///
148 | /// 获取磁盘驱动器图标
149 | ///
150 | /// 有效的磁盘标号,如C、D、I等等,不区分大小写
151 | /// 标识是获取小图标还是获取大图标
152 | /// 输出与返回图标对应的系统图标索引号
153 | /// 返回一个Icon类型的磁盘驱动器图标对象
154 | public static Icon GetDriverIcon(char driverMark, bool isSmallIcon, out long imageIndex)
155 | {
156 | imageIndex = ErrorDriverIndex;
157 | //非有效盘符,返回封装的磁盘图标
158 | if (driverMark < 'a' && driverMark > 'z' && driverMark < 'A' && driverMark > 'Z')
159 | {
160 | return null;
161 | }
162 | string driverName = driverMark.ToString().ToUpper() + ":\\";
163 |
164 | SHFileInfo shfi = new SHFileInfo();
165 | SHFileInfoFlags uFlags = SHFileInfoFlags.Icon | SHFileInfoFlags.ShellIconSize | SHFileInfoFlags.UseFileAttributes;
166 | if (isSmallIcon)
167 | uFlags |= SHFileInfoFlags.SmallIcon;
168 | else
169 | uFlags |= SHFileInfoFlags.LargeIcon;
170 | int iTotal = (int)SHGetFileInfo(driverName, FileAttribute.Normal, ref shfi, (uint)Marshal.SizeOf(shfi), uFlags);
171 | //int iTotal = (int)SHGetFileInfo(driverName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), uFlags);
172 | Icon icon = null;
173 | if (iTotal > 0)
174 | {
175 | icon = Icon.FromHandle(shfi.hIcon).Clone() as Icon;
176 | imageIndex = shfi.iIcon.ToInt64();
177 | }
178 | User32Base.DestroyIcon(shfi.hIcon); //释放资源
179 | return icon;
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/User32/User32Base.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class User32Base
11 | {
12 | private const string User32 = "user32.dll";
13 |
14 | #region Field
15 | public const int GWL_HWNDPARENT = -8;
16 |
17 | public const int SE_PRIVILEGE_ENABLED = 0x00000002;
18 |
19 | public const int TOKEN_QUERY = 0x00000008;
20 |
21 | public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
22 |
23 | public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
24 |
25 | ///
26 | /// 检索桌面壁纸的位图文件的完整路径
27 | ///
28 | public const uint SPI_GETDESKWALLPAPER = 0x0073;
29 | #endregion
30 |
31 | #region Structures
32 |
33 | [StructLayout(LayoutKind.Sequential)]
34 | internal struct LASTINPUTINFO
35 | {
36 | public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
37 |
38 | [MarshalAs(UnmanagedType.U4)]
39 | public int cbSize;
40 |
41 | [MarshalAs(UnmanagedType.U4)]
42 | public UInt32 dwTime;
43 | }
44 |
45 | // 映射 DEVMODE 结构
46 | // 可以参照 DEVMODE结构的指针定义:
47 | // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx
48 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
49 | public struct DEVMODE
50 | {
51 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
52 | public string dmDeviceName;
53 |
54 | public short dmSpecVersion;
55 | public short dmDriverVersion;
56 | public short dmSize;
57 | public short dmDriverExtra;
58 | public int dmFields;
59 | public int dmPositionX;
60 | public int dmPositionY;
61 | public int dmDisplayOrientation;
62 | public int dmDisplayFixedOutput;
63 | public short dmColor;
64 | public short dmDuplex;
65 | public short dmYResolution;
66 | public short dmTTOption;
67 | public short dmCollate;
68 |
69 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
70 | public string dmFormName;
71 |
72 | public short dmLogPixels;
73 | public short dmBitsPerPel;
74 | public int dmPelsWidth;
75 | public int dmPelsHeight;
76 | public int dmDisplayFlags;
77 | public int dmDisplayFrequency;
78 | public int dmICMMethod;
79 | public int dmICMIntent;
80 | public int dmMediaType;
81 | public int dmDitherType;
82 | public int dmReserved1;
83 | public int dmReserved2;
84 | public int dmPanningWidth;
85 | public int dmPanningHeight;
86 | };
87 |
88 | [StructLayout(LayoutKind.Sequential)]
89 | public struct DevBroadcastDeviceInterface
90 | {
91 | internal int Size;
92 | internal int DeviceType;
93 | internal int Reserved;
94 | internal Guid ClassGuid;
95 | internal short Name;
96 | }
97 |
98 | [StructLayout(LayoutKind.Sequential)]
99 | public struct DevBroadcastHdr
100 | {
101 | internal UInt32 Size;
102 | internal UInt32 DeviceType;
103 | internal UInt32 Reserved;
104 | }
105 |
106 | [Flags]
107 | public enum ExitWindows : uint
108 | {
109 | ///
110 | /// 注销
111 | ///
112 | LoginOff = 0x00,
113 | ///
114 | /// 关机
115 | ///
116 | ShutDown = 0x01,
117 | ///
118 | /// 重启
119 | ///
120 | Reboot = 0x02,
121 | Force = 0x04,
122 | PowerOff = 0x08,
123 | ForceIfHung = 0x10
124 | }
125 |
126 | [Flags]
127 | public enum ShutdownReason : uint
128 | {
129 | MajorApplication = 0x00040000,
130 | MajorHardware = 0x00010000,
131 | MajorLegacyApi = 0x00070000,
132 | MajorOperatingSystem = 0x00020000,
133 | MajorOther = 0x00000000,
134 | MajorPower = 0x00060000,
135 | MajorSoftware = 0x00030000,
136 | MajorSystem = 0x00050000,
137 | MinorBlueScreen = 0x0000000F,
138 | MinorCordUnplugged = 0x0000000b,
139 | MinorDisk = 0x00000007,
140 | MinorEnvironment = 0x0000000c,
141 | MinorHardwareDriver = 0x0000000d,
142 | MinorHotfix = 0x00000011,
143 | MinorHung = 0x00000005,
144 | MinorInstallation = 0x00000002,
145 | MinorMaintenance = 0x00000001,
146 | MinorMMC = 0x00000019,
147 | MinorNetworkConnectivity = 0x00000014,
148 | MinorNetworkCard = 0x00000009,
149 | MinorOther = 0x00000000,
150 | MinorOtherDriver = 0x0000000e,
151 | MinorPowerSupply = 0x0000000a,
152 | MinorProcessor = 0x00000008,
153 | MinorReconfig = 0x00000004,
154 | MinorSecurity = 0x00000013,
155 | MinorSecurityFix = 0x00000012,
156 | MinorSecurityFixUninstall = 0x00000018,
157 | MinorServicePack = 0x00000010,
158 | MinorServicePackUninstall = 0x00000016,
159 | MinorTermSrv = 0x00000020,
160 | MinorUnstable = 0x00000006,
161 | MinorUpgrade = 0x00000003,
162 | MinorWMI = 0x00000015,
163 | FlagUserDefined = 0x40000000,
164 | FlagPlanned = 0x80000000
165 | }
166 |
167 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
168 | public struct TokPriv1Luid
169 | {
170 | public int Count;
171 | public long Luid;
172 | public int Attr;
173 | }
174 | #endregion
175 |
176 | #region P/Invoke Functions
177 |
178 | [DllImport(User32)]
179 | internal static extern int Mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
180 |
181 | [DllImport(User32)]
182 | internal static extern int Keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
183 |
184 | [DllImport(User32)]
185 | internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
186 |
187 | [DllImport(User32)]
188 | internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
189 |
190 | ///
191 | /// 设置窗体父窗体
192 | ///
193 | /// 子窗体句柄
194 | /// 父窗体句柄
195 | ///
196 | [DllImport(User32)]
197 | internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
198 |
199 | ///
200 | /// 得到对应名称Window的句柄
201 | ///
202 | /// Window所属类
203 | /// Window名称
204 | ///
205 | [DllImport(User32, SetLastError = true)]
206 | internal static extern IntPtr FindWindow(string lpWindowClass, string lpWindowName);
207 |
208 | ///
209 | /// 得到指定窗口的子窗口
210 | ///
211 | ///
212 | ///
213 | ///
214 | internal delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
215 | [DllImport(User32)]
216 | [return: MarshalAs(UnmanagedType.Bool)]
217 | internal static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
218 |
219 | [DllImport(User32, SetLastError = true)]
220 | internal static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
221 |
222 | [DllImport(User32, SetLastError = true)]
223 | internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
224 |
225 | [DllImport(User32, SetLastError = true)]
226 | internal static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
227 |
228 | [DllImport(User32)]
229 | internal static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
230 |
231 | ///
232 | /// 枚举显示器设置
233 | ///
234 | /// 显示器名称
235 | /// 参数类型
236 | /// 参数结构
237 | ///
238 | [DllImport(User32)]
239 | internal static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
240 |
241 | ///
242 | /// 改变显示设置
243 | ///
244 | /// 参数结构
245 | ///
246 | ///
247 | [DllImport(User32)]
248 | internal static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);
249 |
250 | ///
251 | /// 注册设备通知
252 | ///
253 | ///
254 | ///
255 | ///
256 | ///
257 | [DllImport(User32, CharSet = CharSet.Auto, SetLastError = true)]
258 | internal static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags);
259 |
260 | ///
261 | /// 取消设备通知
262 | ///
263 | ///
264 | ///
265 | [DllImport(User32)]
266 | internal static extern bool UnregisterDeviceNotification(IntPtr handle);
267 |
268 | [DllImport(User32)]
269 | internal static extern bool ExitWindowsEx(ExitWindows uFlags, ShutdownReason dwReason);
270 |
271 | ///
272 | /// 检索或设置系统范围参数(sting类型)
273 | ///
274 | ///
275 | ///
276 | ///
277 | ///
278 | ///
279 | [DllImport(User32, CharSet = CharSet.Auto, SetLastError = true)]
280 | internal static extern bool SystemParametersInfo(uint uAction, uint uParam, StringBuilder lpvParam, uint init);
281 |
282 | [DllImport(User32, EntryPoint = "DestroyIcon")]
283 | public static extern int DestroyIcon(IntPtr hIcon);
284 | #endregion
285 | }
286 | }
287 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/User32/User32Extension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class User32Extension : User32Base
11 | {
12 | #region Field
13 | private const int WM_SYSCOMMAND = 0x112; //系统消息
14 | private const int SC_SCREENSAVE = 0xf140; // 启动屏幕保护消息
15 | private const int SC_MONITORPOWER = 0xF170; //关闭显示器的系统命令
16 | private const int POWER_OFF = 2; //2 为关闭, 1为省电状态,-1为开机
17 | private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff); //广播消息,所有顶级窗体都会接收
18 | //移动鼠标
19 | public const int MOUSEEVENTF_MOVE = 0x0001;
20 | //模拟鼠标左键按下
21 | public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
22 | //模拟鼠标左键抬起
23 | public const int MOUSEEVENTF_LEFTUP = 0x0004;
24 | //模拟鼠标右键按下
25 | public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
26 | //模拟鼠标右键抬起
27 | public const int MOUSEEVENTF_RIGHTUP = 0x0010;
28 | //模拟鼠标中键按下
29 | public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
30 | //模拟鼠标中键抬起
31 | public const int MOUSEEVENTF_MIDDLEUP = 0x0040;
32 | //标示是否采用绝对坐标
33 | public const int MOUSEEVENTF_ABSOLUTE = 0x8000;
34 | //模拟鼠标滚轮滚动操作,必须配合dwData参数
35 | public const int MOUSEEVENTF_WHEEL = 0x0800;
36 |
37 | // 控制改变屏幕分辨率的常量
38 | public const int ENUM_CURRENT_SETTINGS = -1;
39 | public const int CDS_UPDATEREGISTRY = 0x01;
40 | public const int CDS_TEST = 0x02;
41 | public const int DISP_CHANGE_SUCCESSFUL = 0;
42 | public const int DISP_CHANGE_RESTART = 1;
43 | public const int DISP_CHANGE_FAILED = -1;
44 |
45 | // 控制改变方向的常量定义
46 | public const int DMDO_DEFAULT = 0;
47 | public const int DMDO_90 = 1;
48 | public const int DMDO_180 = 2;
49 | public const int DMDO_270 = 3;
50 |
51 | //注册设备消息相关
52 | public const int DbtDeviceArrival = 0x8000; // System detected a new device
53 | public const int DbtDeviceRemoveComplete = 0x8004; // Device is gone
54 | public const int WmDeviceChange = 0x0219; // Device change event
55 | private const int DbtDeviceTypeDeviceInterface = 5;
56 | // https://docs.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-usb-device
57 | private static readonly Guid GuidDeviceInterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // USB devices
58 | // https://docs.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-monitor
59 | private static readonly Guid GuidDeviceInterfaceMonitorDevice = new Guid("E6F07B5F-EE97-4a90-B076-33F57BF4EAA7"); // Monitor devices
60 | private static IntPtr usbNotificationHandle;
61 | private static IntPtr monitorNotificationHandle;
62 | #endregion
63 |
64 | #region Function
65 | ///
66 | /// 虚拟鼠标操作
67 | ///
68 | ///
69 | ///
70 | ///
71 | ///
72 | ///
73 | public static void SimulateMouseOperation(int flags, int dx, int dy, int dData, int dwExtraInfo)
74 | {
75 | User32Base.Mouse_event(flags, dx, dy, dData, dwExtraInfo);
76 | }
77 |
78 | ///
79 | /// 进行一次简单的鼠标操作
80 | ///
81 | public static void ClearFreeTime()
82 | {
83 | User32Base.Keybd_event(39, 0, 0, 0);
84 | User32Base.Keybd_event(39, 0, 2, 0);
85 | }
86 |
87 | ///
88 | /// 获取电脑最后输入时间
89 | ///
90 | ///
91 | public static int GetLastInputTime()
92 | {
93 | int idleTime = 0;
94 |
95 | LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
96 |
97 | lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
98 |
99 | lastInputInfo.dwTime = 0;
100 |
101 | int envTicks = Environment.TickCount;
102 |
103 | if (GetLastInputInfo(ref lastInputInfo))
104 | {
105 | int lastInputTick = Convert.ToInt32(lastInputInfo.dwTime);
106 |
107 | idleTime = envTicks - lastInputTick;
108 | }
109 |
110 | int toret = ((idleTime > 0) ? (idleTime / 1000) : 0);
111 |
112 | return toret;
113 | }
114 |
115 | ///
116 | /// 关闭显示器
117 | ///
118 | public static void TurnOffScreen()
119 | {
120 | SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, POWER_OFF); // 关闭显示器
121 | }
122 |
123 | ///
124 | /// 返回窗口子窗口指针列表
125 | /// Returns a list of child windows
126 | ///
127 | /// Parent of the windows to return
128 | /// List of child windows
129 | public static List GetChildWindows(IntPtr parent)
130 | {
131 | List result = new List();
132 | GCHandle listHandle = GCHandle.Alloc(result);
133 | try
134 | {
135 | EnumWindowsProc childProc = new EnumWindowsProc(EnumWindow);
136 | EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
137 | }
138 | finally
139 | {
140 | if (listHandle.IsAllocated)
141 | listHandle.Free();
142 | }
143 | return result;
144 | }
145 |
146 | ///
147 | /// 枚举子窗口的回调方法
148 | /// Callback method to be used when enumerating windows.
149 | ///
150 | /// Handle of the next window
151 | /// Pointer to a GCHandle that holds a reference to the list to fill
152 | /// True to continue the enumeration, false to bail
153 | private static bool EnumWindow(IntPtr handle, IntPtr pointer)
154 | {
155 | GCHandle gch = GCHandle.FromIntPtr(pointer);
156 | List list = gch.Target as List;
157 | if (list == null)
158 | {
159 | throw new InvalidCastException("GCHandle Target could not be cast as List");
160 | }
161 | list.Add(handle);
162 | // You can modify this to check to see if you want to cancel the operation, then return a null here
163 | return true;
164 | }
165 |
166 | ///
167 | /// 改变分辨率
168 | ///
169 | ///
170 | ///
171 | public static ExecuteResult ChangeDisplayResolution(int width, int height)
172 | {
173 | // 初始化 DEVMODE结构
174 | DEVMODE devmode = new DEVMODE();
175 | devmode.dmDeviceName = new String(new char[32]);
176 | devmode.dmFormName = new String(new char[32]);
177 | devmode.dmSize = (short)Marshal.SizeOf(devmode);
178 |
179 | if (0 != EnumDisplaySettings(null, ENUM_CURRENT_SETTINGS, ref devmode))
180 | {
181 | devmode.dmPelsWidth = width;
182 | devmode.dmPelsHeight = height;
183 |
184 | // 改变屏幕分辨率
185 | int iRet = ChangeDisplaySettings(ref devmode, CDS_TEST);
186 |
187 | if (iRet == DISP_CHANGE_FAILED)
188 | {
189 | //MessageBox.Show("不能执行你的请求", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
190 | return ExecuteResult.Failed;
191 | }
192 | else
193 | {
194 | iRet = ChangeDisplaySettings(ref devmode, CDS_UPDATEREGISTRY);
195 |
196 | switch (iRet)
197 | {
198 | // 成功改变
199 | case DISP_CHANGE_SUCCESSFUL:
200 | {
201 | return ExecuteResult.Success;
202 | //break;
203 | }
204 | case DISP_CHANGE_RESTART:
205 | {
206 | // MessageBox.Show("你需要重新启动电脑设置才能生效", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
207 | return ExecuteResult.ReStart;
208 | //break;
209 | }
210 | default:
211 | {
212 | return ExecuteResult.Failed;
213 | // MessageBox.Show("改变屏幕分辨率失败", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
214 | //break;
215 | }
216 | }
217 | }
218 | }
219 | else
220 | {
221 | return ExecuteResult.Failed;
222 | }
223 | }
224 |
225 | ///
226 | /// 获取显示设置
227 | ///
228 | ///
229 | public static DEVMODE GetDisplaySettings()
230 | {
231 | // 初始化 DEVMODE结构
232 | DEVMODE devmode = new DEVMODE();
233 | devmode.dmDeviceName = new String(new char[32]);
234 | devmode.dmFormName = new String(new char[32]);
235 | devmode.dmSize = (short)Marshal.SizeOf(devmode);
236 |
237 | User32Base.EnumDisplaySettings(null, User32Extension.ENUM_CURRENT_SETTINGS, ref devmode);
238 |
239 | return devmode;
240 | }
241 |
242 | #region 注册设备消息相关
243 | public static bool IsMonitor(IntPtr lParam)
244 | {
245 | return IsDeviceOfClass(lParam, GuidDeviceInterfaceMonitorDevice);
246 | }
247 |
248 | public static bool IsUsbDevice(IntPtr lParam)
249 | {
250 | return IsDeviceOfClass(lParam, GuidDeviceInterfaceUSBDevice);
251 | }
252 | /// Registers a window to receive notifications when Monitor devices are plugged or unplugged.
253 | public static void RegisterMonitorDeviceNotification(IntPtr windowHandle)
254 | {
255 | var dbi = CreateBroadcastDeviceInterface(GuidDeviceInterfaceMonitorDevice);
256 | monitorNotificationHandle = RegisterDeviceNotification(dbi, windowHandle);
257 | }
258 |
259 | /// Registers a window to receive notifications when USB devices are plugged or unplugged.
260 | public static void RegisterUsbDeviceNotification(IntPtr windowHandle)
261 | {
262 | var dbi = CreateBroadcastDeviceInterface(GuidDeviceInterfaceUSBDevice);
263 | usbNotificationHandle = RegisterDeviceNotification(dbi, windowHandle);
264 | }
265 |
266 | /// UnRegisters the window for Monitor device notifications
267 | public static void UnRegisterMonitorDeviceNotification()
268 | {
269 | UnregisterDeviceNotification(monitorNotificationHandle);
270 | }
271 |
272 | /// UnRegisters the window for USB device notifications
273 | public static void UnRegisterUsbDeviceNotification()
274 | {
275 | UnregisterDeviceNotification(usbNotificationHandle);
276 | }
277 |
278 | private static bool IsDeviceOfClass(IntPtr lParam, Guid classGuid)
279 | {
280 | var hdr = Marshal.PtrToStructure(lParam);
281 |
282 | if (hdr.DeviceType != DbtDeviceTypeDeviceInterface)
283 | return false;
284 |
285 | var devIF = Marshal.PtrToStructure(lParam);
286 |
287 | return devIF.ClassGuid == classGuid;
288 |
289 | }
290 |
291 | private static IntPtr RegisterDeviceNotification(DevBroadcastDeviceInterface dbi, IntPtr windowHandle)
292 | {
293 | var buffer = Marshal.AllocHGlobal(dbi.Size);
294 | IntPtr handle;
295 |
296 | try
297 | {
298 | Marshal.StructureToPtr(dbi, buffer, true);
299 |
300 | handle = RegisterDeviceNotification(windowHandle, buffer, 0);
301 | }
302 | finally
303 | {
304 | // Free buffer
305 | Marshal.FreeHGlobal(buffer);
306 | }
307 |
308 | return handle;
309 | }
310 |
311 | private static DevBroadcastDeviceInterface CreateBroadcastDeviceInterface(Guid classGuid)
312 | {
313 | var dbi = new DevBroadcastDeviceInterface
314 | {
315 | DeviceType = DbtDeviceTypeDeviceInterface,
316 | Reserved = 0,
317 | ClassGuid = classGuid,
318 | Name = 0
319 | };
320 |
321 | dbi.Size = Marshal.SizeOf(dbi);
322 |
323 | return dbi;
324 | }
325 | #endregion
326 |
327 | ///
328 | /// 重启
329 | ///
330 | public static void ReBoot()
331 | {
332 | DoExitWindows(ExitWindows.Force | ExitWindows.Reboot);
333 | }
334 |
335 | ///
336 | /// 关机
337 | ///
338 | public static void ShutDown()
339 | {
340 | DoExitWindows(ExitWindows.Force | ExitWindows.ShutDown);
341 | }
342 |
343 | ///
344 | /// 注销
345 | ///
346 | public static void LoginOff()
347 | {
348 | DoExitWindows(ExitWindows.Force | ExitWindows.LoginOff);
349 | }
350 |
351 | ///
352 | /// 获取当前使用的桌面壁纸的路径
353 | ///
354 | ///
355 | public static bool GetDesktopWallpaper(out string wallPaperPath)
356 | {
357 | StringBuilder path = new StringBuilder(200);
358 | var result = SystemParametersInfo(SPI_GETDESKWALLPAPER, 200, path, 0);
359 | wallPaperPath = path.ToString();
360 | return result;
361 | }
362 | #endregion
363 |
364 | #region 私有方法
365 | ///
366 | /// 执行命令
367 | ///
368 | ///
369 | private static void DoExitWindows(ExitWindows flag)
370 | {
371 | TokPriv1Luid tp;
372 | IntPtr hproc = Kernel32Base.GetCurrentProcess();
373 | Advapi32Base.OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out IntPtr htok);
374 | tp.Count = 1;
375 | tp.Luid = 0;
376 | tp.Attr = SE_PRIVILEGE_ENABLED;
377 | Advapi32Base.LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
378 | Advapi32Base.AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
379 | ExitWindowsEx(flag, ShutdownReason.MajorOther);
380 | }
381 | #endregion
382 | }
383 | }
384 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Winmm/WinmmBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Utils.WindowsApi
9 | {
10 | public class WinmmBase
11 | {
12 | private const string Winmm = "winmm.dll";
13 |
14 | [DllImport(Winmm, EntryPoint = "waveOutSetVolume")]
15 | internal static extern int WaveOutSetVolume(IntPtr deviceID, uint Volume);
16 | [DllImport(Winmm, EntryPoint = "waveOutGetVolume")]
17 | internal static extern int WaveOutGetVolume(IntPtr deviceID, out uint Volume);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Winmm/WinmmExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Utils.WindowsApi
8 | {
9 | public class WinmmExtension:WinmmBase
10 | {
11 | private const uint iMaxValue = 0xFFFF;
12 | private const uint iMinValue = 0x0000;
13 | private static int iCurrentValue = 0;
14 |
15 | public static void SetSystemVolume(double arg)
16 | {
17 | double newVolume = ushort.MaxValue * arg / 10.0;
18 |
19 | uint v = ((uint)newVolume) & 0xffff;
20 | uint vAll = v | (v << 16);
21 |
22 | int retVal = WaveOutSetVolume(IntPtr.Zero, vAll);
23 | }
24 |
25 | private static void GetVolume()
26 | {
27 | //uint d, v;
28 | //d = 0;
29 | //long i = WaveOutGetVolume(d, out v);
30 | //uint vleft = v & 0xFFFF;
31 | //uint vright = (v & 0xFFFF0000) >> 16;
32 | //uint all = vleft | vright;
33 | //uint value = (all * uint.Parse((MaxValue - MinValue).ToString()) / ((UInt32)iMaxValue));
34 | //iCurrentValue = int.Parse(value.ToString());
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Wlanapi/WlanapiBase.Struct.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.NetworkInformation;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace Utils.WindowsApi
10 | {
11 | [StructLayout(LayoutKind.Sequential)]
12 | public struct WlanNotificationData
13 | {
14 | ///
15 | /// Specifies where the notification comes from.
16 | ///
17 | ///
18 | /// On Windows XP SP2, this field must be set to ,
19 | /// or .
20 | ///
21 | public WlanNotificationSource NotificationSource;
22 | ///
23 | /// Indicates the type of notification. The value of this field indicates what type of associated data will be present in .
24 | ///
25 | public int NotificationCode;
26 | ///
27 | /// Indicates which interface the notification is for.
28 | ///
29 | public Guid InterfaceGuid;
30 | ///
31 | /// Specifies the size of , in bytes.
32 | ///
33 | public int DataSize;
34 | ///
35 | /// Pointer to additional data needed for the notification, as indicated by .
36 | ///
37 | public IntPtr DataPtr;
38 |
39 | ///
40 | /// Gets the notification code (in the correct enumeration type) according to the notification source.
41 | ///
42 | public object WlanNotificationCode
43 | {
44 | get
45 | {
46 | if (NotificationSource == WlanNotificationSource.WLAN_NOTIFICATION_SOURCE_MSM)
47 | return (WlanNotificationCodeMsm)NotificationCode;
48 | else if (NotificationSource == WlanNotificationSource.WLAN_NOTIFICATION_SOURCE_ACM)
49 | return (WlanNotificationCodeAcm)NotificationCode;
50 | else
51 | return NotificationCode;
52 | }
53 |
54 | }
55 | }
56 |
57 | ///
58 | /// Contains information about a LAN interface.
59 | ///
60 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
61 | public struct WlanInterfaceInfo
62 | {
63 | ///
64 | /// The GUID of the interface.
65 | ///
66 | public Guid InterfaceGuid;
67 | ///
68 | /// The description of the interface.
69 | ///
70 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
71 | public string InterfaceDescription;
72 | ///
73 | /// The current state of the interface.
74 | ///
75 | public WlanInterfaceState State;
76 | }
77 |
78 | ///
79 | /// Contains information about connection related notifications.
80 | ///
81 | ///
82 | /// Corresponds to the native WLAN_CONNECTION_NOTIFICATION_DATA type.
83 | ///
84 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
85 | public struct WlanConnectionNotificationData
86 | {
87 | ///
88 | /// On Windows XP SP 2, only is supported.
89 | ///
90 | public WlanConnectionMode WlanConnectionMode;
91 | ///
92 | /// The name of the profile used for the connection. Profile names are case-sensitive.
93 | ///
94 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
95 | public string ProfileName;
96 | ///
97 | /// The SSID of the association.
98 | ///
99 | public Dot11Ssid Dot11Ssid;
100 | ///
101 | /// The BSS network type.
102 | ///
103 | public Dot11BssType Dot11BssType;
104 | ///
105 | /// Indicates whether security is enabled for this connection.
106 | ///
107 | public bool SecurityEnabled;
108 | ///
109 | /// Indicates the reason for an operation failure.
110 | /// This field has a value of for all connection-related notifications except .
111 | /// If the connection fails, this field indicates the reason for the failure.
112 | ///
113 | public WlanReasonCode WlanReasonCode;
114 | ///
115 | /// This field contains the XML presentation of the profile used for discovery, if the connection succeeds.
116 | ///
117 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
118 | public string ProfileXml;
119 | }
120 |
121 | ///
122 | /// Contains the SSID of an interface.
123 | ///
124 | public struct Dot11Ssid
125 | {
126 | ///
127 | /// The length, in bytes, of the array.
128 | ///
129 | public uint SSIDLength;
130 | ///
131 | /// The SSID.
132 | ///
133 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
134 | public byte[] SSID;
135 | }
136 |
137 | ///
138 | /// Defines the security attributes for a wireless connection.
139 | ///
140 | ///
141 | /// Corresponds to the native WLAN_SECURITY_ATTRIBUTES type.
142 | ///
143 | [StructLayout(LayoutKind.Sequential)]
144 | public struct WlanSecurityAttributes
145 | {
146 | ///
147 | /// Indicates whether security is enabled for this connection.
148 | ///
149 | [MarshalAs(UnmanagedType.Bool)]
150 | public bool SecurityEnabled;
151 | [MarshalAs(UnmanagedType.Bool)]
152 | public bool OneXEnabled;
153 | ///
154 | /// The authentication algorithm.
155 | ///
156 | public Dot11AuthAlgorithm Dot11AuthAlgorithm;
157 | ///
158 | /// The cipher algorithm.
159 | ///
160 | public Dot11CipherAlgorithm Dot11CipherAlgorithm;
161 | }
162 |
163 | ///
164 | /// Defines the attributes of a wireless connection.
165 | ///
166 | ///
167 | /// Corresponds to the native WLAN_CONNECTION_ATTRIBUTES type.
168 | ///
169 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
170 | public struct WlanConnectionAttributes
171 | {
172 | ///
173 | /// The state of the interface.
174 | ///
175 | public WlanInterfaceState IsState;
176 | ///
177 | /// The mode of the connection.
178 | ///
179 | public WlanConnectionMode WlanConnectionMode;
180 | ///
181 | /// The name of the profile used for the connection. Profile names are case-sensitive.
182 | ///
183 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
184 | public string ProfileName;
185 | ///
186 | /// The attributes of the association.
187 | ///
188 | public WlanAssociationAttributes WlanAssociationAttributes;
189 | ///
190 | /// The security attributes of the connection.
191 | ///
192 | public WlanSecurityAttributes WlanSecurityAttributes;
193 | }
194 |
195 | ///
196 | /// Contains association attributes for a connection
197 | ///
198 | ///
199 | /// Corresponds to the native WLAN_ASSOCIATION_ATTRIBUTES type.
200 | ///
201 | [StructLayout(LayoutKind.Sequential)]
202 | public struct WlanAssociationAttributes
203 | {
204 | ///
205 | /// The SSID of the association.
206 | ///
207 | public Dot11Ssid Dot11Ssid;
208 | ///
209 | /// Specifies whether the network is infrastructure or ad hoc.
210 | ///
211 | public Dot11BssType Dot11BssType;
212 | ///
213 | /// The BSSID of the association.
214 | ///
215 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
216 | public byte[] Dot11Bssid;
217 | ///
218 | /// The physical type of the association.
219 | ///
220 | public Dot11PhyType Dot11PhyType;
221 | ///
222 | /// The position of the value in the structure containing the list of PHY types.
223 | ///
224 | public uint Dot11PhyIndex;
225 | ///
226 | /// A percentage value that represents the signal quality of the network.
227 | /// This field contains a value between 0 and 100.
228 | /// A value of 0 implies an actual RSSI signal strength of -100 dbm.
229 | /// A value of 100 implies an actual RSSI signal strength of -50 dbm.
230 | /// You can calculate the RSSI signal strength value for values between 1 and 99 using linear interpolation.
231 | ///
232 | public uint WlanSignalQuality;
233 | ///
234 | /// The receiving rate of the association.
235 | ///
236 | public uint RxRate;
237 | ///
238 | /// The transmission rate of the association.
239 | ///
240 | public uint TxRate;
241 |
242 | ///
243 | /// Gets the BSSID of the associated access point.
244 | ///
245 | /// The BSSID.
246 | public PhysicalAddress WlanDot11Bssid
247 | {
248 | get { return new PhysicalAddress(Dot11Bssid); }
249 | }
250 | }
251 |
252 | ///
253 | /// Specifies the parameters used when using the function.
254 | ///
255 | ///
256 | /// Corresponds to the native WLAN_CONNECTION_PARAMETERS type.
257 | ///
258 | [StructLayout(LayoutKind.Sequential)]
259 | public struct WlanConnectionParameters
260 | {
261 | ///
262 | /// Specifies the mode of connection.
263 | ///
264 | public WlanConnectionMode WlanConnectionMode;
265 | ///
266 | /// Specifies the profile being used for the connection.
267 | /// The contents of the field depend on the :
268 | ///
269 | ///
270 | /// Value of
271 | /// Contents of the profile string
272 | ///
273 | /// -
274 | ///
275 | /// The name of the profile used for the connection.
276 | ///
277 | /// -
278 | ///
279 | /// The XML representation of the profile used for the connection.
280 | ///
281 | /// -
282 | /// , or
283 | /// null
284 | ///
285 | ///
286 | ///
287 | [MarshalAs(UnmanagedType.LPWStr)]
288 | public string Profile;
289 | ///
290 | /// Pointer to a structure that specifies the SSID of the network to connect to.
291 | /// This field is optional. When set to null, all SSIDs in the profile will be tried.
292 | /// This field must not be null if is set to or .
293 | ///
294 | public IntPtr Dot11SsidPtr;
295 | ///
296 | /// Pointer to a structure that contains the list of basic service set (BSS) identifiers desired for the connection.
297 | ///
298 | ///
299 | /// On Windows XP SP2, must be set to null.
300 | ///
301 | public IntPtr DesiredBssidListPtr;
302 | ///
303 | /// A value that indicates the BSS type of the network. If a profile is provided, this BSS type must be the same as the one in the profile.
304 | ///
305 | public Dot11BssType Dot11BssType;
306 | ///
307 | /// Specifies ocnnection parameters.
308 | ///
309 | ///
310 | /// On Windows XP SP2, must be set to 0.
311 | ///
312 | public WlanConnectionFlags Flags;
313 | }
314 |
315 | ///
316 | /// Contains basic information about a profile.
317 | ///
318 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
319 | public struct WlanProfileInfo
320 | {
321 | ///
322 | /// The name of the profile. This value may be the name of a domain if the profile is for provisioning. Profile names are case-sensitive.
323 | ///
324 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
325 | public string ProfileName;
326 | ///
327 | /// Profile flags.
328 | ///
329 | public WlanProfileFlags ProfileFlags;
330 | }
331 |
332 | ///
333 | /// The header of the list returned by .
334 | ///
335 | [StructLayout(LayoutKind.Sequential)]
336 | internal struct WlanProfileInfoListHeader
337 | {
338 | public uint NumberOfItems;
339 | public uint Index;
340 | }
341 |
342 | ///
343 | /// Contains information about an available wireless network.
344 | ///
345 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
346 | public struct WlanAvailableNetwork
347 | {
348 | ///
349 | /// Contains the profile name associated with the network.
350 | /// If the network doesn't have a profile, this member will be empty.
351 | /// If multiple profiles are associated with the network, there will be multiple entries with the same SSID in the visible network list. Profile names are case-sensitive.
352 | ///
353 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
354 | public string ProfileName;
355 | ///
356 | /// Contains the SSID of the visible wireless network.
357 | ///
358 | public Dot11Ssid Dot11Ssid;
359 | ///
360 | /// Specifies whether the network is infrastructure or ad hoc.
361 | ///
362 | public Dot11BssType Dot11BssType;
363 | ///
364 | /// Indicates the number of BSSIDs in the network.
365 | ///
366 | public uint NumberOfBssids;
367 | ///
368 | /// Indicates whether the network is connectable or not.
369 | ///
370 | public bool NetworkConnectable;
371 | ///
372 | /// Indicates why a network cannot be connected to. This member is only valid when is false.
373 | ///
374 | public WlanReasonCode WlanNotConnectableReason;
375 | ///
376 | /// The number of PHY types supported on available networks.
377 | /// The maximum value of this field is 8. If more than 8 PHY types are supported, must be set to true.
378 | ///
379 | private uint NumberOfPhyTypes;
380 | ///
381 | /// Contains an array of values that represent the PHY types supported by the available networks.
382 | /// When is greater than 8, this array contains only the first 8 PHY types.
383 | ///
384 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
385 | private Dot11PhyType[] Dot11PhyTypes;
386 | ///
387 | /// Gets the values that represent the PHY types supported by the available networks.
388 | ///
389 | public Dot11PhyType[] WlanDot11PhyTypes
390 | {
391 | get
392 | {
393 | Dot11PhyType[] ret = new Dot11PhyType[NumberOfPhyTypes];
394 | Array.Copy(Dot11PhyTypes, ret, NumberOfPhyTypes);
395 | return ret;
396 | }
397 | }
398 | ///
399 | /// Specifies if there are more than 8 PHY types supported.
400 | /// When this member is set to true, an application must call to get the complete list of PHY types.
401 | /// contains the PHY type for an entry.
402 | ///
403 | public bool MorePhyTypes;
404 | ///
405 | /// A percentage value that represents the signal quality of the network.
406 | /// This field contains a value between 0 and 100.
407 | /// A value of 0 implies an actual RSSI signal strength of -100 dbm.
408 | /// A value of 100 implies an actual RSSI signal strength of -50 dbm.
409 | /// You can calculate the RSSI signal strength value for values between 1 and 99 using linear interpolation.
410 | ///
411 | public uint WlanSignalQuality;
412 | ///
413 | /// Indicates whether security is enabled on the network.
414 | ///
415 | public bool SecurityEnabled;
416 | ///
417 | /// Indicates the default authentication algorithm used to join this network for the first time.
418 | ///
419 | public Dot11AuthAlgorithm Dot11DefaultAuthAlgorithm;
420 | ///
421 | /// Indicates the default cipher algorithm to be used when joining this network.
422 | ///
423 | public Dot11CipherAlgorithm Dot11DefaultCipherAlgorithm;
424 | ///
425 | /// Contains various flags for the network.
426 | ///
427 | public WlanAvailableNetworkFlags Flags;
428 | ///
429 | /// Reserved for future use. Must be set to NULL.
430 | ///
431 | uint Reserved;
432 |
433 | public bool Equals(WlanAvailableNetwork network)
434 | {
435 | // Compares the two SSID byte arrays
436 | return this.Dot11Ssid.SSIDLength == network.Dot11Ssid.SSIDLength
437 | && this.Dot11Ssid.SSID.SequenceEqual(network.Dot11Ssid.SSID);
438 | }
439 | }
440 |
441 | ///
442 | /// The header of an array of information about available networks.
443 | ///
444 | [StructLayout(LayoutKind.Sequential)]
445 | internal struct WlanAvailableNetworkListHeader
446 | {
447 | ///
448 | /// Contains the number of items following the header.
449 | ///
450 | public uint NumberOfItems;
451 | ///
452 | /// The index of the current item. The index of the first item is 0.
453 | ///
454 | public uint Index;
455 | }
456 |
457 | ///
458 | /// Contains information about a basic service set (BSS).
459 | ///
460 | [StructLayout(LayoutKind.Sequential)]
461 | public struct WlanBssEntry
462 | {
463 | ///
464 | /// Contains the SSID of the access point (AP) associated with the BSS.
465 | ///
466 | public Dot11Ssid Dot11Ssid;
467 | ///
468 | /// The identifier of the PHY on which the AP is operating.
469 | ///
470 | public uint PhyId;
471 | ///
472 | /// Contains the BSS identifier.
473 | ///
474 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
475 | public byte[] Dot11Bssid;
476 | ///
477 | /// Specifies whether the network is infrastructure or ad hoc.
478 | ///
479 | public Dot11BssType Dot11BssType;
480 | public Dot11PhyType Dot11BssPhyType;
481 | ///
482 | /// The received signal strength in dBm.
483 | ///
484 | public int Rssi;
485 | ///
486 | /// The link quality reported by the driver. Ranges from 0-100.
487 | ///
488 | public uint LinkQuality;
489 | ///
490 | /// If 802.11d is not implemented, the network interface card (NIC) must set this field to TRUE. If 802.11d is implemented (but not necessarily enabled), the NIC must set this field to TRUE if the BSS operation complies with the configured regulatory domain.
491 | ///
492 | public bool InRegDomain;
493 | ///
494 | /// Contains the beacon interval value from the beacon packet or probe response.
495 | ///
496 | public ushort BeaconPeriod;
497 | ///
498 | /// The timestamp from the beacon packet or probe response.
499 | ///
500 | public ulong Timestamp;
501 | ///
502 | /// The host timestamp value when the beacon or probe response is received.
503 | ///
504 | public ulong HostTimestamp;
505 | ///
506 | /// The capability value from the beacon packet or probe response.
507 | ///
508 | public ushort CapabilityInformation;
509 | ///
510 | /// The frequency of the center channel, in kHz.
511 | ///
512 | public uint ChCenterFrequency;
513 | ///
514 | /// Contains the set of data transfer rates supported by the BSS.
515 | ///
516 | public WlanRateSet WlanRateSet;
517 | ///
518 | /// Offset of the information element (IE) data blob.
519 | ///
520 | public uint IeOffset;
521 | ///
522 | /// Size of the IE data blob, in bytes.
523 | ///
524 | public uint IeSize;
525 | }
526 |
527 | ///
528 | /// Contains the set of supported data rates.
529 | ///
530 | [StructLayout(LayoutKind.Sequential)]
531 | public struct WlanRateSet
532 | {
533 | ///
534 | /// The length, in bytes, of .
535 | ///
536 | private uint RateSetLength;
537 | ///
538 | /// An array of supported data transfer rates.
539 | /// If the rate is a basic rate, the first bit of the rate value is set to 1.
540 | /// A basic rate is the data transfer rate that all stations in a basic service set (BSS) can use to receive frames from the wireless medium.
541 | ///
542 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 126)]
543 | private ushort[] RateSet;
544 |
545 | public ushort[] Rates
546 | {
547 | get
548 | {
549 | ushort[] rates = new ushort[RateSetLength / sizeof(ushort)];
550 | Array.Copy(RateSet, rates, rates.Length);
551 | return rates;
552 | }
553 | }
554 |
555 | ///
556 | /// CalculateS the data transfer rate in Mbps for an arbitrary supported rate.
557 | ///
558 | ///
559 | ///
560 | public double GetRateInMbps(int rate)
561 | {
562 | return (RateSet[rate] & 0x7FFF) * 0.5;
563 | }
564 | }
565 |
566 | [StructLayout(LayoutKind.Sequential)]
567 | internal struct WlanBssListHeader
568 | {
569 | internal uint TotalSize;
570 | internal uint NumberOfItems;
571 | }
572 |
573 | ///
574 | /// The header of the list returned by .
575 | ///
576 | [StructLayout(LayoutKind.Sequential)]
577 | internal struct WlanInterfaceInfoListHeader
578 | {
579 | public uint NumberOfItems;
580 | public uint Index;
581 | }
582 | }
583 |
--------------------------------------------------------------------------------
/Utils/WindowsApi/Win32/Wlanapi/WlanapiBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace Utils.WindowsApi
11 | {
12 | public partial class WlanapiBase
13 | {
14 | private const string Wlanapi = "Wlanapi.dll";
15 |
16 | public const uint WLAN_CLIENT_VERSION_XP_SP2 = 1;
17 | public const uint WLAN_CLIENT_VERSION_LONGHORN = 2;
18 |
19 | ///
20 | /// Defines the callback function which accepts WLAN notifications.
21 | ///
22 | public delegate void WlanNotificationCallbackDelegate(ref WlanNotificationData notificationData, IntPtr context);
23 |
24 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanopenhandle
25 | [DllImport(Wlanapi)]
26 | public static extern int WlanOpenHandle(
27 | uint dwClientVersion,
28 | IntPtr pReserved,
29 | [Out] out uint pdwNegotiatedVersion,
30 | [Out] out IntPtr ClientHandle);
31 |
32 | //https://learn.microsoft.com/zh-cn/previous-versions/windows/embedded/gg159537(v=winembedded.80)
33 | [DllImport(Wlanapi)]
34 | public static extern int WlanRegisterNotification(
35 | IntPtr hClientHandle,
36 | WlanNotificationSource dwNotifSource,
37 | bool bIgnoreDuplicate,
38 | WlanNotificationCallbackDelegate funcCallback,
39 | IntPtr pCallbackContext,
40 | IntPtr pReserved,
41 | [Out] out WlanNotificationSource pdwPrevNotifSource);
42 |
43 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanclosehandle
44 | [DllImport(Wlanapi)]
45 | public static extern int WlanCloseHandle(
46 | [In] IntPtr hClientHandle,
47 | IntPtr pReserved);
48 |
49 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanqueryinterface
50 | [DllImport(Wlanapi)]
51 | public static extern int WlanQueryInterface(
52 | [In] IntPtr clientHandle,
53 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
54 | [In] WlanIntfOpcode opCode,
55 | [In, Out] IntPtr pReserved,
56 | [Out] out int dataSize,
57 | [Out] out IntPtr ppData,
58 | [Out] out WlanOpcodeValueType wlanOpcodeValueType);
59 |
60 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlansetinterface
61 | [DllImport(Wlanapi)]
62 | public static extern int WlanSetInterface(
63 | [In] IntPtr clientHandle,
64 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
65 | [In] WlanIntfOpcode opCode,
66 | [In] uint dataSize,
67 | [In] IntPtr pData,
68 | [In, Out] IntPtr pReserved);
69 |
70 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanscan
71 | /// Not supported on Windows XP SP2: must be a null reference.
72 | /// Not supported on Windows XP SP2: must be a null reference.
73 | [DllImport(Wlanapi)]
74 | public static extern int WlanScan(
75 | [In] IntPtr clientHandle,
76 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
77 | [In] IntPtr pDot11Ssid,
78 | [In] IntPtr pIeData,
79 | [In, Out] IntPtr pReserved);
80 |
81 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanconnect
82 | [DllImport(Wlanapi)]
83 | public static extern int WlanConnect(
84 | [In] IntPtr clientHandle,
85 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
86 | [In] ref WlanConnectionParameters connectionParameters,
87 | IntPtr pReserved);
88 |
89 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlandisconnect
90 | [DllImport(Wlanapi)]
91 | public static extern int WlanDisconnect(
92 | [In] IntPtr clientHandle,
93 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
94 | IntPtr pReserved);
95 |
96 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlangetprofile
97 | /// Not supported on Windows XP SP2: must be a null reference.
98 | [DllImport(Wlanapi)]
99 | public static extern int WlanGetProfile(
100 | [In] IntPtr clientHandle,
101 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
102 | [In, MarshalAs(UnmanagedType.LPWStr)] string profileName,
103 | [In] IntPtr pReserved,
104 | [Out] out IntPtr profileXml,
105 | [Out, Optional] out WlanProfileFlags flags,
106 | [Out, Optional] out WlanAccess grantedAccess);
107 |
108 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlangetprofilelist
109 | [DllImport(Wlanapi)]
110 | public static extern int WlanGetProfileList(
111 | [In] IntPtr clientHandle,
112 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
113 | [In] IntPtr pReserved,
114 | [Out] out IntPtr profileList
115 | );
116 |
117 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlangetavailablenetworklist
118 | [DllImport(Wlanapi)]
119 | public static extern int WlanGetAvailableNetworkList(
120 | [In] IntPtr clientHandle,
121 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
122 | [In] WlanGetAvailableNetworkFlags flags,
123 | [In, Out] IntPtr reservedPtr,
124 | [Out] out IntPtr availableNetworkListPtr);
125 |
126 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlangetnetworkbsslist
127 | [DllImport(Wlanapi)]
128 | public static extern int WlanGetNetworkBssList(
129 | [In] IntPtr clientHandle,
130 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
131 | [In] IntPtr dot11SsidInt,
132 | [In] Dot11BssType dot11BssType,
133 | [In] bool securityEnabled,
134 | IntPtr reservedPtr,
135 | [Out] out IntPtr wlanBssList
136 | );
137 |
138 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlansetprofile
139 | [DllImport(Wlanapi)]
140 | public static extern int WlanSetProfile(
141 | [In] IntPtr clientHandle,
142 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
143 | [In] WlanProfileFlags flags,
144 | [In, MarshalAs(UnmanagedType.LPWStr)] string profileXml,
145 | [In, Optional, MarshalAs(UnmanagedType.LPWStr)] string allUserProfileSecurity,
146 | [In] bool overwrite,
147 | [In] IntPtr pReserved,
148 | [Out] out WlanReasonCode reasonCode);
149 |
150 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlandeleteprofile
151 | [DllImport(Wlanapi)]
152 | public static extern int WlanDeleteProfile(
153 | [In] IntPtr clientHandle,
154 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
155 | [In, MarshalAs(UnmanagedType.LPWStr)] string profileName,
156 | IntPtr reservedPtr
157 | );
158 |
159 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlansetprofileeapxmluserdata
160 | [DllImport(Wlanapi)]
161 | public static extern int WlanSetProfileEapXmlUserData(
162 | // The client's session handle, obtained by a previous call to the WlanOpenHandle function.
163 | // 客户端的会话句柄,通过先前对WlanOpenHandle函数的调用获得。
164 | [In] IntPtr clientHandle,
165 | // The GUID of the interface.
166 | // 接口的GUID。
167 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid,
168 | // The name of the profile associated with the EAP user data.
169 | // 与EAP用户数据关联的配置文件的名称。
170 | // Profile names are case-sensitive. This string must be NULL-terminated.
171 | // 配置文件名称区分大小写。此字符串必须以NULL结尾。
172 | [In, MarshalAs(UnmanagedType.LPWStr)] string profileName,
173 | // A set of flags that modify the behavior of the function.
174 | [In] SetEapUserDataMode dwFlags,
175 | // A pointer to XML data used to set the user credentials,
176 | // 指向用于设置用户凭证的XML数据的指针,
177 | // The XML data must be based on the EAPHost User Credentials schema. To view sample user credential XML data,
178 | // XML数据必须基于EAPHost用户凭据架构。要查看示例用户凭证XML数据,
179 | // see EAPHost User Properties: http://msdn.microsoft.com/en-us/library/windows/desktop/bb204765(v=vs.85).aspx
180 | [In, MarshalAs(UnmanagedType.LPWStr)] string userDataXML,
181 | IntPtr reservedPtr
182 | );
183 |
184 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanreasoncodetostring
185 | [DllImport(Wlanapi)]
186 | public static extern int WlanReasonCodeToString(
187 | [In] WlanReasonCode reasonCode,
188 | [In] int bufferSize,
189 | [In, Out] StringBuilder stringBuffer,
190 | IntPtr pReserved
191 | );
192 |
193 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanenuminterfaces
194 | [DllImport(Wlanapi)]
195 | public static extern int WlanEnumInterfaces(
196 | [In] IntPtr clientHandle,
197 | [In, Out] IntPtr pReserved,
198 | [Out] out IntPtr ppInterfaceList);
199 |
200 | //https://learn.microsoft.com/zh-cn/windows/win32/api/wlanapi/nf-wlanapi-wlanfreememory
201 | [DllImport(Wlanapi)]
202 | public static extern void WlanFreeMemory(IntPtr pMemory);
203 |
204 | ///
205 | /// Helper method to wrap calls to Native WiFi API methods.
206 | /// If the method falls, throws an exception containing the error code.
207 | ///
208 | /// The error code.
209 | [DebuggerStepThrough]
210 | internal static void ThrowIfError(int win32ErrorCode)
211 | {
212 | if (win32ErrorCode != 0)
213 | throw new Win32Exception(win32ErrorCode);
214 | }
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/UtilsDemo/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/UtilsDemo/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace UtilsDemo
8 | {
9 | internal class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 |
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/UtilsDemo/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("UtilsDemo")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("UtilsDemo")]
13 | [assembly: AssemblyCopyright("Copyright © 2024")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("6a1b5e4b-0650-4e1f-ab48-2deafe40d6e8")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
33 | //通过使用 "*",如下所示:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/UtilsDemo/UtilsDemo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6A1B5E4B-0650-4E1F-AB48-2DEAFE40D6E8}
8 | Exe
9 | UtilsDemo
10 | UtilsDemo
11 | v4.8
12 | 512
13 | true
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | {52b9c6b5-da34-4b13-a2ba-5a13f97d0386}
56 | Utils
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------