修改符号链接详情:CreateFilePrivate调用报错问题排查
无法排查CreateFilePrivate调用问题(错误码2:ERROR_FILE_NOT_FOUND)
问题场景
通过PowerShell调用自定义Win32类的setFileDetails方法,代码如下:
$path = "D:\temporal\t1.txt" $item = Get-Item -LiteralPath $path -Force [Win32]::setFileDetails($path, $item.CreationTimeUtc.ToFileTime(), $item.LastAccessTimeUtc.ToFileTime(), $item.LastWriteTimeUtc.AddDays(1).ToFileTime())
对应的C# Win32类实现代码:
using System; // 依赖该程序集的部分内容 using System.Runtime.InteropServices; // 用于DllImport和Marshal相关操作 using Microsoft.Win32.SafeHandles; // 引入SafeFileHandle using System.IO; // 引入FileShare、FileMode public class Win32 { struct FILE_BASIC_INFO { internal long CreationTime; internal long LastAccessTime; internal long LastWriteTime; internal long ChangeTime; internal uint FileAttributes; // 文件属性(二进制值) }; [Flags] enum AccessRights: uint { // Windows PowerShell的`Add-Type`不支持System.Messaging.GenericAccessRights // 通用访问权限 Read = 0x80000000, // 2147483648,对应十进制-2147483648 Write = 0x40000000, // 1073741824 Execute = 0x20000000, // 536870912 All = 0x10000000, // 268435456 None = 0x00000000 // 0 }; [Flags] enum CreateFile_Options: uint { // 标志位 ReparsePoint = 0x00200000, // 若为符号链接则不跟随,对应OPEN_REPARSE_POINT BACKUP_SEMANTICS = 0x02000000, DELETE_ON_CLOSE = 0x04000000, NO_BUFFERING = 0x20000000, OPEN_NO_RECALL = 0x00100000, OVERLAPPED = 0x40000000, POSIX_SEMANTICS = 0x01000000, RANDOM_ACCESS = 0x10000000, SESSION_AWARE = 0x00800000, SEQUENTIAL_SCAN = 0x08000000, WRITE_THROUGH = 0x80000000 }; [DllImport("kernel32.dll", SetLastError = true)] static extern bool SetFileInformationByHandle( SafeFileHandle item, int Type_v, // 对应枚举FILE_INFO_BY_HANDLE_CLASS ref FILE_BASIC_INFO sho_v, // 指针类型参数 uint size_v ); [DllImport("kernel32.dll", SetLastError = true)] static extern bool GetFileInformationByHandleEx( SafeFileHandle item, int Type_v, // 对应枚举FILE_INFO_BY_HANDLE_CLASS ref FILE_BASIC_INFO sho_v, // 指针类型参数 uint size_v ); [DllImport("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)] static extern SafeFileHandle CreateFilePrivate( string path, AccessRights v_Access, FileShare v_Share, IntPtr v_Security, // 传IntPtr.Zero使用默认安全设置,也可传入SECURITY_ATTRIBUTES结构体引用 FileMode a, CreateFile_Options v_Options, IntPtr Template // 不能传SafeFileHandle类型的null,改用IntPtr.Zero ); public static void setFileDetails ( string path, long CreationEventTime, long ReadingEventTime, long WritingEventTime // System.IO.FileAttributes FileAttributes ) { SafeFileHandle item = CreateFilePrivate(path , AccessRights.Read | AccessRights.Write , FileShare.Read , IntPtr.Zero , FileMode.Open , CreateFile_Options.ReparsePoint , IntPtr.Zero); Console.WriteLine(path); // 输出的路径100%指向符号链接 Console.WriteLine(Marshal.GetLastWin32Error()); // 返回错误码2,对应ERROR_FILE_NOT_FOUND var BasicInfo = new FILE_BASIC_INFO(); GetFileInformationByHandleEx(item, (int) 0, ref BasicInfo, (uint) Marshal.SizeOf(BasicInfo)); BasicInfo = new FILE_BASIC_INFO() { CreationTime = CreationEventTime, LastAccessTime = ReadingEventTime, LastWriteTime = WritingEventTime, ChangeTime = BasicInfo.ChangeTime, FileAttributes = (uint) 0 // 设为0表示不修改文件属性 }; SetFileInformationByHandle(item, (int) 0, ref BasicInfo, (uint) Marshal.SizeOf(BasicInfo)); } }
当前问题
已根据@Dai的建议修复代码,但问题依旧:调用后返回错误码2(ERROR_FILE_NOT_FOUND),且已确认路径指向的是符号链接。
内容的提问来源于stack exchange,提问作者irvnriir
相关产品推荐
相关产品推荐

