Skip to content

Instantly share code, notes, and snippets.

@anaisbetts
Created September 15, 2015 04:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save anaisbetts/e90c7d89624d1b1adc72 to your computer and use it in GitHub Desktop.
Save anaisbetts/e90c7d89624d1b1adc72 to your computer and use it in GitHub Desktop.
Call secret Explorer API to change tray state
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
namespace SlackNotifier
{
public class TrayStateChanger
{
public List<NOTIFYITEM> GetTrayItems()
{
var instance = new TrayNotify();
try {
if (useLegacyInterface()) {
return getTrayItemsWin7(instance);
} else {
return getTrayItems(instance);
}
} finally {
Marshal.ReleaseComObject(instance);
}
}
static List<NOTIFYITEM> getTrayItems(TrayNotify instance)
{
var notifier = (ITrayNotify)instance;
var callback = new NotificationCb();
var handle = default(ulong);
notifier.RegisterCallback(callback, out handle);
notifier.UnregisterCallback(handle);
return callback.items;
}
static List<NOTIFYITEM> getTrayItemsWin7(TrayNotify instance)
{
var notifier = (ITrayNotifyWin7)instance;
var callback = new NotificationCb();
notifier.RegisterCallback(callback);
notifier.RegisterCallback(null);
return callback.items;
}
class NotificationCb : INotificationCb
{
public readonly List<NOTIFYITEM> items = new List<NOTIFYITEM>();
public void Notify([In] uint nEvent, [In] ref NOTIFYITEM notifyItem)
{
items.Add(notifyItem);
}
}
bool useLegacyInterface()
{
var ver = Environment.OSVersion.Version;
if (ver.Major < 6) return true;
if (ver.Major > 6) return false;
// Windows 6.2 and higher use new interface
return ver.Minor <= 1;
}
}
// The known values for NOTIFYITEM's dwPreference member.
public enum NOTIFYITEM_PREFERENCE {
// In Windows UI: "Only show notifications."
PREFERENCE_SHOW_WHEN_ACTIVE = 0,
// In Windows UI: "Hide icon and notifications."
PREFERENCE_SHOW_NEVER = 1,
// In Windows UI: "Show icon and notifications."
PREFERENCE_SHOW_ALWAYS = 2
};
// NOTIFYITEM describes an entry in Explorer's registry of status icons.
// Explorer keeps entries around for a process even after it exits.
public struct NOTIFYITEM {
[MarshalAs(UnmanagedType.LPWStr)]
string exe_name; // The file name of the creating executable.
[MarshalAs(UnmanagedType.LPWStr)]
string tip; // The last hover-text value associated with this status
// item.
IntPtr icon; // The icon associated with this status item.
IntPtr hwnd; // The HWND associated with the status item.
NOTIFYITEM_PREFERENCE preference; // Determines the behavior of the icon with respect to
// the taskbar
uint id; // The ID specified by the application. (hWnd, uID) is
// unique.
Guid guid; // The GUID specified by the application, alternative to
// uID.
};
[ComImport]
[Guid("D782CCBA-AFB0-43F1-94DB-FDA3779EACCB")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface INotificationCb
{
void Notify([In]uint nEvent, [In] ref NOTIFYITEM notifyItem);
}
[ComImport]
[Guid("FB852B2C-6BAD-4605-9551-F15F87830935")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ITrayNotifyWin7
{
void RegisterCallback([MarshalAs(UnmanagedType.Interface)]INotificationCb callback);
void SetPreference([In] ref NOTIFYITEM notifyItem);
void EnableAutoTray([In] bool enabled);
}
[ComImport]
[Guid("D133CE13-3537-48BA-93A7-AFCD5D2053B4")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ITrayNotify
{
void RegisterCallback([MarshalAs(UnmanagedType.Interface)]INotificationCb callback, [Out] out ulong handle);
void UnregisterCallback([In] ref ulong handle);
void SetPreference([In] ref NOTIFYITEM notifyItem);
void EnableAutoTray([In] bool enabled);
void DoAction([In] bool enabled);
}
[ComImport, Guid("25DEAD04-1EAC-4911-9E3A-AD0A4AB560FD")]
class TrayNotify { }
}
@alfein
Copy link

alfein commented Aug 22, 2017

Hi Paul,

Glad to have found this... Thank you.

A similar one from Squirrel does updates slightly differently https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/TrayHelper.cs

Can I use this version to force the icon visible or should I use the NOTIFYITEM_Writable from Squirrel?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment