使用C#调用CfRegisterSyncRoot出现0x80070057错误,求排查方案
解决CfRegisterSyncRoot调用返回0x80070057错误的问题
问题概述
使用C#结合CSWin32访问CloudFilter API创建云同步提供程序时,调用CfRegisterSyncRoot始终返回0x80070057错误,转换后得到异常:System.ArgumentException: Value does not fall within the expected range.。预期云提供程序会出现在文件资源管理器左侧导航栏及注册表中,但实际均未生效,尝试修改参数、使用指针重载、清理bin文件夹等操作均未解决问题。
错误原因分析
0x80070057是典型的参数无效错误,结合CloudFilter API的要求,主要问题在于:
- CSWin32生成的结构体默认不会自动填充
StructSize字段,而Win32 API需要该字段识别结构体大小,否则无法正确解析参数。 - 同步根目录可能不存在,API不会自动创建目录。
- 程序未以管理员权限运行,注册同步根需要系统级权限。
解决方案
- 手动设置结构体的
StructSize字段:对CF_SYNC_REGISTRATION和CF_SYNC_POLICIES结构体,必须显式设置StructSize为结构体的字节大小。 - 确保同步根目录存在:调用API前检查并创建目标目录。
- 以管理员权限运行程序:注册同步根需要管理员权限,否则会因权限不足导致参数错误或操作失败。
修正后的代码示例
using Windows.Win32; using Windows.Win32.Storage.CloudFilters; using Windows.Win32.Foundation; using System.Runtime.InteropServices; using System.IO; namespace PStore; internal class Install { public static void Main() { string syncRootPath = @"C:\Users\finne\PStore"; // 确保同步根目录存在,API不会自动创建 if (!Directory.Exists(syncRootPath)) { Directory.CreateDirectory(syncRootPath); } unsafe { fixed (char* providerNameP = "PStore", providerVersionP = "1.1.1") { CF_SYNC_REGISTRATION SyncReg = new() { // 必须设置结构体大小,让API正确解析 StructSize = (uint)sizeof(CF_SYNC_REGISTRATION), ProviderName = new PCWSTR(providerNameP), ProviderVersion = new PCWSTR(providerVersionP) }; CF_SYNC_POLICIES SyncPol = new() { // 同样需要设置结构体大小 StructSize = (uint)sizeof(CF_SYNC_POLICIES), Hydration = new CF_HYDRATION_POLICY { Primary = CF_HYDRATION_POLICY_PRIMARY.CF_HYDRATION_POLICY_FULL, Modifier = CF_HYDRATION_POLICY_MODIFIER.CF_HYDRATION_POLICY_MODIFIER_AUTO_DEHYDRATION_ALLOWED }, Population = new CF_POPULATION_POLICY { Primary = CF_POPULATION_POLICY_PRIMARY.CF_POPULATION_POLICY_FULL, Modifier = CF_POPULATION_POLICY_MODIFIER.CF_POPULATION_POLICY_MODIFIER_NONE }, InSync = CF_INSYNC_POLICY.CF_INSYNC_POLICY_NONE, HardLink = CF_HARDLINK_POLICY.CF_HARDLINK_POLICY_NONE, PlaceholderManagement = CF_PLACEHOLDER_MANAGEMENT_POLICY.CF_PLACEHOLDER_MANAGEMENT_POLICY_DEFAULT, }; HRESULT res = PInvoke.CfRegisterSyncRoot( syncRootPath, SyncReg, SyncPol, CF_REGISTER_FLAGS.CF_REGISTER_FLAG_NONE ); if (res != HRESULT.S_OK) { Console.WriteLine($"Failed with {(uint) res:X8}"); throw Marshal.GetExceptionForHR((int) res) ?? new Exception($"Unidentified Error - {(uint) res:X8}"); } else { Console.WriteLine("Sync root registered successfully."); } } } } }
验证步骤
- 以管理员权限运行修改后的程序。
- 检查文件资源管理器左侧导航栏,确认云提供程序已出现。
- 查看注册表路径
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager,确认存在对应同步根的注册项。
内容的提问来源于stack exchange,提问作者Finn E
相关产品推荐
相关产品推荐

