Add-StructuredTray.ps1 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. if (-not (Get-Module -ListAvailable -Name powershell-yaml)) {
  2. Install-Module -Scope CurrentUser powershell-yaml
  3. }
  4. Import-Module powershell-yaml
  5. # Add-StructuredTray
  6. # by Tobias Simetsreiter <tobias@tsimnet.eu>
  7. # .Net methods for hiding/showing the console in the background
  8. Add-Type -ReferencedAssemblies "System.Drawing" -Language CSharp @"
  9. using System.Drawing;
  10. using System.Runtime.InteropServices;
  11. using System;
  12. namespace Console {
  13. public class Window {
  14. [DllImport("Kernel32.dll")]
  15. public static extern IntPtr GetConsoleWindow();
  16. [DllImport("user32.dll")]
  17. public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
  18. }
  19. }
  20. "@;
  21. [Int]$global:ConsoleVisible = $true
  22. Function Toggle-Console(){
  23. $consolePtr = [Console.Window]::GetConsoleWindow()
  24. $visible = (-not $global:ConsoleVisible)
  25. $global:ConsoleVisible = $visible
  26. $visible | Out-Host
  27. [Console.Window]::ShowWindow($consolePtr, [Int]$visible)
  28. }
  29. # Add assemblies for WPF and Mahapps
  30. Add-Type -AssemblyName "System.Windows.Forms"
  31. Add-Type -AssemblyName "System.Drawing"
  32. Add-Type -AssemblyName "presentationframework"
  33. Add-Type -AssemblyName "WindowsFormsIntegration"
  34. Function Add-StructuredTray{
  35. param(
  36. [Parameter(ValueFromPipeline=$true)]
  37. [PSCustomObject[]]$definition,
  38. $ParentTray = $null,
  39. [String]$Config
  40. )
  41. BEGIN {
  42. $ErrorActionPreference = "Stop"
  43. }
  44. PROCESS {
  45. $Script:TopTray = $false
  46. if (-not $definition){
  47. $definition = Get-Content $Config -Raw | ConvertFrom-Yaml
  48. }
  49. if ($null -eq $ParentTray){
  50. # Hide Console
  51. if ($definition.HideConsole -eq $true){
  52. Toggle-Console
  53. }
  54. # Add the systray icon
  55. if ($definition.Icon){
  56. $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($definition.Icon)
  57. } else {
  58. $icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Command cmd.exe).source)
  59. }
  60. $Script:Tray_Icon = New-Object System.Windows.Forms.NotifyIcon
  61. $Script:Tray_Icon.Text = $definition.Title
  62. $Script:Tray_Icon.Icon = $icon
  63. $Script:Tray_Icon.Visible = $true
  64. $Host.UI.RawUI.WindowTitle = $definition.Title
  65. # Add all menus as context menus
  66. $ParentTray = New-Object System.Windows.Forms.ContextMenu
  67. $Script:TopTray = $ParentTray
  68. $Script:Tray_Icon.ContextMenu = $ParentTray
  69. $Script:Tray_Icon.add_Click({
  70. # [System.Windows.Forms.Integration.ElementHost]::EnableModelessKeyboardInterop($Users_Window)
  71. # If ($_.Button -eq [Windows.Forms.MouseButtons]::Left) {
  72. # "Clicked" | Out-Host
  73. # }
  74. })
  75. if ($definition.MenuItems){
  76. $definition.MenuItems | Add-StructuredTray -Parent $ParentTray
  77. }
  78. $Menu_Exit = New-Object System.Windows.Forms.MenuItem
  79. $Menu_Exit.Text = "Exit"
  80. $Menu_Exit.add_Click({
  81. $Script:Tray_Icon.Visible = $false
  82. $Script:Tray_Icon.Dispose()
  83. $Script:appContext.ExitThread()
  84. })
  85. $ParentTray.MenuItems.AddRange($Menu_Exit)
  86. # Use a Garbage colection to reduce Memory RAM
  87. [System.GC]::Collect()
  88. $Script:appContext = New-Object System.Windows.Forms.ApplicationContext
  89. [void][System.Windows.Forms.Application]::Run($Script:appContext)
  90. $Script:Tray_Icon.Visible = $false
  91. $Script:Tray_Icon.Dispose()
  92. } else {
  93. $Menu_Script = New-Object System.Windows.Forms.MenuItem
  94. $Menu_Script.Text = $definition.Text
  95. $Menu_Script.Tag = $definition
  96. if ($null -ne $definition.Enabled){
  97. $Menu_Script.Enabled = $definition.Enabled
  98. }
  99. if ($definition.Command){
  100. $Menu_Script.add_Click({
  101. Param ($com)
  102. $com.Tag.Command | Out-host
  103. if ($com.Tag.NewWindow -eq $true){
  104. Start-Process powershell -ArgumentList ("-ExecutionPolicy", "Bypass", "-noprofile", $com.Tag.Command)
  105. } else {
  106. $return = Invoke-Expression $com.Tag.Command
  107. }
  108. if ($com.Tag.Notification){
  109. $Script:Tray_Icon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Info
  110. $Script:Tray_Icon.BalloonTipText = $return
  111. $Script:Tray_Icon.BalloonTipTitle = $com.Tag.Text
  112. $Script:Tray_Icon.ShowBalloonTip(5000)
  113. } else {
  114. $return | Out-Host
  115. }
  116. })
  117. }
  118. $ParentTray.MenuItems.AddRange($Menu_Script)
  119. if ($definition.MenuItems){
  120. $definition.MenuItems | Add-StructuredTray -Parent $Menu_Script
  121. }
  122. }
  123. }
  124. }