chkdsk
Goto Top

Powershell Skript nach Systray verschieben

Guten Morgen Zusammen,

ich habe folgendes kleines Skript was den Screensaver aushebelt und alle 60 Sekunden die Leertaste drückt.
param($minutes = 44640)

$myshell = New-Object -com "Wscript.Shell"  

for ($i = 0; $i -lt $minutes; $i++) {
  Start-Sleep -Seconds 60
  $myshell.sendkeys("Space")  
}

Wie bekomm ich das Skript nach Start in ein Systray mit der Rechtsklick Option "Beenden" und Pausieren"?

Content-Key: 606942

Url: https://administrator.de/contentid/606942

Printed on: April 25, 2024 at 15:04 o'clock

Member: BirdyB
Solution BirdyB Sep 23, 2020 at 08:57:57 (UTC)
Goto Top
Moin,

ich habe es selbst noch nicht probiert, aber schau doch mal hier:
http://www.systanddeploy.com/2018/12/create-your-own-powershell.html

VG
Member: satosan
satosan Sep 23, 2020 at 09:14:14 (UTC)
Goto Top
Zitat von @BirdyB:

ich habe es selbst noch nicht probiert, aber schau doch mal hier:
http://www.systanddeploy.com/2018/12/create-your-own-powershell.html

Ja da gibts diverse leicht verstaendliche Anleitungen im 'English'-sprachigen Raum. Die aehneln sich alle irgendwie und sollten dem TO weiterhelfen. Ich glaube mal bei 'Adam The Automator' auch mal eine umfangreiche Anleitung gelesen zu haben.

VG Sato
Member: chkdsk
chkdsk Sep 23, 2020 at 09:14:58 (UTC)
Goto Top
Moin Zusammen,

Ich habe jetzt folgendes.
Skript wird gestartet und wandert direkt in den Tray. Rechtsklickmenü mit 3 Auswahlpunkten klappt auch auf. Beenden funktioniert. Start allerdings nicht (ab Zeile 147). Wie man eine Pausieren Funktion einbaut, erschließt sich mir auch noch nicht ganz.
Nice to have wäre auch, das man den aktuellen Status beim einfachen klick auf das Tray sieht, also ob das Skript lüft oder pausiert ist.
$window = Add-Type -memberDefinition @"  
[DllImport("user32.dll")]  
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions -passThru  
$window::ShowWindow((Get-Process –id $pid).MainWindowHandle, 0) 


Add-Type -AssemblyName PresentationFramework, System.Drawing, System.Windows.Forms
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')  
[xml]$XAML = @'  
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        xmlns:local="clr-namespace:WpfApp3"  
        Name="window" WindowStyle="None" Width="180" Height="70" Opacity="0.85" AllowsTransparency="False">  
        <Window.Resources>
        <Style TargetType="GridViewColumnHeader">            
            <Setter Property="Foreground" Value="Black"/>              
            <Setter Property="FontWeight" Value="Bold"/>  
            <Setter Property="Opacity" Value="0.5"/>  
            <Setter Property="Template">  
                <Setter.Value>
                    <ControlTemplate TargetType="GridViewColumnHeader">  
                    <Border Background="Black">  
                    <ContentPresenter></ContentPresenter>
                    </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        </Window.Resources>
    <Grid Name="grid" Height="50" HorizontalAlignment="Left" VerticalAlignment="Top">        

<Label Name="Title" Content="no Screensaver" HorizontalAlignment="Left" VerticalAlignment="Top" Width="513" Background="Black" Foreground="White" FontWeight="Bold" FontSize="20" Height="70"/>  
		
        	
	
            <ListView Name="listview" SelectionMode="Single" Foreground="Black" Background="Transparent" BorderBrush="Black" IsHitTestVisible="False">  
                <ListView.ItemContainerStyle>
                    <Style>                        
                    </Style>
                </ListView.ItemContainerStyle>
            </ListView>
    </Grid>
</Window>
'@  

#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}  

#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}  

Function RefreshData{
#===========================================================================
# Stores WMI values in WMI Object from System Classes
#===========================================================================
$oWMIOS = @()
$oWMIHD = @()
$oWMINIC = @()
$oWMICPU = @()
$oWMIOS = Get-WmiObject win32_OperatingSystem
$oWMIHD = Get-WmiObject Win32_Volume -Filter "DriveType='3'"  
$oWMINIC = Get-WmiObject Win32_NetworkAdapterConfiguration | Where { $_.IPAddress } | Select -Expand IPAddress | Where { $_ -like '1*' }  
$oWMICPU = Get-WmiObject win32_processor | select Name, LoadPercentage

#===========================================================================
# Links WMI Object Values to XAML Form Fields
#===========================================================================
$txtUsername.Text = $env:UserName
$txtDomain.Text = $env:USERDNSDOMAIN
$txtHostName.Text = $oWMIOS.PSComputerName

#Formats and displays OS name
$aOSName = $oWMIOS.name.Split("|")  
$txtOSName.Text = $aOSName

#Displays IP Address
$txtWindowsIP.Text = $oWMINIC ; VPN: 

}

#===========================================================================
# Build Tray Icon
#===========================================================================
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Windows\System32\SystemSettingsBroker.exe")  

# Populate ListView with PS Object data and set width 
$listview.ItemsSource = $disks
$listview.Width = $grid.width*.9 

# Create GridView object to add to ListView 
$gridview = New-Object System.Windows.Controls.GridView 
 
# Dynamically add columns to GridView, then bind data to columns 
foreach ($column in $columnorder) { 
    $gridcolumn = New-Object System.Windows.Controls.GridViewColumn 
    $gridcolumn.Header = $column 
    $gridcolumn.Width = $grid.width*.20 
    $gridbinding = New-Object System.Windows.Data.Binding $column 
    $gridcolumn.DisplayMemberBinding = $gridbinding 
    $gridview.AddChild($gridcolumn) 
} 
 
# Add GridView to ListView 
$listview.View = $gridview 
 
# Create notifyicon, and right-click -> Exit menu 
$notifyicon = New-Object System.Windows.Forms.NotifyIcon 
$notifyicon.Text = "Systeminformation"   
$notifyicon.Icon = $icon 
$notifyicon.Visible = $true 
 
$menuitem = New-Object System.Windows.Forms.MenuItem 
$menuitem.Text = "Start"  

$menuitem2 = New-Object System.Windows.Forms.MenuItem 
$menuitem2.Text = "Pause"   

$menuitem3 = New-Object System.Windows.Forms.MenuItem 
$menuitem3.Text = "Beenden"   

$contextmenu = New-Object System.Windows.Forms.ContextMenu 
$notifyicon.ContextMenu = $contextmenu 
$notifyicon.contextMenu.MenuItems.AddRange($menuitem) 
$notifyicon.contextMenu.MenuItems.AddRange($menuitem2) 
$notifyicon.contextMenu.MenuItems.AddRange($menuitem3) 
 
# Add a left click that makes the Window appear in the lower right part of the screen, above the notify icon. 
$notifyicon.add_Click({ 
    if ($_.Button -eq [Windows.Forms.MouseButtons]::Left) { 
            # reposition each time, in case the resolution or monitor changes 
	    $window.Left = $([System.Windows.SystemParameters]::WorkArea.Width-$window.Width) 
            $window.Top = $([System.Windows.SystemParameters]::WorkArea.Height-$window.Height) 
            $window.Show() 
            $window.Activate()
    	    RefreshData
    } 
}) 


#Start Script
$menuitem.add_Click({
param($minutes = 44640)

$myshell = New-Object -com "Wscript.Shell"  

for ($i = 0; $i -lt $minutes; $i++) {
  Start-Sleep -Seconds 60
  $myshell.sendkeys("LeftCtrl")  
}
})
 
# Close the window if it's double clicked   
$window.Add_MouseDoubleClick({ 
    RefreshData
}) 
 
#Close the window if it loses focus 
$window.Add_Deactivated({ 
    $window.Hide()
}) 
 
# When Exit is clicked, close everything and kill the PowerShell process 
$menuitem3.add_Click({ 
   $notifyicon.Visible = $false 
   $window.close() 
   Stop-Process $pid 
}) 
 
# Make PowerShell Disappear 
$windowcode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'   
$asyncwindow = Add-Type -MemberDefinition $windowcode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
$null = $asyncwindow::ShowWindowAsync((Get-Process -PID $pid).MainWindowHandle, 0) 
 
Force garbage collection just to start slightly lower RAM usage. 
[System.GC]::Collect() 
 
Create an application context for it to all run within. 
This helps with responsiveness, especially when clicking Exit. 
$appContext = New-Object System.Windows.Forms.ApplicationContext 
[void][System.Windows.Forms.Application]::Run($appContext)
Mitglied: 145916
Solution 145916 Sep 23, 2020 updated at 12:15:09 (UTC)
Goto Top
Add-Type -A System.Windows.Forms
Add-Type –memberDefinition '[DllImport("user32.dll")]public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);' -name W32 -namespace MyTools –passThru  
[MyTools.W32]::ShowWindow((Get-Process –id $pid).MainWindowHandle, 0)

$global:form = New-Object System.Windows.Forms.Form -Property @{
    Name = "form"  
    Text = "form"  
    Width = 1
    Height = 1
    Visible = $false
    ShowInTaskbar = $false
    WindowState= 'Minimized'  
}
$global:shell = New-Object -Com "Wscript.Shell"  
$global:timer = New-Object System.Windows.Forms.Timer -Property @{Interval = 60000}
$global:timer.add_tick({
    # action starts here
    $global:shell.SendKeys("^{ESC}")  
})

$global:cmenu = New-Object System.Windows.Forms.ContextMenu
$global:cmenu.MenuItems.Add('Exit',{  
    $global:timer.Stop()
    $global:timer.Dispose()
    $global:nicon.Dispose()
    $global:form.Close()
}) | out-null
$global:cmenu.MenuItems.Add('Pause',{  
    if ($this.Text -eq "Pause"){  
        $global:timer.Stop()
        $this.Text = "Start"  
    }else{
        $global:timer.Start()
        $this.Text = "Pause"  
    }
}) | out-null
$global:nicon = New-Object System.Windows.Forms.NotifyIcon -Property @{
    Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Windows\System32\SystemSettingsBroker.exe")  
    Visible = $true
    ContextMenu = $global:cmenu
}
$global:timer.Start()
$global:form.ShowDialog() | out-null
Member: chkdsk
chkdsk Sep 23, 2020 updated at 12:10:57 (UTC)
Goto Top
Zitat von @145916:

> Add-Type -A System.Windows.Forms
> Add-Type –memberDefinition '[DllImport("user32.dll")]public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);' -name W32 -namespace MyTools –passThru  
> [MyTools.W32]::ShowWindow((Get-Process –id $pid).MainWindowHandle, 0)
> 
> $global:form = New-Object System.Windows.Forms.Form -Property @{
>     Name = "form"  
>     Text = "form"  
>     Width = 1
>     Height = 1
>     Visible = $false
>     ShowInTaskbar = $false
>     WindowState= 'Minimized'  
> }
> $global:shell = New-Object -Com "Wscript.Shell"  
> $global:timer = New-Object System.Windows.Forms.Timer -Property @{Interval = 60000}
> $global:timer.add_tick({
>     # action starts here
>     $global:shell.SendKeys("^{ESC}")  
>     $global:nicon.ShowBalloonTip(1000,'MyAction',"My action fired",'Info')  
> })
> 
> $global:cmenu = New-Object System.Windows.Forms.ContextMenu
> $global:cmenu.MenuItems.Add('Exit',{  
>     $global:timer.Stop()
>     $global:timer.Dispose()
>     $global:nicon.Dispose()
>     $global:form.Close()
> }) | out-null
> $global:cmenu.MenuItems.Add('Pause',{  
>     if ($this.Text -eq "Pause"){  
>         $global:timer.Stop()
>         $this.Text = "Start"  
>     }else{
>         $global:timer.Start()
>         $this.Text = "Pause"  
>     }
> }) | out-null
> $global:nicon = New-Object System.Windows.Forms.NotifyIcon -Property @{
>     Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Windows\System32\SystemSettingsBroker.exe")  
>     Visible = $true
>     ContextMenu = $global:cmenu
> }
> $global:timer.Start()
> $global:form.ShowDialog() | out-null
> 

@145916 läuft bisher super face-smile ich habe jetzt nur mal die Esc Taste durch Print ausgetauscht, da einige Programme, welche im Vordergrund laufen durch Esc beendet werden. Ist aber den Programmen bei uns geschuldet.

Eine kleine Anmerkung habe ich noch. ShowBalloonTip zeigt nichts an

Edit: nach Zeile 42 folgendes einfügen

$global:nicon.Text = "gewünschter Text"   
Mitglied: 145916
145916 Sep 23, 2020 updated at 12:36:50 (UTC)
Goto Top
Zitat von @chkdsk:
ich habe jetzt nur mal die Esc Taste durch Print ausgetauscht, da einige Programme, welche im Vordergrund laufen durch Esc beendet werden. Ist aber den Programmen bei uns geschuldet.
Naja davon gehe ich aus das du den Code vorher durchliest und entsprechende Stellen anpasst face-wink.
Eine kleine Anmerkung habe ich noch. Das Tray Icon hat keinen Namen,
Dann gib ihm einen
https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.notifyi ...
Kannst du gleich beim Anlegen des Objektes abfackeln
$global:nicon = New-Object System.Windows.Forms.NotifyIcon -Property @{
    Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Windows\System32\SystemSettingsBroker.exe")
    Visible = $true
    ContextMenu = $global:cmenu
    Text = "MeinSuperDuperHyperLeckMichAATool"
}
Eine kleine Anmerkung habe ich noch. ShowBalloonTip zeigt nichts an
Macht Windows 10 nicht mehr, das zeigen nur noch ältere OS an, da unter Windows 10 MS auf die Toast-Notifications umgestellt hat.