├── .github
├── ISSUE_TEMPLATE
│ ├── bug-report.md
│ └── question.md
└── workflows
│ └── CI.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── NotifyIcon.sln
├── README.md
└── src
├── .editorconfig
├── Directory.Build.props
├── Directory.Packages.props
├── GeneratePackage.props
├── ImplicitUsings.cs
├── NotifyIcon.Platform.Linux
├── LinuxNotifyIcon.cs
└── NotifyIcon.Platform.Linux.csproj
├── NotifyIcon.Platform.Mac
├── MacNotifyIcon.cs
└── NotifyIcon.Platform.Mac.csproj
├── NotifyIcon.Platform.Windows
├── NotifyIcon.Platform.Windows.csproj
└── WindowsNotifyIcon.cs
├── NotifyIcon.Platform
├── ContextMenuStrip.cs
├── NotifyIcon.Platform.csproj
├── NotifyIcon.cs
├── Properties
│ └── InternalsVisibleTo.cs
└── ToolTipIcon.cs
├── NotifyIcon.snk
├── NotifyIcon
└── NotifyIcon.csproj
├── Samples.AvaloniaApp1
├── App.axaml
├── App.axaml.cs
├── Assets
│ └── test_icon.ico
├── MainWindow.axaml
├── MainWindow.axaml.cs
├── NotifyIconPipeClient.cs
├── NotifyIconPipeCore.cs
├── NotifyIconPipeServer.cs
├── Program.cs
├── Properties
│ └── PublishProfiles
│ │ ├── linux-arm.pubxml
│ │ ├── linux-arm64.pubxml
│ │ ├── linux-x64.pubxml
│ │ ├── macos-x64.pubxml
│ │ ├── osx-arm64.pubxml
│ │ ├── osx-x64.pubxml
│ │ ├── win-arm64.pubxml
│ │ └── win-x64.pubxml
├── Samples.AvaloniaApp1.csproj
└── ViewModels
│ └── ApplicationViewModel.cs
├── Samples.ClassLibrary1
├── NotifyIconHelper.cs
├── Properties
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── Resources
│ ├── Icon.ico
│ └── Icon_16.png
└── Samples.ClassLibrary1.csproj
├── Samples.ConsoleApp1
├── AppDelegate.cs
├── Program.cs
├── Properties
│ └── PublishProfiles
│ │ ├── linux-arm.pubxml
│ │ ├── linux-arm64.pubxml
│ │ ├── linux-x64.pubxml
│ │ ├── osx-arm64.pubxml
│ │ ├── osx-x64.pubxml
│ │ ├── win-arm64.pubxml
│ │ └── win-x64.pubxml
└── Samples.ConsoleApp1.csproj
├── Samples.MauiApp1
├── App.xaml
├── App.xaml.cs
├── AppShell.xaml
├── AppShell.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── MauiProgram.cs
├── Platforms
│ ├── Android
│ │ ├── AndroidManifest.xml
│ │ ├── MainActivity.cs
│ │ ├── MainApplication.cs
│ │ └── Resources
│ │ │ └── values
│ │ │ └── colors.xml
│ ├── MacCatalyst
│ │ ├── AppDelegate.cs
│ │ ├── Info.plist
│ │ └── Program.cs
│ ├── Tizen
│ │ ├── Main.cs
│ │ └── tizen-manifest.xml
│ ├── Windows
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── MauiProgram.cs
│ │ ├── Package.appxmanifest
│ │ └── app.manifest
│ └── iOS
│ │ ├── AppDelegate.cs
│ │ ├── Info.plist
│ │ └── Program.cs
├── Properties
│ └── launchSettings.json
├── Resources
│ ├── Colors.xaml
│ ├── Fonts
│ │ ├── OpenSans-Regular.ttf
│ │ └── OpenSans-Semibold.ttf
│ ├── Images
│ │ └── dotnet_bot.svg
│ ├── Raw
│ │ └── AboutAssets.txt
│ ├── Styles.xaml
│ ├── appicon.svg
│ └── appiconfg.svg
└── Samples.MauiApp1.csproj
├── Samples.WinUI3App1
├── App.xaml
├── App.xaml.cs
├── Assets
│ ├── LockScreenLogo.scale-200.png
│ ├── SplashScreen.scale-200.png
│ ├── Square150x150Logo.scale-200.png
│ ├── Square44x44Logo.scale-200.png
│ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ ├── StoreLogo.png
│ └── Wide310x150Logo.scale-200.png
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Package.appxmanifest
├── Properties
│ ├── PublishProfiles
│ │ ├── win10-arm64.pubxml
│ │ ├── win10-x64.pubxml
│ │ └── win10-x86.pubxml
│ └── launchSettings.json
├── Samples.WinUI3App1.csproj
├── WinUIProgram.cs
└── app.manifest
└── Samples.WpfApp1
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
└── PublishProfiles
│ ├── win-arm64.pubxml
│ └── win-x64.pubxml
└── Samples.WpfApp1.csproj
/.github/ISSUE_TEMPLATE/bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Bug Report \U0001F41B"
3 | about: 创建 Bug 报告以帮助我们改进 / Create a report to help us improve
4 | title: "\U0001F41B[BUG] 请输入标题(Please enter a title)"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 |
18 |
19 | ### 🐛 描述(Description)
20 |
24 |
25 |
26 | ### 📷 复现步骤(Steps to Reproduce)
27 |
28 |
34 | 1.
35 | 2.
36 | 3.
37 |
38 | ### 📄 日志信息(Log Information)
39 |
47 |
48 | ### 🚑 基本信息(Basic Information)
49 |
50 | - 库版本(Library Version):
51 | - 系统版本号(OS Version):
52 |
53 | ### 🖼 截图(Screenshots)
54 |
55 |
59 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Question \U0001F9D0"
3 | about: 对库使用的疑问或需要帮助 / Questions about the use of the library or need help
4 | title: "\U0001F9D0[Question] 请输入标题(Please enter a title)"
5 | labels: question
6 | assignees: ''
7 |
8 | ---
9 |
10 |
16 |
17 | ### 🧐 问题描述(Description)
18 |
19 |
23 |
24 | ### 🚑 其他信息(Other Information)
25 |
26 |
30 |
31 | - 库版本(Library Version):
32 | - 系统版本号(OS Version):
33 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches:
5 | - main
6 | tags:
7 | - "*"
8 | pull_request:
9 | workflow_dispatch:
10 |
11 | jobs:
12 | test:
13 | name: Test
14 | runs-on: ${{ matrix.os }}
15 | strategy:
16 | matrix:
17 | os: [ windows-latest ]
18 |
19 | steps:
20 | - name: Checkout repository
21 | uses: actions/checkout@v3
22 | with:
23 | fetch-depth: 0
24 | submodules: recursive
25 |
26 | - name: Setup .NET
27 | uses: actions/setup-dotnet@v2
28 | with:
29 | dotnet-version: 7.0.x
30 |
31 | - name: Install Android SDK
32 | run: dotnet workload install android
33 |
34 | - name: Install iOS SDK
35 | run: dotnet workload install ios
36 |
37 | - name: Install macOS SDK
38 | run: dotnet workload install macos
39 |
40 | - name: Install Mac Catalyst SDK
41 | run: dotnet workload install maccatalyst
42 |
43 | - name: Install Maui
44 | run: dotnet workload install maui
45 |
46 | - name: Install wasm-tools
47 | run: dotnet workload install wasm-tools
48 |
49 | - name: Restore Workload
50 | run: dotnet workload restore
51 |
52 | - name: Verify dotnet info
53 | run: dotnet --info
54 |
55 | - name: dotnet restore NotifyIcon.sln
56 | run: dotnet restore ./NotifyIcon.sln
57 |
58 | - name: Test
59 | shell: pwsh
60 | run: dotnet test -c Release
61 |
62 | build:
63 | name: Build
64 | needs: [ test ]
65 | if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
66 | runs-on: windows-latest
67 | strategy:
68 | matrix:
69 | include:
70 | - ProjectName: "NotifyIcon"
71 | PackageId: "NotifyIcon"
72 | - ProjectName: "NotifyIcon.Platform"
73 | PackageId: "NotifyIcon.Base"
74 | - ProjectName: "NotifyIcon.Platform.Windows"
75 | PackageId: "NotifyIcon.Windows"
76 | - ProjectName: "NotifyIcon.Platform.Mac"
77 | PackageId: "NotifyIcon.Mac"
78 | - ProjectName: "NotifyIcon.Platform.Linux"
79 | PackageId: "NotifyIcon.Linux"
80 |
81 | steps:
82 | - name: Checkout repository
83 | uses: actions/checkout@v3
84 | with:
85 | fetch-depth: 0
86 | submodules: recursive
87 |
88 | - name: Setup .NET
89 | uses: actions/setup-dotnet@v2
90 | with:
91 | dotnet-version: 7.0.x
92 |
93 | - name: Install Android SDK
94 | run: dotnet workload install android
95 |
96 | - name: Install iOS SDK
97 | run: dotnet workload install ios
98 |
99 | - name: Install macOS SDK
100 | run: dotnet workload install macos
101 |
102 | - name: Install Mac Catalyst SDK
103 | run: dotnet workload install maccatalyst
104 |
105 | - name: Install Maui
106 | run: dotnet workload install maui
107 |
108 | - name: Install wasm-tools
109 | run: dotnet workload install wasm-tools
110 |
111 | - name: Restore Workload
112 | run: dotnet workload restore
113 |
114 | - name: Verify dotnet info
115 | run: dotnet --info
116 |
117 | - name: Build
118 | shell: pwsh
119 | run: dotnet build -c Release src\${{ matrix.ProjectName }}\${{ matrix.ProjectName }}.csproj
120 |
121 | - name: Push nuget packages
122 | shell: pwsh
123 | run: |
124 | dotnet nuget push pkg\${{ matrix.PackageId }}*.nupkg -s https://nuget.pkg.github.com/BeyondDimension -k ${{ secrets.RMBADMIN_TOKEN }} --skip-duplicate
125 | dotnet nuget push pkg\${{ matrix.PackageId }}*.snupkg -s https://nuget.pkg.github.com/BeyondDimension -k ${{ secrets.RMBADMIN_TOKEN }} --skip-duplicate
126 | dotnet nuget push pkg\${{ matrix.PackageId }}*.nupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} --skip-duplicate
127 | dotnet nuget push pkg\${{ matrix.PackageId }}*.snupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} --skip-duplicate
128 | release:
129 | name: Release
130 | needs: build
131 | runs-on: ubuntu-latest
132 |
133 | steps:
134 | - name: Changelog
135 | uses: glennawatson/ChangeLog@v1
136 | id: changelog
137 |
138 | - name: Create Release
139 | uses: ncipollo/release-action@v1
140 | with:
141 | token: ${{ secrets.RMBADMIN_TOKEN }}
142 | body: ${{ steps.changelog.outputs.commitLog }}
143 | draft: false
144 | prerelease: false
145 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "ref/DirectoryPackages"]
2 | path = ref/DirectoryPackages
3 | url = https://github.com/BeyondDimension/DirectoryPackages.git
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 SteamTools Team
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NotifyIcon.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.2.32516.85
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotifyIcon", "src\NotifyIcon\NotifyIcon.csproj", "{11739B05-8E34-4BC0-9678-62D4E93AC0EC}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotifyIcon.Platform.Windows", "src\NotifyIcon.Platform.Windows\NotifyIcon.Platform.Windows.csproj", "{BA5F675C-1D3B-413D-95CC-7337DE01B1CB}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotifyIcon.Platform.Linux", "src\NotifyIcon.Platform.Linux\NotifyIcon.Platform.Linux.csproj", "{1D643B0B-B5EE-4E94-AF12-F782BE504D7D}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotifyIcon.Platform.Mac", "src\NotifyIcon.Platform.Mac\NotifyIcon.Platform.Mac.csproj", "{CB9327D1-DA24-4984-A4D7-B30C1C89E75C}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotifyIcon.Platform", "src\NotifyIcon.Platform\NotifyIcon.Platform.csproj", "{ECD79BE3-1CC5-4260-A217-AF18069D5BA8}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.WpfApp1", "src\Samples.WpfApp1\Samples.WpfApp1.csproj", "{EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}"
17 | EndProject
18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.ClassLibrary1", "src\Samples.ClassLibrary1\Samples.ClassLibrary1.csproj", "{285875B7-5876-4F36-9875-A5E5D3F5F66D}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.ConsoleApp1", "src\Samples.ConsoleApp1\Samples.ConsoleApp1.csproj", "{788CBDD6-1490-4FED-A884-0A4302070A4E}"
21 | EndProject
22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.AvaloniaApp1", "src\Samples.AvaloniaApp1\Samples.AvaloniaApp1.csproj", "{E79A8246-B65D-4631-8922-D02175133FE9}"
23 | EndProject
24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.WinUI3App1", "src\Samples.WinUI3App1\Samples.WinUI3App1.csproj", "{962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}"
25 | EndProject
26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.MauiApp1", "src\Samples.MauiApp1\Samples.MauiApp1.csproj", "{E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}"
27 | EndProject
28 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{0364A0F8-4A8C-4385-89D2-4EADDE50577F}"
29 | EndProject
30 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Root", "_Root", "{F3E4E683-51F2-470B-BCA8-055E5CAA8C4A}"
31 | ProjectSection(SolutionItems) = preProject
32 | src\.editorconfig = src\.editorconfig
33 | .gitignore = .gitignore
34 | .github\workflows\CI.yml = .github\workflows\CI.yml
35 | src\Directory.Build.props = src\Directory.Build.props
36 | ref\DirectoryPackages\Directory.Packages.props = ref\DirectoryPackages\Directory.Packages.props
37 | src\GeneratePackage.props = src\GeneratePackage.props
38 | src\ImplicitUsings.cs = src\ImplicitUsings.cs
39 | README.md = README.md
40 | EndProjectSection
41 | EndProject
42 | Global
43 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
44 | Debug|Any CPU = Debug|Any CPU
45 | Debug|arm64 = Debug|arm64
46 | Debug|x64 = Debug|x64
47 | Debug|x86 = Debug|x86
48 | Release|Any CPU = Release|Any CPU
49 | Release|arm64 = Release|arm64
50 | Release|x64 = Release|x64
51 | Release|x86 = Release|x86
52 | EndGlobalSection
53 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
54 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
55 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
56 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|arm64.ActiveCfg = Debug|Any CPU
57 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|arm64.Build.0 = Debug|Any CPU
58 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|x64.ActiveCfg = Debug|Any CPU
59 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|x64.Build.0 = Debug|Any CPU
60 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|x86.ActiveCfg = Debug|Any CPU
61 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Debug|x86.Build.0 = Debug|Any CPU
62 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
63 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|Any CPU.Build.0 = Release|Any CPU
64 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|arm64.ActiveCfg = Release|Any CPU
65 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|arm64.Build.0 = Release|Any CPU
66 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|x64.ActiveCfg = Release|Any CPU
67 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|x64.Build.0 = Release|Any CPU
68 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|x86.ActiveCfg = Release|Any CPU
69 | {11739B05-8E34-4BC0-9678-62D4E93AC0EC}.Release|x86.Build.0 = Release|Any CPU
70 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
71 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
72 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|arm64.ActiveCfg = Debug|Any CPU
73 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|arm64.Build.0 = Debug|Any CPU
74 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|x64.ActiveCfg = Debug|Any CPU
75 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|x64.Build.0 = Debug|Any CPU
76 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|x86.ActiveCfg = Debug|Any CPU
77 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Debug|x86.Build.0 = Debug|Any CPU
78 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
79 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|Any CPU.Build.0 = Release|Any CPU
80 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|arm64.ActiveCfg = Release|Any CPU
81 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|arm64.Build.0 = Release|Any CPU
82 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|x64.ActiveCfg = Release|Any CPU
83 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|x64.Build.0 = Release|Any CPU
84 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|x86.ActiveCfg = Release|Any CPU
85 | {BA5F675C-1D3B-413D-95CC-7337DE01B1CB}.Release|x86.Build.0 = Release|Any CPU
86 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
87 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
88 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|arm64.ActiveCfg = Debug|Any CPU
89 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|arm64.Build.0 = Debug|Any CPU
90 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|x64.ActiveCfg = Debug|Any CPU
91 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|x64.Build.0 = Debug|Any CPU
92 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|x86.ActiveCfg = Debug|Any CPU
93 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Debug|x86.Build.0 = Debug|Any CPU
94 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
95 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|Any CPU.Build.0 = Release|Any CPU
96 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|arm64.ActiveCfg = Release|Any CPU
97 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|arm64.Build.0 = Release|Any CPU
98 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|x64.ActiveCfg = Release|Any CPU
99 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|x64.Build.0 = Release|Any CPU
100 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|x86.ActiveCfg = Release|Any CPU
101 | {1D643B0B-B5EE-4E94-AF12-F782BE504D7D}.Release|x86.Build.0 = Release|Any CPU
102 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
103 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|Any CPU.Build.0 = Debug|Any CPU
104 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|arm64.ActiveCfg = Debug|Any CPU
105 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|arm64.Build.0 = Debug|Any CPU
106 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|x64.ActiveCfg = Debug|Any CPU
107 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|x64.Build.0 = Debug|Any CPU
108 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|x86.ActiveCfg = Debug|Any CPU
109 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Debug|x86.Build.0 = Debug|Any CPU
110 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|Any CPU.ActiveCfg = Release|Any CPU
111 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|Any CPU.Build.0 = Release|Any CPU
112 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|arm64.ActiveCfg = Release|Any CPU
113 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|arm64.Build.0 = Release|Any CPU
114 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|x64.ActiveCfg = Release|Any CPU
115 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|x64.Build.0 = Release|Any CPU
116 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|x86.ActiveCfg = Release|Any CPU
117 | {CB9327D1-DA24-4984-A4D7-B30C1C89E75C}.Release|x86.Build.0 = Release|Any CPU
118 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
119 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
120 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|arm64.ActiveCfg = Debug|Any CPU
121 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|arm64.Build.0 = Debug|Any CPU
122 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|x64.ActiveCfg = Debug|Any CPU
123 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|x64.Build.0 = Debug|Any CPU
124 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|x86.ActiveCfg = Debug|Any CPU
125 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Debug|x86.Build.0 = Debug|Any CPU
126 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
127 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|Any CPU.Build.0 = Release|Any CPU
128 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|arm64.ActiveCfg = Release|Any CPU
129 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|arm64.Build.0 = Release|Any CPU
130 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|x64.ActiveCfg = Release|Any CPU
131 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|x64.Build.0 = Release|Any CPU
132 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|x86.ActiveCfg = Release|Any CPU
133 | {ECD79BE3-1CC5-4260-A217-AF18069D5BA8}.Release|x86.Build.0 = Release|Any CPU
134 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
135 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
136 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|arm64.ActiveCfg = Debug|Any CPU
137 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|arm64.Build.0 = Debug|Any CPU
138 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|x64.ActiveCfg = Debug|Any CPU
139 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|x64.Build.0 = Debug|Any CPU
140 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|x86.ActiveCfg = Debug|Any CPU
141 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Debug|x86.Build.0 = Debug|Any CPU
142 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
143 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|Any CPU.Build.0 = Release|Any CPU
144 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|arm64.ActiveCfg = Release|Any CPU
145 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|arm64.Build.0 = Release|Any CPU
146 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|x64.ActiveCfg = Release|Any CPU
147 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|x64.Build.0 = Release|Any CPU
148 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|x86.ActiveCfg = Release|Any CPU
149 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C}.Release|x86.Build.0 = Release|Any CPU
150 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
151 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|Any CPU.Build.0 = Debug|Any CPU
152 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|arm64.ActiveCfg = Debug|Any CPU
153 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|arm64.Build.0 = Debug|Any CPU
154 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|x64.ActiveCfg = Debug|Any CPU
155 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|x64.Build.0 = Debug|Any CPU
156 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|x86.ActiveCfg = Debug|Any CPU
157 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Debug|x86.Build.0 = Debug|Any CPU
158 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|Any CPU.ActiveCfg = Release|Any CPU
159 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|Any CPU.Build.0 = Release|Any CPU
160 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|arm64.ActiveCfg = Release|Any CPU
161 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|arm64.Build.0 = Release|Any CPU
162 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|x64.ActiveCfg = Release|Any CPU
163 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|x64.Build.0 = Release|Any CPU
164 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|x86.ActiveCfg = Release|Any CPU
165 | {285875B7-5876-4F36-9875-A5E5D3F5F66D}.Release|x86.Build.0 = Release|Any CPU
166 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
167 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
168 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|arm64.ActiveCfg = Debug|Any CPU
169 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|arm64.Build.0 = Debug|Any CPU
170 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|x64.ActiveCfg = Debug|Any CPU
171 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|x64.Build.0 = Debug|Any CPU
172 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|x86.ActiveCfg = Debug|Any CPU
173 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Debug|x86.Build.0 = Debug|Any CPU
174 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
175 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|Any CPU.Build.0 = Release|Any CPU
176 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|arm64.ActiveCfg = Release|Any CPU
177 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|arm64.Build.0 = Release|Any CPU
178 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|x64.ActiveCfg = Release|Any CPU
179 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|x64.Build.0 = Release|Any CPU
180 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|x86.ActiveCfg = Release|Any CPU
181 | {788CBDD6-1490-4FED-A884-0A4302070A4E}.Release|x86.Build.0 = Release|Any CPU
182 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
183 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
184 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|arm64.ActiveCfg = Debug|Any CPU
185 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|arm64.Build.0 = Debug|Any CPU
186 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|x64.ActiveCfg = Debug|Any CPU
187 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|x64.Build.0 = Debug|Any CPU
188 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|x86.ActiveCfg = Debug|Any CPU
189 | {E79A8246-B65D-4631-8922-D02175133FE9}.Debug|x86.Build.0 = Debug|Any CPU
190 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
191 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|Any CPU.Build.0 = Release|Any CPU
192 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|arm64.ActiveCfg = Release|Any CPU
193 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|arm64.Build.0 = Release|Any CPU
194 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|x64.ActiveCfg = Release|Any CPU
195 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|x64.Build.0 = Release|Any CPU
196 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|x86.ActiveCfg = Release|Any CPU
197 | {E79A8246-B65D-4631-8922-D02175133FE9}.Release|x86.Build.0 = Release|Any CPU
198 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|Any CPU.ActiveCfg = Debug|x64
199 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|Any CPU.Build.0 = Debug|x64
200 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|arm64.ActiveCfg = Debug|arm64
201 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|arm64.Build.0 = Debug|arm64
202 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|x64.ActiveCfg = Debug|x64
203 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|x64.Build.0 = Debug|x64
204 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|x86.ActiveCfg = Debug|x86
205 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Debug|x86.Build.0 = Debug|x86
206 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|Any CPU.ActiveCfg = Release|x64
207 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|Any CPU.Build.0 = Release|x64
208 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|arm64.ActiveCfg = Release|arm64
209 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|arm64.Build.0 = Release|arm64
210 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|x64.ActiveCfg = Release|x64
211 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|x64.Build.0 = Release|x64
212 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|x86.ActiveCfg = Release|x86
213 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172}.Release|x86.Build.0 = Release|x86
214 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
215 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|Any CPU.Build.0 = Debug|Any CPU
216 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
217 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|arm64.ActiveCfg = Debug|Any CPU
218 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|arm64.Build.0 = Debug|Any CPU
219 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|arm64.Deploy.0 = Debug|Any CPU
220 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|x64.ActiveCfg = Debug|Any CPU
221 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|x64.Build.0 = Debug|Any CPU
222 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|x64.Deploy.0 = Debug|Any CPU
223 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|x86.ActiveCfg = Debug|Any CPU
224 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|x86.Build.0 = Debug|Any CPU
225 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Debug|x86.Deploy.0 = Debug|Any CPU
226 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|Any CPU.ActiveCfg = Release|Any CPU
227 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|Any CPU.Build.0 = Release|Any CPU
228 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|Any CPU.Deploy.0 = Release|Any CPU
229 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|arm64.ActiveCfg = Release|Any CPU
230 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|arm64.Build.0 = Release|Any CPU
231 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|arm64.Deploy.0 = Release|Any CPU
232 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|x64.ActiveCfg = Release|Any CPU
233 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|x64.Build.0 = Release|Any CPU
234 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|x64.Deploy.0 = Release|Any CPU
235 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|x86.ActiveCfg = Release|Any CPU
236 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|x86.Build.0 = Release|Any CPU
237 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32}.Release|x86.Deploy.0 = Release|Any CPU
238 | EndGlobalSection
239 | GlobalSection(SolutionProperties) = preSolution
240 | HideSolutionNode = FALSE
241 | EndGlobalSection
242 | GlobalSection(NestedProjects) = preSolution
243 | {EA6EF25C-CD06-4AC1-91C5-7E256053DE3C} = {0364A0F8-4A8C-4385-89D2-4EADDE50577F}
244 | {285875B7-5876-4F36-9875-A5E5D3F5F66D} = {0364A0F8-4A8C-4385-89D2-4EADDE50577F}
245 | {788CBDD6-1490-4FED-A884-0A4302070A4E} = {0364A0F8-4A8C-4385-89D2-4EADDE50577F}
246 | {E79A8246-B65D-4631-8922-D02175133FE9} = {0364A0F8-4A8C-4385-89D2-4EADDE50577F}
247 | {962EE8A8-AE35-4840-9CAE-8DD2ADE3B172} = {0364A0F8-4A8C-4385-89D2-4EADDE50577F}
248 | {E30BC9EF-AE40-4EAF-8BA6-63143BD17E32} = {0364A0F8-4A8C-4385-89D2-4EADDE50577F}
249 | EndGlobalSection
250 | GlobalSection(ExtensibilityGlobals) = postSolution
251 | SolutionGuid = {BDE162C9-AE66-456E-97B7-F84AC8337E96}
252 | EndGlobalSection
253 | EndGlobal
254 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NotifyIcon
2 | 在通知区域创建图标的组件。
3 |
4 | ## 包引用方式(二选一)
5 | 1. 运行时自动匹配平台实现 [](https://www.nuget.org/packages/NotifyIcon/)
6 | - ```Install-Package NotifyIcon```
7 | 2. 仅单个平台实现
8 | - Windows [](https://www.nuget.org/packages/NotifyIcon.Windows/)
9 | - ```Install-Package NotifyIcon.Windows```
10 | - Linux [](https://www.nuget.org/packages/NotifyIcon.Linux/)
11 | - ```Install-Package NotifyIcon.Linux```
12 | - macOS [](https://www.nuget.org/packages/NotifyIcon.Mac/)
13 | - ```Install-Package NotifyIcon.Mac```
14 |
15 | ## 平台支持与目标框架
16 | - Windows
17 | - .NET Framework 3.5 ~ 4.8+
18 | - .NET Core 2.0+
19 | - .NET 5+
20 | - .NET Standard 2.0+
21 | - Linux
22 | - .NET Framework 4.6.1+ / Mono 5.4+
23 | - .NET Core 2.0+
24 | - .NET 5+
25 | - .NET Standard 2.0+
26 | - macOS
27 | - .NET Framework 4.6.1+ / Mono 5.4+
28 | - .NET Core 2.0+
29 | - .NET 5+
30 | - .NET Standard 2.0+
31 |
32 | ## 使用方式
33 | 1. 直接使用
34 | - ```NotifyIcon notifyIcon = NotifyIcon.Create();```
35 | 2. 通过 **Microsoft.Extensions.DependencyInjection** 使用
36 | - 添加到依赖注入服务中
37 | - ```services.AddSingleton(typeof(NotifyIcon), NotifyIcon.ImplType);```
38 |
39 | ## 添加右键菜单项
40 | ```
41 | notifyIcon.ContextMenuStrip.Items.Add(new ContextMenuStrip.MenuItem() { Text = "Menu Text 01", Command = ReactiveCommand.Create(() =>
42 | {
43 | // ...
44 | })});
45 | ```
46 |
47 | ## 示例项目
48 | | Platform | ProjectFileName |
49 | | --------------------------- | ----------------------------------- |
50 | | NotifyIcon for WPF | Samples.WpfApp1.csproj |
51 | | NotifyIcon for Console | Samples.ConsoleApp1.csproj |
52 | | NotifyIcon for Avalonia | Samples.AvaloniaApp1.csproj |
53 | | NotifyIcon for WinUI3 | Samples.WinUI3App1.csproj |
54 | | NotifyIcon for MAUI | Samples.MauiApp1.csproj |
55 |
--------------------------------------------------------------------------------
/src/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*.{sh}]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | # Matches multiple files with brace expansion notation
12 | # Set default charset
13 | [*]
14 | charset = utf-8
15 |
16 | # Tab indentation (no size specified)
17 | [Makefile]
18 | indent_style = tab
19 |
20 | [*.{js,json,xaml,axaml,xml,resx,resw,csproj,wapproj,appxmanifest}]
21 | indent_style = space
22 | indent_size = 2
23 |
24 | # c# 文件
25 | [*.cs]
26 |
27 | #### Core EditorConfig 选项 ####
28 |
29 | # 缩进和间距
30 | indent_size = 4
31 | indent_style = space
32 | tab_width = 4
33 |
34 | # 新行首选项
35 | end_of_line = crlf
36 | insert_final_newline = false
37 |
38 | #### .NET 编码约定 ####
39 |
40 | # 组织 Using
41 | dotnet_separate_import_directive_groups = false
42 | dotnet_sort_system_directives_first = false
43 | file_header_template = unset
44 |
45 | # this. 和 Me. 首选项
46 | dotnet_style_qualification_for_event = false:suggestion
47 | dotnet_style_qualification_for_field = false
48 | dotnet_style_qualification_for_method = false:suggestion
49 | dotnet_style_qualification_for_property = false:suggestion
50 |
51 | # 语言关键字与 bcl 类型首选项
52 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
53 | dotnet_style_predefined_type_for_member_access = true:suggestion
54 |
55 | # 括号首选项
56 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
57 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
58 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary
59 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
60 |
61 | # 修饰符首选项
62 | dotnet_style_require_accessibility_modifiers = never
63 |
64 | # 表达式级首选项
65 | dotnet_style_coalesce_expression = true
66 | dotnet_style_collection_initializer = true
67 | dotnet_style_explicit_tuple_names = true
68 | dotnet_style_null_propagation = true
69 | dotnet_style_object_initializer = true
70 | dotnet_style_operator_placement_when_wrapping = beginning_of_line
71 | dotnet_style_prefer_auto_properties = true
72 | dotnet_style_prefer_compound_assignment = true
73 | dotnet_style_prefer_conditional_expression_over_assignment = true
74 | dotnet_style_prefer_conditional_expression_over_return = true
75 | dotnet_style_prefer_inferred_anonymous_type_member_names = true
76 | dotnet_style_prefer_inferred_tuple_names = true
77 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true
78 | dotnet_style_prefer_simplified_boolean_expressions = true
79 | dotnet_style_prefer_simplified_interpolation = true
80 |
81 | # 字段首选项
82 | dotnet_style_readonly_field = true
83 |
84 | # 参数首选项
85 | dotnet_code_quality_unused_parameters = all
86 |
87 | # 禁止显示首选项
88 | dotnet_remove_unnecessary_suppression_exclusions = none
89 |
90 | #### c# 编码约定 ####
91 |
92 | # var 首选项
93 | csharp_style_var_elsewhere = true
94 | csharp_style_var_for_built_in_types = true
95 | csharp_style_var_when_type_is_apparent = true
96 |
97 | # Expression-bodied 成员
98 | csharp_style_expression_bodied_accessors = true
99 | csharp_style_expression_bodied_constructors = false
100 | csharp_style_expression_bodied_indexers = true
101 | csharp_style_expression_bodied_lambdas = true
102 | csharp_style_expression_bodied_local_functions = false
103 | csharp_style_expression_bodied_methods = false
104 | csharp_style_expression_bodied_operators = false
105 | csharp_style_expression_bodied_properties = true
106 |
107 | # 模式匹配首选项
108 | csharp_style_pattern_matching_over_as_with_null_check = true
109 | csharp_style_pattern_matching_over_is_with_cast_check = true
110 | csharp_style_prefer_not_pattern = true
111 | csharp_style_prefer_pattern_matching = true
112 | csharp_style_prefer_switch_expression = true
113 |
114 | # Null 检查首选项
115 | csharp_style_conditional_delegate_call = true
116 |
117 | # 修饰符首选项
118 | csharp_prefer_static_local_function = true
119 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
120 |
121 | # 代码块首选项
122 | csharp_prefer_braces = false
123 | csharp_prefer_simple_using_statement = true
124 |
125 | # 表达式级首选项
126 | csharp_prefer_simple_default_expression = true
127 | csharp_style_deconstructed_variable_declaration = true
128 | csharp_style_implicit_object_creation_when_type_is_apparent = true
129 | csharp_style_inlined_variable_declaration = true
130 | csharp_style_pattern_local_over_anonymous_function = true
131 | csharp_style_prefer_index_operator = true
132 | csharp_style_prefer_range_operator = true
133 | csharp_style_throw_expression = true
134 | csharp_style_unused_value_assignment_preference = discard_variable
135 | csharp_style_unused_value_expression_statement_preference = discard_variable
136 |
137 | # "using" 指令首选项
138 | csharp_using_directive_placement = outside_namespace
139 |
140 | #### C# 格式规则 ####
141 |
142 | # 新行首选项
143 | csharp_new_line_before_catch = true
144 | csharp_new_line_before_else = true
145 | csharp_new_line_before_finally = true
146 | csharp_new_line_before_members_in_anonymous_types = true
147 | csharp_new_line_before_members_in_object_initializers = true
148 | csharp_new_line_before_open_brace = all
149 | csharp_new_line_between_query_expression_clauses = true
150 |
151 | # 缩进首选项
152 | csharp_indent_block_contents = true
153 | csharp_indent_braces = false
154 | csharp_indent_case_contents = true
155 | csharp_indent_case_contents_when_block = true
156 | csharp_indent_labels = one_less_than_current
157 | csharp_indent_switch_labels = true
158 |
159 | # 空格键首选项
160 | csharp_space_after_cast = false
161 | csharp_space_after_colon_in_inheritance_clause = true
162 | csharp_space_after_comma = true
163 | csharp_space_after_dot = false
164 | csharp_space_after_keywords_in_control_flow_statements = true
165 | csharp_space_after_semicolon_in_for_statement = true
166 | csharp_space_around_binary_operators = before_and_after
167 | csharp_space_around_declaration_statements = false
168 | csharp_space_before_colon_in_inheritance_clause = true
169 | csharp_space_before_comma = false
170 | csharp_space_before_dot = false
171 | csharp_space_before_open_square_brackets = false
172 | csharp_space_before_semicolon_in_for_statement = false
173 | csharp_space_between_empty_square_brackets = false
174 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
175 | csharp_space_between_method_call_name_and_opening_parenthesis = false
176 | csharp_space_between_method_call_parameter_list_parentheses = false
177 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
178 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
179 | csharp_space_between_method_declaration_parameter_list_parentheses = false
180 | csharp_space_between_parentheses = false
181 | csharp_space_between_square_brackets = false
182 |
183 | # 包装首选项
184 | csharp_preserve_single_line_blocks = true
185 | csharp_preserve_single_line_statements = true
186 |
187 | #### 命名样式 ####
188 |
189 | # 命名规则
190 |
191 | dotnet_naming_rule.interface_should_be_以_i_开始.severity = suggestion
192 | dotnet_naming_rule.interface_should_be_以_i_开始.symbols = interface
193 | dotnet_naming_rule.interface_should_be_以_i_开始.style = 以_i_开始
194 |
195 | dotnet_naming_rule.类型_should_be_帕斯卡拼写法.severity = suggestion
196 | dotnet_naming_rule.类型_should_be_帕斯卡拼写法.symbols = 类型
197 | dotnet_naming_rule.类型_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
198 |
199 | dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.severity = suggestion
200 | dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.symbols = 非字段成员
201 | dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
202 |
203 | # 符号规范
204 |
205 | dotnet_naming_symbols.interface.applicable_kinds = interface
206 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
207 | dotnet_naming_symbols.interface.required_modifiers =
208 |
209 | dotnet_naming_symbols.类型.applicable_kinds = class, struct, interface, enum
210 | dotnet_naming_symbols.类型.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
211 | dotnet_naming_symbols.类型.required_modifiers =
212 |
213 | dotnet_naming_symbols.非字段成员.applicable_kinds = property, event, method
214 | dotnet_naming_symbols.非字段成员.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
215 | dotnet_naming_symbols.非字段成员.required_modifiers =
216 |
217 | # 命名样式
218 |
219 | dotnet_naming_style.帕斯卡拼写法.required_prefix =
220 | dotnet_naming_style.帕斯卡拼写法.required_suffix =
221 | dotnet_naming_style.帕斯卡拼写法.word_separator =
222 | dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
223 |
224 | dotnet_naming_style.以_i_开始.required_prefix = I
225 | dotnet_naming_style.以_i_开始.required_suffix =
226 | dotnet_naming_style.以_i_开始.word_separator =
227 | dotnet_naming_style.以_i_开始.capitalization = pascal_case
228 |
229 | # IDE0010: 添加缺失的事例
230 | dotnet_diagnostic.IDE0010.severity = none
231 |
232 | # IDE0011: 添加大括号
233 | dotnet_diagnostic.IDE0011.severity = none
234 |
235 | # IDE0040: 添加可访问性修饰符
236 | dotnet_diagnostic.IDE0040.severity = none
237 |
238 | # IDE0130: 命名空间与文件夹结构不匹配
239 | dotnet_style_namespace_match_folder = false
240 |
241 | # IDE0130: 命名空间与文件夹结构不匹配
242 | dotnet_diagnostic.IDE0130.severity = none
243 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(NoWarn);NU1507;1591;SA1612;IL2026
4 | latest
5 | enable
6 | true
7 | true
8 | true
9 | false
10 |
11 | 1.23.10209.11223
12 | https://avatars.githubusercontent.com/u/79355691?s=200&v=4
13 | 长沙次元超越科技有限公司
14 | ©️ $(Company). All rights reserved.
15 | $(Company)
16 | $(Version)
17 | $(Version)
18 | true
19 |
20 |
21 |
22 |
23 | Properties
24 |
25 |
26 |
27 |
28 | SIGN_ASSEMBLY;$(DefineConstants)
29 | true
30 | false
31 | ..\NotifyIcon.snk
32 |
33 |
34 |
35 | 7.0
36 |
37 |
38 |
39 | 10.14
40 |
41 |
42 |
47 | __LIB_SYS_OS2__;$(DefineConstants)
48 |
49 |
50 |
55 | DRAWING;$(DefineConstants)
56 |
57 |
58 |
62 | NET5_0_OR_GREATER2;$(DefineConstants)
63 |
64 |
65 |
68 | XAMARIN_MAC;$(DefineConstants)
69 |
70 |
71 |
77 | MONO_MAC;$(DefineConstants)
78 |
79 |
80 |
81 | NET_WINDOWS;$(DefineConstants)
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/src/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/GeneratePackage.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | MIT
4 | https://github.com/BeyondDimension/NotifyIcon
5 | $(PackageProjectUrl)/releases
6 | $(PackageProjectUrl).git
7 | git
8 | main
9 | true
10 | true
11 | true
12 | $(MSBuildProjectDirectory)\..\..\pkg
13 |
14 | true
15 |
16 | true
17 | snupkg
18 | true
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/ImplicitUsings.cs:
--------------------------------------------------------------------------------
1 | // C# 10 定义全局 using
2 |
3 | #pragma warning disable IDE0079 // 请删除不必要的忽略
4 | #pragma warning disable IDE0005
5 | #pragma warning disable SA1209 // Using alias directives should be placed after other using directives
6 | #pragma warning disable SA1211 // Using alias directives should be ordered alphabetically by alias name
7 |
8 | global using System;
9 | global using System.Collections.Generic;
10 | global using System.IO;
11 | global using System.Linq;
12 | #if !NET35 && !NET40 && !NET45 && !NETSTANDARD1_0
13 | global using System.Net.Http;
14 | #endif
15 | global using System.Threading;
16 | #if !NET35
17 | global using System.Threading.Tasks;
18 | #endif
19 | #if NET5_0_OR_GREATER2
20 | global using System.Runtime.Versioning;
21 | #endif
22 |
--------------------------------------------------------------------------------
/src/NotifyIcon.Platform.Linux/LinuxNotifyIcon.cs:
--------------------------------------------------------------------------------
1 | #if !XAMARIN_MAC && !__MACOS__ && !NET6_0_MACOS10_14 && !NET_WINDOWS && !NET5_0_WINDOWS && !NET6_0_WINDOWS && !NETSTANDARD1_0 && !NET35 && !NET40 && !NET45 && !NETSTANDARD1_1
2 | using Gdk;
3 | using Gtk;
4 |
5 | namespace System.Windows;
6 |
7 | #pragma warning disable CS0612 // 类型或成员已过时
8 | #if NET5_0_OR_GREATER2
9 | [SupportedOSPlatform("linux")]
10 | #endif
11 | internal sealed class LinuxNotifyIcon : NotifyIcon
12 | {
13 | readonly StatusIcon statusIcon;
14 | Menu? popupMenu;
15 |
16 | public LinuxNotifyIcon() : base()
17 | {
18 | statusIcon = new();
19 | statusIcon.Activate += StatusIcon_Activate;
20 | statusIcon.PopupMenu += StatusIcon_PopupMenu;
21 | }
22 |
23 | void StatusIcon_Activate(object? sender, EventArgs e) => Click?.Invoke(sender, e);
24 |
25 | void StatusIcon_PopupMenu(object? sender, PopupMenuArgs _)
26 | {
27 | popupMenu?.Dispose();
28 |
29 | if (!ContextMenuStrip.Items.Any()) return;
30 |
31 | popupMenu = new();
32 |
33 | popupMenu.Deactivated += PopupMenu_Deactivated;
34 | popupMenu.PoppedUp += PopupMenu_PoppedUp;
35 |
36 | foreach (var item in ContextMenuStrip.Items)
37 | {
38 | MenuItem menuItem;
39 | if (item.Icon != null)
40 | {
41 | var icon = Convert(item.Icon);
42 | menuItem = new ImageMenuItem(item.Text)
43 | {
44 | Image = new Image(icon, IconSize.Menu),
45 | };
46 | }
47 | else
48 | {
49 | menuItem = new MenuItem(item.Text);
50 | }
51 | menuItem.Activated += (s, e) => OnContextMenuItemClick(item, s, e);
52 | popupMenu.Add(menuItem);
53 | }
54 |
55 | popupMenu.ShowAll();
56 | popupMenu.Popup();
57 |
58 | RightClick?.Invoke(sender, MouseEventArgs.Empty);
59 | }
60 |
61 | private void PopupMenu_PoppedUp(object? sender, EventArgs e)
62 | => OnContextMenuPopup(sender, e);
63 |
64 | private void PopupMenu_Deactivated(object? sender, EventArgs e)
65 | {
66 | if (popupMenu != null)
67 | {
68 | popupMenu.Deactivated -= PopupMenu_Deactivated;
69 | popupMenu.PoppedUp -= PopupMenu_PoppedUp;
70 | }
71 | OnContextMenuCollapse(sender, e);
72 | }
73 |
74 | static GLib.IIcon Convert(object? value)
75 | {
76 | if (value is GLib.IIcon icon)
77 | {
78 | return icon;
79 | }
80 | else
81 | {
82 | Pixbuf pixbuf;
83 | if (value is byte[] byteArray)
84 | {
85 | pixbuf = new(byteArray);
86 | }
87 | else if (value is Stream stream)
88 | {
89 | pixbuf = new(stream);
90 | }
91 | else if (value is string fileName)
92 | {
93 | pixbuf = new(fileName);
94 | }
95 | else if (value is FileInfo fileInfo)
96 | {
97 | pixbuf = new(fileInfo.FullName);
98 | }
99 | else if (value is IntPtr intPtr)
100 | {
101 | pixbuf = new(intPtr);
102 | }
103 | else if (value is string[] strArray)
104 | {
105 | pixbuf = new(strArray);
106 | }
107 | else if (value is GLib.IAsyncResult asyncResult)
108 | {
109 | pixbuf = new(asyncResult);
110 | }
111 | else
112 | {
113 | throw new NotSupportedException();
114 | }
115 | return pixbuf;
116 | }
117 | }
118 |
119 | public override object? Icon
120 | {
121 | set => statusIcon.Icon = Convert(value);
122 | }
123 |
124 | public override string? Text
125 | {
126 | get => statusIcon.TooltipText;
127 | set => statusIcon.TooltipText = value;
128 | }
129 |
130 | public override bool Visible
131 | {
132 | get => statusIcon.Visible;
133 | set => statusIcon.Visible = value;
134 | }
135 |
136 | public override event EventHandler? Click;
137 |
138 | public override event EventHandler? DoubleClick;
139 |
140 | public override event EventHandler? RightClick;
141 |
142 | bool disposedValue;
143 | protected override void Dispose(bool disposing)
144 | {
145 | if (!disposedValue)
146 | {
147 | if (disposing)
148 | {
149 | // TODO: 释放托管状态(托管对象)
150 | popupMenu?.Dispose();
151 | statusIcon.Activate -= StatusIcon_Activate;
152 | statusIcon.PopupMenu -= StatusIcon_PopupMenu;
153 | statusIcon.Dispose();
154 | }
155 |
156 | // TODO: 释放未托管的资源(未托管的对象)并重写终结器
157 | // TODO: 将大型字段设置为 null
158 | disposedValue = true;
159 | }
160 | base.Dispose(disposing);
161 | }
162 | }
163 | #pragma warning restore CS0612 // 类型或成员已过时
164 |
165 | #endif
--------------------------------------------------------------------------------
/src/NotifyIcon.Platform.Linux/NotifyIcon.Platform.Linux.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net6.0;net7.0
5 | System.Windows.NotifyIcon.Linux
6 | System.Windows
7 | 在通知区域创建图标的组件的 Linux 实现。
8 | NotifyIcon.Linux
9 | LINUX;SINGLE_PLATFORM;$(DefineConstants)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/NotifyIcon.Platform.Mac/MacNotifyIcon.cs:
--------------------------------------------------------------------------------
1 | #if !NET_WINDOWS && !NET5_0_WINDOWS && !NET6_0_WINDOWS && !NETSTANDARD1_0 && !NET35 && !NET40 && !NET45 && !NETSTANDARD1_1
2 | #if MONO_MAC
3 | using MonoMac.AppKit;
4 | using MonoMac.Foundation;
5 | using MonoMac.CoreGraphics;
6 | #elif XAMARIN_MAC
7 | using AppKit;
8 | using Foundation;
9 | using CoreGraphics;
10 | using UserNotifications;
11 | #endif
12 | using System.ComponentModel;
13 | using System.Collections.Specialized;
14 |
15 | namespace System.Windows;
16 |
17 | #if NET5_0_OR_GREATER2
18 | [SupportedOSPlatform("macos")]
19 | #endif
20 | internal sealed class MacNotifyIcon : NotifyIcon
21 | {
22 | NSStatusItem? statusItem;
23 |
24 | public MacNotifyIcon() : base()
25 | {
26 | #if MONO_MAC
27 | var length = -1D;
28 | #else
29 | var length = NSStatusItemLength.Variable;
30 | #endif
31 | NSRunLoop.Main.InvokeOnMainThread(() =>
32 | {
33 | statusItem = NSStatusBar.SystemStatusBar.CreateStatusItem(length);
34 | statusItem.DoubleClick += StatusItem_DoubleClick;
35 | });
36 | }
37 |
38 | void StatusItem_DoubleClick(object? sender, EventArgs e)
39 | => DoubleClick?.Invoke(sender, e);
40 |
41 | static NSImage Convert(object? value)
42 | {
43 | if (value is NSImage image)
44 | {
45 | return image;
46 | }
47 | else
48 | {
49 | if (value is byte[] byteArray)
50 | {
51 | return new NSImage(NSData.FromArray(byteArray));
52 | }
53 | if (value is Stream stream)
54 | {
55 | return NSImage.FromStream(stream);
56 | }
57 | else if (value is string fileName)
58 | {
59 | return new(fileName);
60 | }
61 | else if (value is FileInfo fileInfo)
62 | {
63 | return new(fileInfo.FullName);
64 | }
65 | #if MONO_MAC
66 | else if (value is IntPtr intPtr)
67 | {
68 | return new(intPtr);
69 | }
70 | #endif
71 | else if (value is NSPasteboard pasteboard)
72 | {
73 | return new(pasteboard);
74 | }
75 | else if (value is NSCoder coder)
76 | {
77 | return new(coder);
78 | }
79 | #if MONO_MAC
80 | else if (value is NSObjectFlag t)
81 | {
82 | return new(t);
83 | }
84 | #endif
85 | else if (value is NSUrl url)
86 | {
87 | return new(url);
88 | }
89 | else if (value is CGSize aSize)
90 | {
91 | return new(aSize);
92 | }
93 | else if (value is NSData data)
94 | {
95 | return new(data);
96 | }
97 | else
98 | {
99 | throw new NotSupportedException();
100 | }
101 | }
102 | }
103 |
104 | #if NET5_0_OR_GREATER2
105 | [UnsupportedOSPlatform("macos10.10")]
106 | #endif
107 | public override object? Icon
108 | {
109 | set => statusItem!.Image = Convert(value);
110 | }
111 |
112 | #if NET5_0_OR_GREATER2
113 | [UnsupportedOSPlatform("macos10.10")]
114 | #endif
115 | public override string? Text
116 | {
117 | get => statusItem!.ToolTip;
118 | set => statusItem!.ToolTip = value;
119 | }
120 |
121 | public override bool Visible
122 | #if MONO_MAC
123 | {
124 | get => statusItem!.View.NeedsDisplay;
125 | set => statusItem!.View.NeedsDisplay = value;
126 | }
127 | #else
128 | {
129 | get => statusItem!.Visible;
130 | set => statusItem!.Visible = value;
131 | }
132 | #endif
133 |
134 | public override event EventHandler? Click;
135 |
136 | public override event EventHandler? DoubleClick;
137 |
138 | public override event EventHandler? RightClick;
139 |
140 | bool disposedValue;
141 | protected override void Dispose(bool disposing)
142 | {
143 | if (!disposedValue)
144 | {
145 | if (disposing)
146 | {
147 | // TODO: 释放托管状态(托管对象)
148 | if (statusItem != null)
149 | {
150 | statusItem.DoubleClick -= StatusItem_DoubleClick;
151 | statusItem.Dispose();
152 | statusItem = null;
153 | }
154 | }
155 |
156 | // TODO: 释放未托管的资源(未托管的对象)并重写终结器
157 | // TODO: 将大型字段设置为 null
158 | disposedValue = true;
159 | }
160 | base.Dispose(disposing);
161 | }
162 |
163 | readonly Dictionary menuItems = new();
164 |
165 | NSMenuItem Convert(ContextMenuStrip.MenuItem menuItem)
166 | {
167 | if (menuItems.ContainsKey(menuItem)) return menuItems[menuItem];
168 | NSMenuItem menuItem1 = new();
169 | menuItem.PropertyChanged += MenuItem_PropertyChanged;
170 | menuItem1.Activated += (s, e) => OnContextMenuItemClick(menuItem, s, e);
171 | MenuItem_PropertyChanged(menuItem1, new(nameof(ContextMenuStrip.MenuItem.Text)));
172 | MenuItem_PropertyChanged(menuItem1, new(nameof(ContextMenuStrip.MenuItem.Icon)));
173 | MenuItem_PropertyChanged(menuItem1, new(nameof(ContextMenuStrip.MenuItem.Visible)));
174 | menuItems.Add(menuItem, menuItem1);
175 | return menuItem1;
176 | void MenuItem_PropertyChanged(object? sender, PropertyChangedEventArgs e)
177 | {
178 | switch (e.PropertyName)
179 | {
180 | case nameof(ContextMenuStrip.MenuItem.Text):
181 | menuItem1.Title = menuItem.Text ?? string.Empty;
182 | break;
183 | case nameof(ContextMenuStrip.MenuItem.Icon):
184 | menuItem1.Image = menuItem.Icon != null ? Convert(menuItem.Icon) : null;
185 | break;
186 | case nameof(ContextMenuStrip.MenuItem.Visible):
187 | if (menuItem1.View != null)
188 | {
189 | menuItem1.View.NeedsDisplay = menuItem.Visible;
190 | }
191 | break;
192 | }
193 | }
194 | }
195 |
196 | protected override void Items_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
197 | {
198 | if (statusItem!.Menu == null)
199 | {
200 | statusItem.Menu = new();
201 | }
202 | var newStartingIndex = e.NewStartingIndex < 0 ? 0 : e.NewStartingIndex;
203 | switch (e.Action)
204 | {
205 | case NotifyCollectionChangedAction.Add:
206 | Add();
207 | break;
208 | case NotifyCollectionChangedAction.Remove:
209 | Remove();
210 | break;
211 | case NotifyCollectionChangedAction.Replace:
212 | case NotifyCollectionChangedAction.Move:
213 | Remove();
214 | Add();
215 | break;
216 | case NotifyCollectionChangedAction.Reset:
217 | newStartingIndex = 0;
218 | statusItem.Menu.RemoveAllItems();
219 | foreach (var item in menuItems.Values)
220 | {
221 | item.Dispose();
222 | }
223 | menuItems.Clear();
224 | Add();
225 | break;
226 | }
227 | void Add()
228 | {
229 | if (e.NewItems == null) return;
230 | foreach (var item in e.NewItems)
231 | {
232 | if (item is ContextMenuStrip.MenuItem menuItem)
233 | {
234 | var newItem = Convert(menuItem);
235 | statusItem.Menu.InsertItem(newItem, newStartingIndex++);
236 | }
237 | }
238 | }
239 | void Remove()
240 | {
241 | if (e.OldItems == null) return;
242 | foreach (var item in e.OldItems)
243 | {
244 | if (item is ContextMenuStrip.MenuItem menuItem)
245 | {
246 | if (menuItems.ContainsKey(menuItem))
247 | {
248 | var removeItem = menuItems[menuItem];
249 | statusItem.Menu.RemoveItem(removeItem);
250 | removeItem.Dispose();
251 | }
252 | }
253 | }
254 | }
255 | }
256 |
257 | #if !MONO_MAC
258 | public override void ShowBalloonTip(string tipTitle, string tipText, ToolTipIcon tipIcon)
259 | {
260 | // https://docs.microsoft.com/en-us/dotnet/api/usernotifications.unusernotificationcenter?view=xamarin-mac-sdk-14
261 | // https://github.com/davidortinau/WeatherTwentyOne/blob/main/src/WeatherTwentyOne/Platforms/MacCatalyst/NotificationService.cs
262 |
263 | UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert, (approved, err) =>
264 | {
265 | if (!approved)
266 | return;
267 |
268 | var content = new UNMutableNotificationContent()
269 | {
270 | Title = tipTitle,
271 | Body = tipText,
272 | };
273 |
274 | var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(0.25, false);
275 | var request = UNNotificationRequest.FromIdentifier(Guid.NewGuid().ToString(), content, trigger);
276 | UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
277 | {
278 | if (err != null)
279 | throw new Exception($"Failed to schedule notification: {err}");
280 | });
281 | });
282 | }
283 | #endif
284 | }
285 | #endif
--------------------------------------------------------------------------------
/src/NotifyIcon.Platform.Mac/NotifyIcon.Platform.Mac.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net461;net6.0-macos;net7.0-macos
5 | System.Windows.NotifyIcon.Mac
6 | System.Windows
7 | 在通知区域创建图标的组件的 macOS 实现。
8 | NotifyIcon.Mac
9 | MAC;SINGLE_PLATFORM;$(DefineConstants)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/NotifyIcon.Platform.Windows/NotifyIcon.Platform.Windows.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net7.0;net6.0;net461;net45;net40;net35;netstandard2.0
5 | System.Windows.NotifyIcon.Windows
6 | System.Windows
7 | 在通知区域创建图标的组件的 Win32 API 实现。
8 | NotifyIcon.Windows
9 | WINDOWS;SINGLE_PLATFORM;$(DefineConstants)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/NotifyIcon.Platform/ContextMenuStrip.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.ComponentModel;
3 | using System.Windows.Input;
4 |
5 | namespace System.Windows;
6 |
7 | ///
8 | /// 表示快捷菜单。
9 | ///
10 | public sealed class ContextMenuStrip
11 | {
12 | internal ContextMenuStrip()
13 | {
14 | Items = new();
15 | }
16 |
17 | ///
18 | /// 获取或设置菜单项。
19 | ///
20 | public ObservableCollection