使特定的托盘图标始终显示在 Windows 7 中的所有配置文件中

使特定的托盘图标始终显示在 Windows 7 中的所有配置文件中

我正在设置一台 Windows 7 机器,它将放在公共场所,供许多人共享。我已向所有用户的开始菜单添加了一个快捷方式,用于运行位于系统托盘中的程序。我希望此程序的托盘图标始终默认可见,无论谁登录。如果用户确实想要,他们可以在其个人资料上将其关闭,但我需要至少在开始时将其设置为始终可见。我该怎么做?

我宁愿不显示所有图标,部分原因与隐藏它们的原因相同:我不想太杂乱。另外,由于这是一台公用计算机,因此正在运行另一个名为 DeepFreeze 的程序,它也有一个系统托盘图标,我不希望该图标一直显示。

答案1

简而言之,目前你不能这样做。

没有组策略或首选项来设置此功能,并且其跟踪方式使其特定于当前用户和系统,从而使“设置”在不同实例之间差异很大。

如果您想查看的话,它们存储在这里(在注册表中)HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify:。

这里

应用程序无法通过编程始终在系统托盘上显示自己,无论是在首次安装时还是在运行时的任何时间。这是我们在 Windows 7 中做出的几项改变之一,旨在打造一个更干净、更安静的桌面,用户可以控制使用他们最喜欢的应用程序和图标自定义顶层。

我们不允许通过编程方式提升(除了临时提升或显示通知外),从而让用户控制通知区域。假设机器足够安静,当您首次使用 Shell_NotifyIcon(NIM_ADD, ...) 添加图标时,图标将在任务栏上显示 45 秒,然后移至溢出。如果用户提升图标,图标将始终显示在任务栏上。如果用户将其降级,图标将永远不会显示在任务栏上。任何提升都需要用户发起。我们在 Windows 7 中通过拖放和通知区域图标控制面板使此操作变得更加容易,我们在可用性研究和基于 beta 反馈中看到,用户可以轻松发现如何自定义通知行为,并会提升他们想要快速访问的图标。

最简单的办法是向所有用户显示所有通知区域图标。这可以通过添加(简单的)注册表项来实现:

创建HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer一个名为的新 DWORD 值EnableAutoTray并将其设置为0关闭通知区域的“自动隐藏”功能。

如果您只希望它对某些用户/组发生,您也可以通过一些 OU 配置和脚本在 HKCU 上下文中使用它。

这里了解更多信息。

答案2

我在网上搜索并偶然发现了这个。

长话短说,PowerShell(提供脚本)和 GPO 的组合。

http://4sysops.com/archives/forcing-notification-area-icons-to-always-show-in-windows-7-or-windows-8/

长话短说,创建一个包含以下内容的 PowerShell 脚本:

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
    }
}

使用您选择的名称将其保存为 ps1 文件。

打开组策略管理 MMC。选择您选择的组策略对象,右键单击并选择编辑。在编辑器中,导航到用户配置 > Windows 设置 > 脚本 > 登录,然后单击“显示属性”。转到 PowerShell 选项卡并单击查看文件。

将刚刚制作的脚本复制到刚刚打开的资源管理器窗口中,然后关闭窗口。

在登录脚本属性窗口中,添加一个新的 PowerShell 脚本,在脚本名称中输入您使用的脚本名称(例如:NotifyIcon.ps1),然后在参数中输入程序名称(区分大小写!)后跟要使用的设置:

0 = 仅显示通知 1 = 隐藏图标和通知 2 = 显示图标和通知 <--- 您需要的那个

例如,如果您需要 RealVNC 服务器始终出现,您可以输入:

winvnc4.exe 2

作为参数

您可以通过几种不同的方式找出可执行文件的名称,例如打开“运行”对话框并键入msconfig并查看启动程序、手动导航到安装目录C:\Program Files\{your program},或者尝试通过查看任务管理器中正在运行的进程来匹配所需的程序。十有八九,这种方法都会成功。

为了实现此功能,用户必须先运行该应用程序,然后正确注销,这样 explorer.exe 才有机会将更新的通知区域历史记录写入注册表。在后续登录时,脚本应成功在历史记录中找到该程序,并将其设置更新为始终显示。

您也可以尝试从 PowerShell 提示符手动运行脚本进行调试,但在运行它之前必须先终止 explorer.exe ('taskkill /f /im explorer.exe'),否则 explorer 将看不到您的更新,并且在退出时会覆盖它。

我对这个过程不负任何责任。我没有写它,我只是找到了它。剧本的功劳归于米卡·罗兰. GPO 流程的功劳归功于杰夫肯德尔

答案3

我不知道您是否可以设置图标的缓存顺序,因为如果添加新程序它可能会不断变化,但您可以将通知设置为“始终在任务栏上显示所有图标和通知”。

要将其设置为默认值,请转到以下注册表项:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer

添加DWORD值“ EnableAutoTray”,双击,将十六进制值设置为“ 0”。

我测试了一下并且成功了。

有趣的是:我首先尝试将其添加到这个键:

HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer

我一直以为这是新用户的默认注册表,但它不起作用。所以我去查找并找到了这篇有趣的文章,打破了我对 .DEFAULT 键的长期想法。

.Default 用户不是默认用户

补充:我能说的最好的是注册表项在这里如果您尝试像打开“ Control Panel\All Control Panel Items\Notification Area Icons”一样设置一个图标:

HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify

如果你看一下它们,你会发现它们不太容易理解,所以我不确定你能如何很好地编辑它们。

我建议您考虑创建一个新用户及其配置文件,将该图标的“控制面板\所有控制面板项\通知区域图标”(至少)设置为“显示图标和通知”。

然后重新启动以释放配置文件,并以管理员身份登录。将该配置文件复制到“ ”配置文件。您可以使用 Explorer 手动执行此操作,也可以使用我们在“ ”C:\Users\Default中曾经执行过的方式执行此操作。它将呈灰色,但您可以使用Control Panel\All Control Panel Items\SystemAdvanced System Settings>Advanced>User Profiles>Copy toWindows 启用程序来解决这个问题。

答案4

#this will grab all the SID on current user and apply across all.
Function Enable-Notifications
{
    Param
        (
        [parameter(Mandatory=$false)][string]$cpuName
        )


        if (Test-Connection $cpuName -Quiet)    
        {
Try
                {
                    $serviceName = "Remote Registry"  
                    Get-Service -ComputerName $cpuName -Name $serviceName | Start-Service
                }
                Catch
                {
                    Write-Host "Possible Error restarting $serviceName on $cpuName" -ForegroundColor Red
                }
                Try
                {
                    $root = [Microsoft.Win32.RegistryHive]::Users
                    $regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($root, $cpuName)

                    $users = $regKey.GetSubKeyNames() | where { $_.Length -gt 10 -and $_.EndsWith("_Classes") -eq $false }
                    foreach ($usersid in $users)
                    {
                        $key = "$usersid\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer"
                        $regKey = $regKey.OpenSubKey($key, $true)
                        $regKey.SetValue("EnableAutoTray", "0", 'DWORD')
                    }
                    $ActiveUser = ([Environment]::UserDomainName + "\" + [Environment]::UserName)
                    $Time = Get-Date -format "MM-dd-yyyy @ HH:mm"
                    $WriteOut = "$ActiveUser enabled Notifcations on $cpuName at $Time"
                    $WriteOut >> "c:\scripts\Notification-Update-Enable.csv"
                    Write-Host "Enable Notifications on $cpuName" -ForegroundColor Green
                }       
                Catch
                {
                    $errormsg = $cpuName + ” is down/not responding.”
                    Write-Host $errorMsg -ForegroundColor Red
                    $errormsg >> "c:\scripts\Notification-Update-Enable_Off.csv"
                }
}
        else
        {
            Write-Host "$cpuName is Offline. Try again later." -ForegroundColor Red
            $errormsg >> "c:\scripts\Notification-Update-Enable_Off.csv"
        }
}

相关内容