Set tray icon to always show
Asked Answered
F

5

18

How I can I set a NotifyIcon to be always visible in the right tray: http://screensnapr.com/v/qKWHe2.png

because it shifts it over into the inactive icon window: http://screensnapr.com/v/jjtuK0.png

The issue is that the tray icon has a context menu that lets someone take a screen shot. So every time they take a screenshot, that inactive icon window is in the picture, blocking whatever is behind it like a photo bomber.

I know it is possible to do it through code because other applications such as comodo has done it without having me drag and drop the icon onto there. For pining a shortcut to the taskbar I learned that you set a shortcut in this folder:

C:\Users\Username\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar

Is there something similar for the tray? Or is there an option I can use code wise.

Freespoken answered 24/10, 2011 at 14:44 Comment(6)
Giving notification area icons "always visible" status is a user choice made through the taskbar properties dialog. I 'd be surprised if Windows exposed a programmatic interface to it as well.Hakodate
Yes, and normally I wouldn't try to force it onto the user. But it is vital that they make a screenshot that isnt covered up by the inactive icon window.Freespoken
Then they can go into "Customize..." and say that they want that icon to be visible all the time.Burnette
The inactive tray window stays open even after someone clicks on a menu item. I could risk glitching up the window by forcing it to hide but that is a bad hack to a more solid possible solution.Freespoken
I know this is old, but I came across this. The reason your Comodo can do it is likely something to do with the fact that it runs in ring0 rather than ring3. Don't quote me on that, though.Bossuet
Your software is not so special that it needs to force itself on the user. Consider instead helping the user understand how to enable it to show on it's own.Rubierubiginous
F
9

I was searching online and actually found this randomly.

Long story short, a combination of PowerShell (script provided) and GPO.

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

Long story, create a PowerShell script containing the following:

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

Save it as a ps1 file using the name of your choice.

Open up the Group Policy Management MMC. Select your chosen Group Policy Object, right click and select Edit. In the editor, navigate to User Configuration > Windows Settings > Scripts > Logon and click "Display Properties". Go to the PowerShell tab and click View Files.

Copy the script you just made into the Explorer window that just opened and then close out of the window.

In the login script properties window, add a new PowerShell script, in the script name, enter the name of the script you used (example: NotifyIcon.ps1), and then in the parameters, enter the program name (case sensitive!) followed by the setting to use:

0 = only show notifications 1 = hide icon and notifications 2 = show icon and notifications <--- The one you need

Example, if you need the RealVNC server to always appear, you would enter:

winvnc4.exe 2

as the paramenters

You can find out the name of the executable in a couple different ways, such as opening a Run dialogue box and typing msconfig and looking at the startup programs, manually navigating to the installation directory C:\Program Files{your program}, or trying to match the desired program by looking at the running processes in Task Manager. 9 times out of 10 this will result in success.

In order for this to work, the user must have previously run the application, and then properly logged out, so that explorer.exe gets a chance to write the updated notification area history to the Registry. On a subsequent login, the script should successfully locate the program in the history, and update its setting to always show.

You can also try running the script manually from a PowerShell prompt to debug, but you MUST kill explorer.exe (‘taskkill /f /im explorer.exe’) before running it, otherwise explorer won’t see your update, and will overwrite it when it does quit.

I take no credit for this process. I didn't write it, I just found it. Credit for the script goes to Micah Rowland. Credit for the GPO process goes to Geoff Kendal

Not enough reputation to link to original authors, with the exception of the one at the top.

Fiction answered 5/9, 2013 at 14:49 Comment(2)
This still seems to work on Windows 10. An easier way to restart explorer.exe as mentioned, it's necessary, just to go to Task Manager and find explorer.exe and right click, then choose restart. This can be done after running the powershell script.Gunslinger
madamission I don't think simply restarting explorer.exe will suffice - keep in mind, I answered this over 7 years ago, so changes to how Windows operates or my memory failing could prove this next statement wrong, but my understanding is that if you run the script while explorer is still running, when restarting explorer it will overwrite what you just tried to do. So the better process would be to kill explorer, run the script, start explorer. The reason why this works in a GPO logon script is because the script executes before the desktop session is established.Fiction
G
7

Not applicable by code, just instruct users to make it always show

http://blogs.msdn.com/b/oldnewthing/archive/2010/12/15/10105142.aspx

But you can manage to hack it by modifying a registry entry

HKEY_Current_User\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify

check this

Groundwork answered 24/10, 2011 at 14:50 Comment(9)
Again, that is not true because there are applications such as comodo that have put themselves in my immediate tray area without me specifically putting it there so you can not argue it is impossible. You do not know or condone it is another matter but do not make claims that are common misconceptionsFreespoken
if so then.. all software vendors will do it and enforcing user to see their tray icons!Groundwork
@Drake: I believe the misconception is yours here. Do you know every detail of the "decide which icons are shown" algorithm? If you do not, how can you be so sure that it is "always shown", especially when there is literature and common sense disagreeing with this?Hakodate
Because I'm looking right at it. Its there in my tray. Its been there since I installed in and it always sticks to the tray in every installation. Just because most people don't know the solution doesn't mean it is impossible.Freespoken
@Drake: I don't dispute that the icon is there. I 'm just saying that it being there might not be a constant, but rather something that happens to be true so far.Hakodate
It's just irritating to see so many people rise up to claim this is an impossible feat because they have been fed wrong information and take it as facts. I just want it in the tray by default, not by force. Just default.Freespoken
The default is "only show notifications". Explorer tries to guess whether the icon is indicating a notification, and sometimes this guess generates false positives, which is what you're seeing with those other programs.Asgard
Looks interesting, but I dont know VB well. Do you have any C# or registry only references?Freespoken
@Freespoken What is this "wrong information" which you refer to? Are you saying the article by Raymond Chen that Mohamed's links to has factual errors?Civilian
H
6

Giving notification area icons "always visible" status is a choice the user makes through the taskbar properties dialog. This is a design decision made by the appropriate Windows team in order to put this choice at the user's discretion.

For this reason, there is no programmatic interface that allows you to make an icon always visible. There's even no interface to ask if your icon is visible or not.

In your shoes I 'd just set up a hotkey that allows the user to take screenshots without getting involved with the icon at all (all screen capture programs do this).

If the user really likes to right click before taking a screenshot, they can always change their preference through taskbar properties as mentioned above.

Hakodate answered 24/10, 2011 at 14:52 Comment(4)
Its not a type of application that requires a global hotkey, it for when they want to voluntarily provide a screen shot with an error report for testing. Having to memorize or give up a specific hotkey combination for this is more intrusive than just having it show in the tray.Freespoken
@Drake: I 'm not saying force them to do this. I 'm saying "give them the option, and it will also solve your current problem for those who take it".Hakodate
They do have an option, if they don't want it in the active tray list. They can always drag it into the inactive one. But by default they should be able to see that the application is running and that it is ready to take a command any time they need it. I can already imagine people trying to run two instances of it because they cannot see that it is active, or end up forgetting its available to them.Freespoken
Even if it were possible to set the icon as always visible in code, more often than I care to count, I've seen icons that were set that way go to the inactive list, so the users will always have to watch for this anyway unless the program itself were to monitor the setting somehow (which, as someone pointed out, is also not possible in code) and change it back.Fleshpots
A
1

Using something like this script to enhance a software package so that with a simple checkbox the user can decide whether to pin the icon to the notification area (or not) without having to jump through the various hoops that Microsoft has chosen to put in the way seems like a fantastic idea in terms of accessibility.

Maybe if Microsoft had offered a right click pin/unpin option on the notification area icons (like the taskbar), or the ability for a program to easily offer such a feature we wouldn't be having this discussion.

Argilliferous answered 2/11, 2016 at 22:13 Comment(0)
C
0

Microsoft has explicitly taken the stance that this is a decision for the user and not one that can be made programmatically. Yes there are various utilities around that hack at the internals to achieve this, but there is no supported way to achieve what you desire.

Civilian answered 24/10, 2011 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.