如何检查本地OneDrive文件夹是否同步?

我需要能够检查本地OneDrive文件夹是否同步/最新。

我可以通过查看任何文件/文件夹属性(使用C#代码)来检查这一点而不使用任何One Drive API吗?

我被困在那里,并试图检查主文件夹图标。

EDITED

重点是提取同步文件夹图标并获取重叠CLSID。

您首先需要一个类来提取您需要的信息:

using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using Microsoft.Win32; namespace MyApp.Classes { public class ExtractIconInfo { [Flags] private enum SHGFI : uint { SHGFI_ICON = 0x000000100, SHGFI_DISPLAYNAME = 0x000000200, SHGFI_TYPENAME = 0x000000400, SHGFI_ATTRIBUTES = 0x000000800, SHGFI_ICONLOCATION = 0x000001000, SHGFI_EXETYPE = 0x000002000, SHGFI_SYSICONINDEX = 0x000004000, SHGFI_LINKOVERLAY = 0x000008000, SHGFI_SELECTED = 0x000010000, SHGFI_ATTR_SPECIFIED = 0x000020000, SHGFI_LARGEICON = 0x000000000, SHGFI_SMALLICON = 0x000000001, SHGFI_OPENICON = 0x000000002, SHGFI_SHELLICONSIZE = 0x000000004, SHGFI_PIDL = 0x000000008, SHGFI_USEFILEATTRIBUTES = 0x000000010, SHGFI_ADDOVERLAYS = 0x000000020, SHGFI_OVERLAYINDEX = 0x000000040 } [Flags] private enum FileAttributes : uint { Readonly = 0x00000001, Hidden = 0x00000002, System = 0x00000004, Directory = 0x00000010, Archive = 0x00000020, Device = 0x00000040, Normal = 0x00000080, Temporary = 0x00000100, SparseFile = 0x00000200, ReparsePoint = 0x00000400, Compressed = 0x00000800, Offline = 0x00001000, NotContentIndexed = 0x00002000, Encrypted = 0x00004000, Virtual = 0x00010000 } [Flags] public enum ISIOI : uint { ISIOI_ICONFILE = 0x00000001, ISIOI_ICONINDEX = 0x00000002 } private SortedDictionary ShellIconOverlayIdentifiers; public string IconName { get; private set; } public Icon Icon { get; private set; } public int IconOverlayIndex { get; private set; } public Guid IconOverlayGuid { get; private set; } public ExtractIconInfo(FileInfo fi) { ExtractIcon(fi.FullName, false); } public ExtractIconInfo(DirectoryInfo di) { ExtractIcon(di.FullName, true); } public ExtractIconInfo(string path, bool isFolder) { ExtractIcon(path, isFolder); } [ComVisible(false)] [ComImport] [Guid("0C6C4200-C589-11D0-999A-00C04FD655E1")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IShellIconOverlayIdentifier { [PreserveSig] int IsMemberOf([MarshalAs(UnmanagedType.LPWStr)] string path, uint attributes); [PreserveSig] int GetOverlayInfo([MarshalAs(UnmanagedType.LPWStr)] string iconFileBuffer, int iconFileBufferSize, out int iconIndex, out uint flags); [PreserveSig] int GetPriority(out int priority); } [StructLayout(LayoutKind.Sequential)] private struct SHFILEINFO { internal IntPtr hIcon; internal int iIcon; internal uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] internal string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] internal string szTypeName; }; [DllImport("shell32.dll")] private static extern IntPtr SHGetFileInfo( string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags ); [DllImport("shell32.dll")] private static extern int SHGetIconOverlayIndex( string pszIconPath, int iIconIndex ); [DllImport("user32.dll")] public static extern int DestroyIcon(IntPtr hIcon); private void ExtractIcon(string path, bool isFolder) { SHFILEINFO shIconInfo = new SHFILEINFO(); SHGetFileInfo(path, isFolder ? (uint)FileAttributes.Directory : (uint)FileAttributes.Normal, ref shIconInfo, (uint)Marshal.SizeOf(shIconInfo), (uint)SHGFI.SHGFI_ICON | (uint)SHGFI.SHGFI_LARGEICON | (uint)SHGFI.SHGFI_DISPLAYNAME | (uint)SHGFI.SHGFI_ADDOVERLAYS | (uint)SHGFI.SHGFI_OVERLAYINDEX); Icon = (Icon)Icon.FromHandle(shIconInfo.hIcon).Clone(); IconName = shIconInfo.szDisplayName; IconOverlayIndex = (shIconInfo.iIcon >> 24) & 0xFF; GetOverlayIconGuid(); DestroyIcon(shIconInfo.hIcon); } private void GetOverlayIconGuid() { IconOverlayGuid = Guid.Empty; GetRegistryShellIconOverlayIdentifiers(); foreach (string key in ShellIconOverlayIdentifiers.Keys) { string AIconFileName = string.Empty; int AIconIndex = 0; Guid value = ShellIconOverlayIdentifiers[key]; GetOverlayIconInfo(value, out AIconFileName, out AIconIndex); if (SHGetIconOverlayIndex(AIconFileName, AIconIndex) == IconOverlayIndex) IconOverlayGuid = value; } } private void GetOverlayIconInfo(Guid CLSID, out string path, out int index) { try { path = new string(' ', 256); uint flags = 0; IShellIconOverlayIdentifier SHIOI = Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID, true), true) as IShellIconOverlayIdentifier; SHIOI.GetOverlayInfo(path, path.Length, out index, out flags); Marshal.ReleaseComObject(SHIOI); if ((flags & (uint)ISIOI.ISIOI_ICONFILE) != 0) { if ((flags & (uint)ISIOI.ISIOI_ICONINDEX) == 0) index = 0; } else { path = string.Empty; index = 0; } path = path.Substring(0, path.IndexOf('\0')); } catch { path = string.Empty; index = 0; } } private void GetRegistryShellIconOverlayIdentifiers() { ShellIconOverlayIdentifiers = new SortedDictionary(); using (RegistryKey key32 = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, Environment.MachineName, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers")) foreach (string subKey in key32.GetSubKeyNames()) { Guid value = Guid.Parse((string)key32.OpenSubKey(subKey).GetValue(null)); if (!ShellIconOverlayIdentifiers.ContainsKey(subKey)) ShellIconOverlayIdentifiers.Add(subKey, value); } using (RegistryKey key64 = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, Environment.MachineName, RegistryView.Registry64).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers")) foreach (string subKey in key64.GetSubKeyNames()) { Guid value = Guid.Parse((string)key64.OpenSubKey(subKey).GetValue(null)); if (!ShellIconOverlayIdentifiers.ContainsKey(subKey)) ShellIconOverlayIdentifiers.Add(subKey, value); } } } } 

这里的相关信息是IconOverlayGuid

然后比较:

 public enum SyncStatus { Off, Unknown, Syncing, Synced, SharedSyncing, SharedSynced, Error } private SyncStatus CheckIfSync(DirectoryInfo di) { ExtractIconInfo IcoInfo = new ExtractIconInfo(di); if (IcoInfo != null) { if (IcoInfo.IconOverlayGuid == Guid.Empty) return SyncStatus.Off; else if (IcoInfo.IconOverlayGuid == new Guid("{BBACC218-34EA-4666-9D7A-C78F2274A524}")) return SyncStatus.Error; else if (IcoInfo.IconOverlayGuid == new Guid("{F241C880-6982-4CE5-8CF7-7085BA96DA5A}")) return SyncStatus.Synced; else if (IcoInfo.IconOverlayGuid == new Guid("{A0396A93-DC06-4AEF-BEE9-95FFCCAEF20E}")) return SyncStatus.Syncing; else if (IcoInfo.IconOverlayGuid == new Guid("{5AB7172C-9C11-405C-8DD5-AF20F3606282}")) return SyncStatus.SharedSynced; else if (IcoInfo.IconOverlayGuid == new Guid("{A78ED123-AB77-406B-9962-2A5D9D2F7F30}")) return SyncStatus.SharedSyncing; else return SyncStatus.Unknown; } else return SyncStatus.Unknown; } 

叠加图标存储在FileSyncShell.dll 。 他们的CLSID存储在注册表中: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiersHKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers

REGEDIT

  • OneDrive1:错误同步
  • OneDrive2:同步共享
  • OneDrive3:同步共享
  • OneDrive4:同步
  • OneDrive5:同步

希望有所帮助!

(我在那个上花了太多时间,但我学到了很多东西!)

可能比较LastModifiedDateTime。

 ...Drive.Root.ItemWithPath(file).Request().GetAsync()).FileSystemInfo.LastModifiedDateTime