ElektroStudios
ElektroStudios

Reputation: 20464

How to refresh explorer after a registry change

I'm trying to refresh the system (Windows 8) after changing a value in the registry, this value affects the explorer settings, Is the value to show/hide the checkboxes:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
    RegEdit.Set_Value("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", _
                      "AutoCheckSelect", "1", Microsoft.Win32.RegistryValueKind.DWord)
End Sub

And to refresh the system I use this:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero)
End Sub

I've tried a lot of flag combinations.

The problem is the explorer windows refreshes but the checkboxes does not appear (or does not been removed), I still need to press F5 inside each explorer window for a full change-refresh.

This is the full code:

Imports System.Runtime.InteropServices

Public Class Form1

<DllImport("shell32.dll")> _
Shared Sub SHChangeNotify( _
ByVal wEventID As HChangeNotifyEventID, _
ByVal uFlags As HChangeNotifyFlags, _
ByVal dwItem1 As IntPtr, _
ByVal dwItem2 As IntPtr)
End Sub

<Flags()> _
Public Enum HChangeNotifyFlags
    ' <summary>
    ' The <i>dwItem1</i> and <i>dwItem2</i> parameters are DWORD values.
    ' </summary>
    SHCNF_DWORD = &H3
    ' <summary>
    ' <i>dwItem1</i> and <i>dwItem2</i> are the addresses of ITEMIDLIST structures that
    ' represent the item(s) affected by the change.
    ' Each ITEMIDLIST must be relative to the desktop folder.
    ' </summary>
    SHCNF_IDLIST = &H0
    ' <summary>
    ' <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of
    ' maximum length MAX_PATH that contain the full path names
    ' of the items affected by the change.
    ' </summary>
    SHCNF_PATHA = &H1
    ' <summary>
    ' <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of
    ' maximum length MAX_PATH that contain the full path names
    ' of the items affected by the change.
    ' </summary>
    SHCNF_PATHW = &H5
    ' <summary>
    ' <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that
    ' represent the friendly names of the printer(s) affected by the change.
    ' </summary>
    SHCNF_PRINTERA = &H2
    ' <summary>
    ' <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that
    ' represent the friendly names of the printer(s) affected by the change.
    ' </summary>
    SHCNF_PRINTERW = &H6
    ' <summary>
    ' The function should not return until the notification
    ' has been delivered to all affected components.
    ' As this flag modifies other data-type flags it cannot by used by itself.
    ' </summary>
    SHCNF_FLUSH = &H1000
    ' <summary>
    ' The function should begin delivering notifications to all affected components
    ' but should return as soon as the notification process has begun.
    ' As this flag modifies other data-type flags it cannot by used by itself.
    ' </summary>
    SHCNF_FLUSHNOWAIT = &H2000
End Enum


<Flags()> _
Public Enum HChangeNotifyEventID
    ' <summary>
    ' All events have occurred.
    ' </summary>
    SHCNE_ALLEVENTS = &H7FFFFFFF

    ' <summary>
    ' A file type association has changed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/>
    ' must be specified in the <i>uFlags</i> parameter.
    ' <i>dwItem1</i> and <i>dwItem2</i> are not used and must be <see langword="null"/>.
    ' </summary>
    SHCNE_ASSOCCHANGED = &H8000000

    ' <summary>
    ' The attributes of an item or folder have changed.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the item or folder that has changed.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_ATTRIBUTES = &H800

    ' <summary>
    ' A nonfolder item has been created.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the item that was created.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_CREATE = &H2

    ' <summary>
    ' A nonfolder item has been deleted.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the item that was deleted.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_DELETE = &H4

    ' <summary>
    ' A drive has been added.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the root of the drive that was added.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_DRIVEADD = &H100

    ' <summary>
    ' A drive has been added and the Shell should create a new window for the drive.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the root of the drive that was added.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_DRIVEADDGUI = &H10000

    ' <summary>
    ' A drive has been removed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the root of the drive that was removed.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_DRIVEREMOVED = &H80

    ' <summary>
    ' Not currently used.
    ' </summary>
    ' SHCNE_EXTENDED_EVENT = &H4000000

    ' <summary>
    ' The amount of free space on a drive has changed.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the root of the drive on which the free space changed.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_FREESPACE = &H40000

    ' <summary>
    ' Storage media has been inserted into a drive.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the root of the drive that contains the new media.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_MEDIAINSERTED = &H20

    ' <summary>
    ' Storage media has been removed from a drive.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the root of the drive from which the media was removed.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_MEDIAREMOVED = &H40

    ' <summary>
    ' A folder has been created. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/>
    ' or <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the folder that was created.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_MKDIR = &H8

    ' <summary>
    ' A folder on the local computer is being shared via the network.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the folder that is being shared.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_NETSHARE = &H200

    ' <summary>
    ' A folder on the local computer is no longer being shared via the network.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the folder that is no longer being shared.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_NETUNSHARE = &H400

    ' <summary>
    ' The name of a folder has changed.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the previous pointer to an item identifier list (PIDL) or name of the folder.
    ' <i>dwItem2</i> contains the new PIDL or name of the folder.
    ' </summary>
    SHCNE_RENAMEFOLDER = &H20000

    ' <summary>
    ' The name of a nonfolder item has changed.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the previous PIDL or name of the item.
    ' <i>dwItem2</i> contains the new PIDL or name of the item.
    ' </summary>
    SHCNE_RENAMEITEM = &H1

    ' <summary>
    ' A folder has been removed.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the folder that was removed.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_RMDIR = &H10

    ' <summary>
    ' The computer has disconnected from a server.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the server from which the computer was disconnected.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' </summary>
    SHCNE_SERVERDISCONNECT = &H4000

    ' <summary>
    ' The contents of an existing folder have changed
    ' but the folder still exists and has not been renamed.
    ' <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
    ' <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
    ' <i>dwItem1</i> contains the folder that has changed.
    ' <i>dwItem2</i> is not used and should be <see langword="null"/>.
    ' If a folder has been created deleted or renamed use SHCNE_MKDIR SHCNE_RMDIR or
    ' SHCNE_RENAMEFOLDER respectively instead.
    ' </summary>
    SHCNE_UPDATEDIR = &H1000

    ' <summary>
    ' An image in the system image list has changed.
    ' <see cref="HChangeNotifyFlags.SHCNF_DWORD"/> must be specified in <i>uFlags</i>.
    ' </summary>
    SHCNE_UPDATEIMAGE = &H8000
End Enum


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
    RegEdit.Set_Value("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", _
                      "AutoCheckSelect", "0", Microsoft.Win32.RegistryValueKind.DWord)
End Sub


Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero)
End Sub

End Class

Upvotes: 3

Views: 5500

Answers (3)

mcw
mcw

Reputation: 3596

I was trying to do something similar - update a registry setting for the start menu and then immediately have the start menu reflect the changes.

The solution from this MSDN question worked for me perfectly.

You could try broadcasting a WM_SETTINGCHANGE message. For example:

class Program
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult);

    private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
    private const int WM_SETTINGCHANGE = 0x1a;
    private const int SMTO_ABORTIFHUNG = 0x0002;

    static void Main(string[] args)
    {
        SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, null, SMTO_ABORTIFHUNG, 100, IntPtr.Zero);
    }
}

Upvotes: 2

Saby
Saby

Reputation: 718

Can you try using SHChangeNotify() with SHCNE_ALLEVENTS events, it may work. It may refresh the explorer after that. Otherwise you have to think some other tricks

Upvotes: 3

Pragy Agarwal
Pragy Agarwal

Reputation: 579

you could try some cheap tricks.

- Send a "F5" keystroke to the explorer window so you don't have to do it manually.
- kill explorer.exe, and relaunch it.

Take a look at this. How to refresh Windows Explorer

Upvotes: 1

Related Questions