Как заставить Windows Explorer автоматически обновляться после изменения тега в файле desktop.ini

Я меняю тег папки, создавая или изменяя файл desktop.ini в Windows 10.

Без уведомления ОС о том, что ей необходимо каким-либо образом обновиться, тегу требуется неопределенное количество времени, чтобы отразить изменение в проводнике Windows.

Я пытаюсь использовать функцию Windows API, чтобы уведомить ОС об изменении атрибута в папке, но это не приводит к обновлению проводника Windows. Были опробованы следующие комбинации:

        [DllImport("shell32.dll")]
    static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
                               HChangeNotifyFlags uFlags,
                               IntPtr dwItem1,
                               IntPtr dwItem2);


    public static void Refresh1()
    {
        var ptr = Marshal.StringToHGlobalUni(@"C:\tmp\test");
        SHChangeNotify(HChangeNotifyEventID.SHCNE_ATTRIBUTES, HChangeNotifyFlags.SHCNF_PATHW, ptr, IntPtr.Zero);
        Marshal.FreeHGlobal(ptr);   
    }

    public static void Refresh2()
    {
        var ptr = Marshal.StringToHGlobalUni(@"C:\tmp\test\desktop.ini");
        SHChangeNotify(HChangeNotifyEventID.SHCNE_DELETE, HChangeNotifyFlags.SHCNF_PATHW, ptr, IntPtr.Zero);
        Marshal.FreeHGlobal(ptr);
    }

    public static void Refresh3()
    {
        var ptr = Marshal.StringToHGlobalUni(@"C:\tmp\test\desktop.ini");
        SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM, HChangeNotifyFlags.SHCNF_PATHW, ptr, IntPtr.Zero);
        Marshal.FreeHGlobal(ptr);
    }

    public static void Refresh4()
    {
        var ptr = Marshal.StringToHGlobalUni(@"C:\tmp\test");
        SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM, HChangeNotifyFlags.SHCNF_PATHW, ptr, IntPtr.Zero);
        Marshal.FreeHGlobal(ptr);
    }

    public static void Refresh5()
    {
        var ptr = Marshal.StringToHGlobalUni(@"C:\tmp\test");
        SHChangeNotify(HChangeNotifyEventID.SHCNE_RENAMEFOLDER, HChangeNotifyFlags.SHCNF_PATHW, ptr, IntPtr.Zero);
        Marshal.FreeHGlobal(ptr);
    }

    public static void Refresh6()
    {
        var ptr = Marshal.StringToHGlobalUni(@"C:\tmp\test");
        SHChangeNotify(HChangeNotifyEventID.SHCNE_RENAMEFOLDER, HChangeNotifyFlags.SHCNF_PATHW, ptr, ptr);
        Marshal.FreeHGlobal(ptr);
    }

Основываясь на комментариях ниже, я попробовал другой подход к маршалингу и множеству перестановок...

    [DllImport("shell32.dll")]
    static extern void SHChangeNotify(HChangeNotifyEventID wEventId, HChangeNotifyFlags uFlags, [MarshalAs(UnmanagedType.LPWStr)] string dwItem1, [MarshalAs(UnmanagedType.LPWStr)] string dwItem2);

    public static void Refresh1()
    {
        var str = @"C:\tmp\test";
        SHChangeNotify(HChangeNotifyEventID.SHCNE_ATTRIBUTES, HChangeNotifyFlags.SHCNF_PATHW, str, str);
    }


    public static void Refresh2()
    {
        var str = @"C:\tmp\test";
        SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM, HChangeNotifyFlags.SHCNF_PATHW, str, "");
    }


    public static void Refresh3()
    {
        var str = @"C:\tmp\test";
        SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM, HChangeNotifyFlags.SHCNF_PATHW, str, str);
    }

    public static void Refresh4()
    {
        var str = @"C:\tmp\test";
        SHChangeNotify(HChangeNotifyEventID.SHCNE_ATTRIBUTES, HChangeNotifyFlags.SHCNF_PATHW, str, "");
    }

Я также пробовал HChangeNotifyEventID.SHCNE_UPDATEDIR в качестве опции для первого параметра, но это также не помогло обновить проводник Windows.

Как изменить тег папки таким образом, чтобы он автоматически обновлялся в проводнике Windows?

  1. Это способ изменить код выше, чтобы сделать это?
  2. Является ли их другой функцией Windows API, которую я должен вызывать для обновления Windows Explorer после изменения desktop.ini (хотя название этого подразумевает, что он должен выполнять эту работу...)?
  3. Должен ли я использовать определенный вызов API Windows только для того, чтобы напрямую изменить тег, который имеет встроенное уведомление для ОС?

person Sam    schedule 14.04.2021    source источник
comment
Вы упорядочиваете строку Unicode, так почему же вы используете SHCNF_PATHA (0x0001) вместо SHCNF_PATHW (0x0005)?   -  person Remy Lebeau    schedule 15.04.2021
comment
@RemyLebeau спасибо, я не был уверен в разнице между этими двумя вариантами пути, но вы уточнили для меня. Я изменил это в своем вопросе выше И в коде, но он по-прежнему не обновляет проводник Windows.   -  person Sam    schedule 15.04.2021
comment
Согласно этот пост следует использовать SHGetSetFolderCustomSettings() вместо прямого изменения desktop.ini: Эта функция... отправляет все необходимые уведомления сама по себе. Хотя я не думаю, что это поддерживает теги.   -  person Remy Lebeau    schedule 15.04.2021
comment
Согласно этому сообщению, попробуйте вместо этого отправить SHCNE_DELETE, указав путь к самому файлу desktop.ini.   -  person Remy Lebeau    schedule 15.04.2021
comment
Или это сообщение, которое предлагает отправить SHCNE_RENAMEFOLDER с обоими путями, установленными на один и тот же путь к папке   -  person Remy Lebeau    schedule 15.04.2021
comment
Или это сообщение, в котором предлагается отправить SHCNE_UPDATEITEM с путем к папке.   -  person Remy Lebeau    schedule 15.04.2021
comment
Вы можете определить функцию следующим образом, это проще, без распределения: void SHChangeNotify(SHCNE wEventId, SHCNF uFlags, [MarshalAs(UnmanagedType.LPWStr)] string dwItem1, [MarshalAs(UnmanagedType.LPWStr)] string dwItem2) Я бы использовал SHCNE_UPDATEITEM и SHCNF_PATHW в файле desktop.ini   -  person Simon Mourier    schedule 15.04.2021
comment
@RemyLebeau Я пытался использовать SHCNE_DELETE, но это не сработало - результаты указаны в отредактированном вопросе.   -  person Sam    schedule 15.04.2021
comment
@SimonMourier попробовал SHCNE_UPDATEITEM и SHCNF_PATHW в файле desktop.ini, но это не привело к обновлению - добавлено к моему вопросу о попытках   -  person Sam    schedule 15.04.2021
comment
@RemyLebeau SHCNE_UPDATEITEM с путем к папке также не требует обновления   -  person Sam    schedule 15.04.2021
comment
@RemyLebeau SHCNE_RENAMEFOLDER также не форсировал обновление. Вопрос обновлен.   -  person Sam    schedule 15.04.2021
comment
@Sam для SHCNE_RENAMEFOLDER, попробуйте указать путь к папке для обоих входных путей, как я упоминал ранее: SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_PATHW, ptr, ptr) А вы пытались удалить Marshal.StringToHGlobalUni(), как предложил Саймон?   -  person Remy Lebeau    schedule 15.04.2021
comment
@RemyLebeau Я только что попытался использовать оба пути ввода, но тоже безуспешно. Теперь придется удалить Маршаллинг ...   -  person Sam    schedule 15.04.2021
comment
@ Сэм, ты проводил какие-нибудь тесты, используя SHCNF_IDLIST вместо SHCNF_PATHW? Вы можете использовать SHParseDisplayName() или аналогичную функцию для преобразования строки пути в ITEMIDLIST.   -  person Remy Lebeau    schedule 15.04.2021
comment
@SimonMourier Я попробовал ваше альтернативное определение функции API в C #, и это не вызвало никаких ошибок, но ни одна из различных переделанных перестановок не смогла обновить папку Windows. Вопрос обновлен с дальнейшими попытками   -  person Sam    schedule 15.04.2021
comment
Пробовали ли вы SHGetSetFolderCustomSettings API. Ссылка: Пользовательские значки папок с desktop.ini и мгновенным обновлением   -  person Song Zhu    schedule 15.04.2021
comment
@SongZhu-MSFT (1) я не уверен, где и как установить тег в связанной структуре данных SHFOLDERCUSTOMSETTINGS (2) даже тогда мне, вероятно, понадобится небольшой пример C #, чтобы помочь мне начать работу - я никогда не понимал всех этих C ++ указатели   -  person Sam    schedule 15.04.2021
comment
Я на 100% уверен, что то, что я дал вам, работает для стандартных элементов оболочки, поэтому это может быть связано с тем, что вы ожидаете от SHhangeNotify при изменении файла desktop.ini, который является специальным файлом.   -  person Simon Mourier    schedule 15.04.2021
comment
@Sam Вы можете обратиться к этому ссылка, чтобы узнать, как вызывать SHGetSetFolderCustomSettings в C#.   -  person Song Zhu    schedule 15.04.2021
comment
@SongZhu-MSFT у меня SHGetSetFolderCustomSetting работает как в примере, но я не знаю, какая комбинация настроек изменит тег папки - наибольший интерес и примеры относятся к значку файла   -  person Sam    schedule 15.04.2021
comment
@SongZhu-MSFT Я не вижу, куда бы я на самом деле поместил string тега, который мне нужен для папки, в структуре данных SHFOLDERCUSTOMSETTINGS   -  person Sam    schedule 15.04.2021
comment
Как сказал Саймон, я думаю, что предложенное вам решение может быть применено, возможно, потому, что у вас другие ожидания относительно изменения desktop.ini.   -  person Song Zhu    schedule 16.04.2021