You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程刷新Windows任务栏并更新托盘图标显示?

Got it, let's fix this. The issue with your current code is that you're using SHCNE_ASSOCCHANGED—that's for file association changes, not taskbar tray settings. To get the same instant refresh as the "Always show all icons and notifications" toggle, you need to use the right Windows API calls to notify the system about the setting change.

1. Use SHChangeNotify with the correct event ID

Instead of SHCNE_ASSOCCHANGED, use SHCNE_SETTINGSCHANGED (which signals system settings have been modified) along with SHCNF_FLUSH to ensure the notification is processed immediately. First, update your enums:

[Flags]
private enum HChangeNotifyEventID {
    SHCNE_ASSOCCHANGED = 0x08000000,
    SHCNE_SETTINGSCHANGED = 0x00000001 // Add this for setting changes
}

[Flags]
private enum HChangeNotifyFlags {
    SHCNF_IDLIST = 0x0000,
    SHCNF_FLUSH = 0x1000 // Add this to force immediate flush
}

Then modify your changeTaskBar function to use the new parameters:

public static void changeTaskBar() { 
    string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"; 
    string setting = "EnableAutoTray"; 
    int setTo = 1; 
    using (RegistryKey regKey = Registry.CurrentUser.OpenSubKey(subKey, true)) { 
        tryOpenCreateKey(regKey, setting, setTo, RegistryValueKind.DWord, subKey); 
        // Notify system of taskbar setting change
        SHChangeNotify(HChangeNotifyEventID.SHCNE_SETTINGSCHANGED, HChangeNotifyFlags.SHCNF_FLUSH | HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
    } 
}

2. Broadcast WM_SETTINGCHANGE to all windows

Another reliable method (exactly what the Windows Settings UI uses) is sending the WM_SETTINGCHANGE message to all top-level windows, specifying we're updating taskbar settings. Add this API declaration first:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool SendMessageTimeout(
    IntPtr hWnd,
    uint Msg,
    UIntPtr wParam,
    string lParam,
    SendMessageTimeoutFlags fuFlags,
    uint uTimeout,
    out UIntPtr lpdwResult);

private const uint WM_SETTINGCHANGE = 0x001A;

Then add this call right after modifying the registry:

UIntPtr result;
// Broadcast taskbar setting change to all windows
SendMessageTimeout(
    (IntPtr)0xFFFF, // HWND_BROADCAST to target all top-level windows
    WM_SETTINGCHANGE,
    UIntPtr.Zero,
    "Taskbar", // Explicitly target taskbar-related settings
    SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
    5000,
    out result);

This will trigger an immediate refresh of the taskbar tray icons without restarting Explorer.

For unhiding files/folders

To refresh hidden files/folders after modifying their attributes, use SHChangeNotify with the SHCNE_UPDATEDIR event to notify the system a directory's properties have changed:

[Flags]
private enum HChangeNotifyEventID {
    // ... existing values
    SHCNE_UPDATEDIR = 0x00000002 // Add this for directory updates
}

// Call this after modifying file/folder attributes
// Replace folderPathPtr with the PIDL of the target directory (use SHParseDisplayName to get it)
SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEDIR, HChangeNotifyFlags.SHCNF_IDLIST, (IntPtr)folderPathPtr, IntPtr.Zero);

For a system-wide refresh of file visibility settings, you can also broadcast WM_SETTINGCHANGE with "Shell" as the parameter instead of "Taskbar".

Why your original code didn't work

SHCNE_ASSOCCHANGED is designed to trigger refreshes for file type association changes (like updating which app opens .txt files), so it doesn't affect taskbar tray icon settings. The system listens for SHCNE_SETTINGSCHANGED or WM_SETTINGCHANGE for UI-related setting updates like tray icon visibility.

内容的提问来源于stack exchange,提问作者MikeS159

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:20:11