我正在使用这个库来创建或获取我的连接点。一旦我得到这样的JunctionPoint
实例,我就可以DirectoryInfo
从Link
's (*)路径创建一个并读取LastWriteTimeUtc
属性。现在我想将此时间戳设置为另一个日期,但它不起作用:值保持不变并且不会引发异常。
(*):这是您找到交汇点的位置的路径。
我怀疑,您需要使用一些 PInvoke 才能完成这项工作。通过在创建时或之后使用第二种方法指定所需的时间戳。所以我查找了用于创建连接点的文档,希望能找到一些有用的东西。CreateFile()
该dwFlagsAndAttributes
参数似乎接受一些标志/数值,并且 该方法的文档SetFileAttributes()
看起来并不好。
我在使用 PInvoke 方面没有太多经验,非常感谢一些好的建议。
编辑
“我不想下载代码。我想在问题中看到足够多的代码以便能够回答”
这是用于创建联结的相关代码。它与codeproject的代码略有不同,因为我需要进行一些修改才能将其嵌入到我自己的库中。Link
是类型DirectoryInfo
:
public void Create(bool overwrite = true)
{
Link.Refresh();
if (Link.Exists)
{
if (!overwrite) throw new IOException("Directory already exists and overwrite parameter is false.");
}
else Link.Create();
using (var handle = OpenReparsePoint(Link.FullName, EFileAccess.GenericWrite))
{
var targetDirBytes = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + Target.FullName);
var reparseDataBuffer = new REPARSE_DATA_BUFFER();
reparseDataBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
reparseDataBuffer.ReparseDataLength = (ushort) (targetDirBytes.Length + 12);
reparseDataBuffer.SubstituteNameOffset = 0;
reparseDataBuffer.SubstituteNameLength = (ushort) targetDirBytes.Length;
reparseDataBuffer.PrintNameOffset = (ushort) (targetDirBytes.Length + 2);
reparseDataBuffer.PrintNameLength = 0;
reparseDataBuffer.PathBuffer = new byte[0x3ff0];
Array.Copy(targetDirBytes, reparseDataBuffer.PathBuffer, targetDirBytes.Length);
var inBufferSize = Marshal.SizeOf(reparseDataBuffer);
var inBuffer = Marshal.AllocHGlobal(inBufferSize);
try
{
Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);
int bytesReturned;
var result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_SET_REPARSE_POINT,
inBuffer, targetDirBytes.Length + 20, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
if (!result) ThrowLastWin32Error("Unable to create junction point.");
}
finally
{
Marshal.FreeHGlobal(inBuffer);
}
}
}
private static SafeFileHandle OpenReparsePoint(string reparsePoint, EFileAccess accessMode)
{
var reparsePointHandle = new SafeFileHandle(CreateFile(reparsePoint, accessMode,
EFileShare.Read | EFileShare.Write | EFileShare.Delete,
IntPtr.Zero, ECreationDisposition.OpenExisting,
EFileAttributes.BackupSemantics |
EFileAttributes.OpenReparsePoint, IntPtr.Zero), true);
if (Marshal.GetLastWin32Error() != 0) ThrowLastWin32Error("Unable to open reparse point.");
return reparsePointHandle;
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(
string lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition dwCreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode,
IntPtr InBuffer, int nInBufferSize,
IntPtr OutBuffer, int nOutBufferSize,
out int pBytesReturned, IntPtr lpOverlapped);