【问题标题】:How do I detect changes to Known Folder Redirection如何检测对已知文件夹重定向的更改
【发布时间】:2020-08-28 21:51:42
【问题描述】:

使用Known Folder Move enabled 安装 OneDrive 时,用户首次登录时不会重定向已知文件夹,然后在会话进行到一半时,它们会被重定向到 OneDrive 文件夹。

我怎样才能检测到这一点?

我已经在CSIDL_Desktop 上尝试过WM_SETTINGCHANGESHChangeNotifyRegister 无济于事。

【问题讨论】:

    标签: c# winapi known-folders


    【解决方案1】:

    它是一个dirty undocumented hack,但如果您监视HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders 的更改,它将在重定向时触发。

    如何做到这一点的 C# 示例是:

    public sealed class KnownFolderWatcher : IDisposable
    {
        private readonly SynchronizationContext SyncCtx;
        private readonly RegistryKey Key;
        private readonly Thread thRead;
        private readonly AutoResetEvent mreTriggered;
    
        public event EventHandler KeyChanged;
    
        private Exception Exception;
        private bool isDisposed;
    
    
        public KnownFolderWatcher(SynchronizationContext syncCtx)
        {
            this.SyncCtx = syncCtx ?? throw new ArgumentNullException(nameof(syncCtx));
    
            this.Key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", false)
                ?? throw new InvalidOperationException("Could not open User Shell Folders key");
    
            this.mreTriggered = new AutoResetEvent(false);
    
            this.thRead = new Thread(thRead_Main);
            this.thRead.Name = "Registry Change Reader";
            this.thRead.IsBackground = true;
            this.thRead.Start();
        }
    
        private void thRead_Main()
        {
            try
            {
                while (true)
                {
                    NativeMethods.RegNotifyChangeKeyValue(Key.Handle, false, 4 /* REG_NOTIFY_CHANGE_LAST_SET */, mreTriggered.SafeWaitHandle, true);
                    mreTriggered.WaitOne();
                    if (isDisposed)
                    {
                        break;
                    }
    
                    SyncCtx.Post(_1 =>
                    {
                        KeyChanged?.Invoke(this, EventArgs.Empty);
                    }, null);
                }
            }
            catch (Exception ex)
            {
                this.Exception = ex;
            }
        }
    
        public void Dispose()
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException(nameof(KnownFolderWatcher));
            }
            isDisposed = true;
    
            mreTriggered.Set();
            thRead.Join();
    
            if (this.Exception != null)
            {
                throw new InvalidOperationException("Exception from read thread", Exception);
            }
        }
    }
    
    internal static class NativeMethods
    {
        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern uint RegNotifyChangeKeyValue(SafeRegistryHandle key, bool watchSubTree, uint notifyFilter, SafeWaitHandle regEvent, bool async);
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-04
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 2012-01-05
      • 2021-05-28
      • 1970-01-01
      相关资源
      最近更新 更多