window 系统托盘不自动隐藏

https://hianz.wordpress.com/2013/09/03/new-windows-tray-notification-manager-is-here/

1.PowerShell脚本实现原文链接

例子:将下面代码复制到一个脚本中去例如123.ps1,

执行时输入  ./123.ps1 myapp.exe < 显示参数>(0=不活动时隐藏 1=总是隐藏 2=总是显示)

执行完成后需要自己重启Explorer.exe,才能得到效果。

通过这种方法会存在一种问题是需要重启Explorer.exe,所以界面会闪烁一下。

param(
    [Parameter(Mandatory=$true,HelpMessage='The name of the program')][string]$ProgramName,
    [Parameter(Mandatory=$true,HelpMessage='The setting (2 = show icon and notifications 1 = hide icon and notifications, 0 = only show notifications')]
        [ValidateScript({if ($_ -lt 0 -or $_ -gt 2) { throw 'Invalid setting' } return $true})]
        [Int16]$Setting
    )

$encText = New-Object System.Text.UTF8Encoding
[byte[]] $bytRegKey = @()
$strRegKey = ""
$bytRegKey = $(Get-ItemProperty $(Get-Item 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify').PSPath).IconStreams
for($x=0; $x -le $bytRegKey.Count; $x++)
{
    $tempString = [Convert]::ToString($bytRegKey[$x], 16)
    switch($tempString.Length)
    {
        0 {$strRegKey += "00"}
        1 {$strRegKey += "0" + $tempString}
        2 {$strRegKey += $tempString}
    }
}
[byte[]] $bytTempAppPath = @()
$bytTempAppPath = $encText.GetBytes($ProgramName)
[byte[]] $bytAppPath = @()
$strAppPath = ""

Function Rot13($byteToRot)
{
    if($byteToRot -gt 64 -and $byteToRot -lt 91)
    {
        $bytRot = $($($byteToRot - 64 + 13) % 26 + 64)
        return $bytRot
    }
    elseif($byteToRot -gt 96 -and $byteToRot -lt 123)
    {
        $bytRot = $($($byteToRot - 96 + 13) % 26 + 96)
        return $bytRot
    }
    else
    {
        return $byteToRot
    }
}

for($x = 0; $x -lt $bytTempAppPath.Count * 2; $x++)
{
    If($x % 2 -eq 0)
    {
        $curbyte = $bytTempAppPath[$([Int]($x / 2))]
            $bytAppPath += Rot13($curbyte)

    }
    Else
    {
        $bytAppPath += 0
    }
}

for($x=0; $x -lt $bytAppPath.Count; $x++)
{
    $tempString = [Convert]::ToString($bytAppPath[$x], 16)
    switch($tempString.Length)
    {
        0 {$strAppPath += "00"}
        1 {$strAppPath += "0" + $tempString}
        2 {$strAppPath += $tempString}
    }
}
if(-not $strRegKey.Contains($strAppPath))
{
    Write-Host Program not found. Programs are case sensitive.
    break
}

[byte[]] $header = @()
$items = @{}
for($x=0; $x -lt 20; $x++)
{
    $header += $bytRegKey[$x]
}

for($x=0; $x -lt $(($bytRegKey.Count-20)/1640); $x++)
{
    [byte[]] $item=@()
    $startingByte = 20 + ($x*1640)
    $item += $bytRegKey[$($startingByte)..$($startingByte+1639)]
    $items.Add($startingByte.ToString(), $item)
}

foreach($key in $items.Keys)
{
$item = $items[$key]
    $strItem = ""
    $tempString = ""

    for($x=0; $x -le $item.Count; $x++)
    {
        $tempString = [Convert]::ToString($item[$x], 16)
        switch($tempString.Length)
        {
            0 {$strItem += "00"}
            1 {$strItem += "0" + $tempString}
            2 {$strItem += $tempString}
        }
    }
    if($strItem.Contains($strAppPath))
    {
        Write-Host Item Found with $ProgramName in item starting with byte $key
            $bytRegKey[$([Convert]::ToInt32($key)+528)] = $setting
            Set-ItemProperty $($(Get-Item 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify').PSPath) -name IconStreams -value $bytRegKey
    }
}

 

2.C#代码实现原文链接

这种方法和上面的powershell一样,会导致界面闪烁。

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Collections;
using System.Diagnostics;
class Program
    {
        static void Main(string[] args)
        {
            Program p1 = new Program();
 
            string prName = null;
            RegistryKey myKey = Registry.CurrentUser.OpenSubKey("Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotify", true);
            byte[] all = (byte[])myKey.GetValue("IconStreams");
            byte[] allwithoutheader = new byte[all.Length - 20];
            byte[] header = new byte[20];
 
            //Parse Header
            //------------------------
            for (int i = 0; i < all.Length; i++)
            {
                if (i <= 19)
                {
                    header[i] = all[i];
                }
                else
                {
                    allwithoutheader[i - 20] = all[i];
                }
            }
            //------------------------
            ArrayList blocklist = p1.storeBlocks(allwithoutheader);
            Console.WriteLine("Name(or part) of program:");
            prName = Console.ReadLine();
 
            string alldataString = null;
            bool found = false;
            int value = 0;
            int blocknumber = 0;
 
            for (int i = 0; i < blocklist.Count; i++)
            {
                for (int j = 0; j < 1639; j++)
                {
                    if (j < 528)
                    {
                        alldataString += System.Convert.ToChar(((List)(blocklist[i]))[j]);
                        if (j == 526)
                        {
                            string transformed = p1.Transform(alldataString);
                            string trimmed = System.Text.RegularExpressions.Regex.Replace(transformed, "\0+", "");
                            if (trimmed.Contains(prName))
                            {
                                alldataString = null;
                                Console.WriteLine("\n===================\n"+prName+" block found!"); //Block in ArrayList
                                Console.WriteLine("current setting --> " + ((List)(blocklist[i]))[528]);
                                Console.WriteLine("===================\nsettings: \n2 = show icon and notifications, \n1 = hide icon and notifications, \n0 = only show notifications\n===================");
                                blocknumber = i;
                                found = true;
                                break;
                            }
                        }
                    }
                }
            }
 
            if (found == false)
            {
                Console.WriteLine("Nothing found");
                Console.ReadLine();
                Environment.Exit(1);
            }
 
            Console.WriteLine("new setting:");
            value = Convert.ToInt32(Console.ReadLine());
            ((List)(blocklist[blocknumber]))[528] = (byte)(value);
 
            byte[] alloriginal = p1.getOriginalFormat(blocklist, allwithoutheader.Length);
            byte[] combined = p1.Combine(header, alloriginal);
 
            myKey.SetValue("IconStreams", combined);
            Console.WriteLine("Successfully wrote to Registry, please restart explorer.exe");
 
 
            Process[] pp = Process.GetProcessesByName("explorer");
            foreach (Process p in pp)
            {
                
                p.Kill();
            }
            Process.Start("explorer.exe");
        }
 
        private byte[] Combine(byte[] first, byte[] second)
        {
            byte[] ret = new byte[first.Length + second.Length];
            Buffer.BlockCopy(first, 0, ret, 0, first.Length);
            Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
            return ret;
        }
 
        private ArrayList storeBlocks(byte[] all)
        {
            ArrayList main = new ArrayList();
            List bytelist = new List();
 
            int help = 1639;
            int j = 0;
            for (int i = 0; i < all.Length; i++)
            {
                bytelist.Add(all[i]);
                if (i == help)
                {
                    main.Add(bytelist);
                    bytelist = new List();
                    help = help + 1640;
                }
            }
            return main;
        }
 
        private byte[] getOriginalFormat(ArrayList list, int bufferSize)
        {
            int help = 0;
            byte[] original = new byte[bufferSize];
            for (int i = 0; i < list.Count; i++)
            {
                for (int j = 0; j < (((List)(list[i])).Count); j++)
                {
 
                    original[help] = (((List)(list[i]))[j]);
                    help++;
                }
            }
            return original;
        }
        private string Transform(string value)
        {
            char[] array = value.ToCharArray();
            for (int i = 0; i < array.Length; i++)
            {
                int number = (int)array[i];
 
                if (number >= 'a' && number <= 'z')
                {
                    if (number > 'm')
                    {
                        number -= 13;
                    }
                    else
                    {
                        number += 13;
                    }
                }
                else if (number >= 'A' && number <= 'Z')
                {
                    if (number > 'M')
                    {
                        number -= 13;
                    }
                    else
                    {
                        number += 13;
                    }
                }
                array[i] = (char)number;
            }
            return new string(array);
        }
    }

 

3.利用windowAPI实现

windows是有api去控制托盘显示和隐藏的,只不过它未开放给我们,但是有人找到怎么调用它的方法了。原文链接

具体在win7上工作的很好,win8没测试,但是win10 1809没有反应。

你可能感兴趣的:(学习过程)