![](/img/trans.png)
[英]How to delete registry symbolic link key from C#: "An error is preventing this key from being opened. Details: Access is denied"
[英]Changing a Details of Symbolic Link
无法弄清楚CreateFilePrivate
有什么问题。
从 PowerShell 调用,带有:
$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())
using System; // required for some of it's content .
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; // binary
};
[Flags]
enum AccessRights: uint { // System.Messaging.GenericAccessRights doesn't work in Windows Powershell 's `Add-Type` .
// # GenericAccessRights
Read = 0x80000000, // 2147483648 "-2147483648"
Write = 0x40000000, // 1073741824
Execute = 0x20000000, // 536870912
All = 0x10000000, // 268435456
None = 0x00000000 // 0
};
[Flags]
enum CreateFile_Options: uint {
// # Flags
ReparsePoint = 0x00200000, // do not follow if a symbolic link . "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, // `enum FILE_INFO_BY_HANDLE_CLASS`
ref FILE_BASIC_INFO sho_v, // "Pointer"
uint size_v
);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetFileInformationByHandleEx(
SafeFileHandle item,
int Type_v, // `enum FILE_INFO_BY_HANDLE_CLASS`
ref FILE_BASIC_INFO sho_v, // "Pointer"
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, // `null` for default . `ref (SECURITY_ATTRIBUTES {})`
FileMode a,
CreateFile_Options v_Options,
IntPtr Template // `(SafeFileHandle) null` : "SafeHandle cannot be null" .
);
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) // the output path 100% targets a Symbolic Link
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 // `(uint) 0` to not change any
};
SetFileInformationByHandle(item, (int) 0, ref BasicInfo, (uint) Marshal.SizeOf(BasicInfo));
}
}
对@Dai 指出的问题进行了修复。
默认情况下,Dllimport 将传递给方法的参数转换为某种特定的编码,因此对于 Unicode <<name>>W
Win32 命令,它需要设置 CharSet。
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
IntPtr 作为指针工作,所以当:
可以使用 IntPtr Type 和 IntPtr.Zero。
感谢所有试图提供帮助的人,尤其是@SimonMourier @Dai。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.