简体   繁体   English

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

[英]How can I check local OneDrive folder is in sync?

I need to be able to check if the local OneDrive folder is in sync/up to date. 我需要能够检查本地OneDrive文件夹是否同步/最新。

Can I check this by looking at any of the file/folder properties(in C# code) Without using any of One Drive APIs? 我可以通过查看任何文件/文件夹属性(使用C#代码)来检查这一点而不使用任何One Drive API吗?

I was stuck with that and tought to check the main folder Icon. 我被困在那里,并试图检查主文件夹图标。

EDITED EDITED

The point is to extract the synced folder icon and get the overlay CLSID. 重点是提取同步文件夹图标并获取重叠CLSID。

You first need a class to extract the info you need : 您首先需要一个类来提取所需的信息:

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<string, Guid> 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<string, Guid>();

            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);
                }
        }
    }
}

The relevant info here is IconOverlayGuid . 这里的相关信息是IconOverlayGuid

Then compare : 然后比较:

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;
}

The Overlay Icons are stored in FileSyncShell.dll . 叠加图标存储在FileSyncShell.dll Their CLSID are stored in the registry : HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers and HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers . 他们的CLSID存储在注册表中: HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiersHKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers

REGEDIT

  • OneDrive1 : Sync in error OneDrive1:错误同步
  • OneDrive2 : Synced Shared OneDrive2:同步共享
  • OneDrive3 : Syncing Shared OneDrive3:同步共享
  • OneDrive4 : Synced OneDrive4:同步
  • OneDrive5 : Syncing OneDrive5:同步

Hope that helps ! 希望有所帮助!

(I spent way too much time on that one, but I learned a lot !) (我在那个上花了太多时间,但我学到了很多东西!)

可能比较LastModifiedDateTime。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 c# 或 PowerShell 检查 OneDrive 文件夹中文件/文件夹的状态是否已同步? - How can I check status of files/folders in OneDrive folder whether it is synced or not using c# or PowerShell? 如何在OneDrive中设置公用文件夹权限? - How can I set public folder permissions in OneDrive? 如何使用OneDrive API将文件上传到OneDrive上的共享文件夹中? - How can I upload files into a shared folder on OneDrive using OneDrive API? Azure Functions:如何查看Dropbox或OneDrive文件夹以及同步ftp位置 - Azure Functions : how to watch a Dropbox or OneDrive folder and sync a ftp location 如何获得OneDrive中另一个文件夹内的文件夹的文件夹ID? - How can i get folder id of folders inside another folders in onedrive? 如何固定Windows Mobile 6设备并将其与本地数据库同步? - How can I dock a Windows Mobile 6 device and sync it with a local database? 是否可以像本地数据库一样在OneDrive(在云中)上使用sqlite数据库? - Can I use an sqlite database on OneDrive (in the cloud) like a local database? 如何检查文件夹的内容是否已更改 - How can I check if the content of a folder was changed 如何使用OneDrive SDK更新存储在OneDrive(业务)上的文件的创建和/或最后修改时间 - How can I update the creation and/or the last modified time of a file stored on OneDrive (Business) using the OneDrive SDK 如何在C#中浏览本地虚拟文件夹? - How can I browse a local virtual folder in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM