浏览代码

add Add-StructuredTray.ps1

Tobias Simetsreiter 4 年之前
父节点
当前提交
491deb6b1f
共有 3 个文件被更改,包括 179 次插入0 次删除
  1. 142 0
      Tray/Add-StructuredTray.ps1
  2. 19 0
      Tray/tray_test.bat
  3. 18 0
      Tray/tray_test.yaml

+ 142 - 0
Tray/Add-StructuredTray.ps1

@@ -0,0 +1,142 @@
+if (-not (Get-Module -ListAvailable -Name powershell-yaml)) {
+    Install-Module -Scope CurrentUser powershell-yaml
+}
+Import-Module powershell-yaml
+
+# Add-StructuredTray
+# by Tobias Simetsreiter <tobias@tsimnet.eu>
+ 
+ # .Net methods for hiding/showing the console in the background
+Add-Type -ReferencedAssemblies "System.Drawing" -Language CSharp @"
+using System.Drawing;
+using System.Runtime.InteropServices;
+using System;
+
+namespace Console {
+    public class Window {
+        [DllImport("Kernel32.dll")]
+        public static extern IntPtr GetConsoleWindow();
+    
+        [DllImport("user32.dll")]
+        public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
+    }
+}
+"@;
+
+[Int]$global:ConsoleVisible = $true
+Function Toggle-Console(){
+    $consolePtr = [Console.Window]::GetConsoleWindow()
+    $visible = (-not $global:ConsoleVisible)
+    $global:ConsoleVisible = $visible
+    $visible | Out-Host
+    [Console.Window]::ShowWindow($consolePtr, [Int]$visible)
+} 
+
+
+# Add assemblies for WPF and Mahapps
+Add-Type -AssemblyName "System.Windows.Forms"
+Add-Type -AssemblyName "System.Drawing"
+Add-Type -AssemblyName "presentationframework"
+Add-Type -AssemblyName "WindowsFormsIntegration"
+
+Function Add-StructuredTray{
+    param(
+        [Parameter(ValueFromPipeline=$true)]
+        [PSCustomObject[]]$definition,
+        $ParentTray = $null,
+        [String]$Config
+    )
+    BEGIN {
+        $ErrorActionPreference = "Stop"
+    }
+    PROCESS {
+        $Script:TopTray = $false
+        if (-not $definition){
+            $definition = Get-Content $Config -Raw | ConvertFrom-Yaml
+        }
+        if ($ParentTray -eq $null){
+            
+            # Hide Console
+            if ($definition.HideConsole -eq $true){
+                Toggle-Console
+            }
+            # Add the systray icon 
+            if ($definition.Icon){
+                $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($definition.Icon)
+            } else {
+                $icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Command cmd.exe).source)
+            }
+            $Script:Tray_Icon = New-Object System.Windows.Forms.NotifyIcon
+            $Script:Tray_Icon.Text = $definition.Title
+            $Script:Tray_Icon.Icon = $icon
+            $Script:Tray_Icon.Visible = $true
+
+            $Host.UI.RawUI.WindowTitle = $definition.Title
+
+            # Add all menus as context menus
+            $ParentTray = New-Object System.Windows.Forms.ContextMenu
+            $Script:TopTray = $ParentTray
+            $Script:Tray_Icon.ContextMenu = $ParentTray
+            $Script:Tray_Icon.add_Click({
+                # [System.Windows.Forms.Integration.ElementHost]::EnableModelessKeyboardInterop($Users_Window)
+                # If ($_.Button -eq [Windows.Forms.MouseButtons]::Left) {
+                #     "Clicked" | Out-Host
+                # }
+            })
+        
+            if ($definition.MenuItems){
+                $definition.MenuItems | Add-StructuredTray -Parent $ParentTray
+            }
+            
+            $Menu_Exit = New-Object System.Windows.Forms.MenuItem
+            $Menu_Exit.Text = "Exit"
+            $Menu_Exit.add_Click({
+                $Script:Tray_Icon.Visible = $false
+                $Script:Tray_Icon.Dispose()
+                $Script:appContext.ExitThread()
+            })
+            $ParentTray.MenuItems.AddRange($Menu_Exit)
+
+            # Use a Garbage colection to reduce Memory RAM
+            [System.GC]::Collect()
+
+            $Script:appContext = New-Object System.Windows.Forms.ApplicationContext
+    
+            [void][System.Windows.Forms.Application]::Run($Script:appContext)
+            $Script:Tray_Icon.Visible = $false
+            $Script:Tray_Icon.Dispose()
+        } else {
+            $Menu_Script = New-Object System.Windows.Forms.MenuItem
+            $Menu_Script.Text = $definition.Text
+            $Menu_Script.Tag = $definition
+            if (-not ($definition.Enabled -eq $null)){
+                $Menu_Script.Enabled = $definition.Enabled
+            }
+            if ($definition.Command){
+                $Menu_Script.add_Click({
+                    Param ($com)
+                    $com.Tag.Command | Out-host
+                    
+                    if ($com.Tag.NewWindow -eq $true){
+                        Start-Process powershell -ArgumentList ("-ExecutionPolicy", "Bypass", "-noprofile", $com.Tag.Command)
+                    } else {
+                        $return = Invoke-Expression $com.Tag.Command
+                    }
+                    if ($com.Tag.Notification){
+                        $Script:Tray_Icon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Info
+                        $Script:Tray_Icon.BalloonTipText  = $return
+                        $Script:Tray_Icon.BalloonTipTitle = $com.Tag.Text
+                        $Script:Tray_Icon.ShowBalloonTip(5000)
+                    } else {
+                        $return | Out-Host
+                    }
+                })
+            }
+            $ParentTray.MenuItems.AddRange($Menu_Script)
+        
+            if ($definition.MenuItems){
+                $definition.MenuItems | Add-StructuredTray -Parent $Menu_Script
+            }
+        }
+    }
+}

+ 19 - 0
Tray/tray_test.bat

@@ -0,0 +1,19 @@
+<# : Begin batch (batch script is in commentary of powershell v2.0+)
+@echo off
+: Use local variables
+setlocal
+: Change current directory to script location - useful for including .ps1 files
+cd "%~dp0"
+setx SCRIPT_NAME "%~f0"
+: Invoke this file as powershell expression
+powershell -executionpolicy remotesigned -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))"
+: Restore environment variables present before setlocal and restore current directory
+endlocal
+: End batch - go to end of file
+goto:eof
+#>
+# here start your powershell script
+
+Import-Module ./Add-StructuredTray.ps1 -Force
+
+Add-StructuredTray -Config tray_test.yaml

+ 18 - 0
Tray/tray_test.yaml

@@ -0,0 +1,18 @@
+Text: "AXVPN Tray"
+Title: "AXVPN Tray"
+Icon: ""
+HideConsole: true
+MenuItems:
+  - Text: "AXVPN Tray"
+    Enabled: false
+  - Text: "ls"
+    Command: "ls"
+    Notification: true
+  - Text: "ping 8.8.8.8"
+    NewWindow: true
+    Command: "ping -t 8.8.8.8"
+  - Text: "Open Directory"
+    Command: "start ."
+  - Text: "Powershell"
+    NewWindow: true
+    Command: "powershell"