Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SetFileTime返回错误代码5_C#_File_Io_Pinvoke_Kernel32 - Fatal编程技术网

C# SetFileTime返回错误代码5

C# SetFileTime返回错误代码5,c#,file,io,pinvoke,kernel32,C#,File,Io,Pinvoke,Kernel32,我正在尝试p/调用SetFileTime,但似乎无法使其工作。它总是为我返回一个错误代码5(拒绝访问),我不知道为什么。以下是我正在使用的代码: void Main() { var pointer = CreateFile(@"C:\Users\User\Desktop\New folder\New Text Document.txt", FileAccess.ReadWrite, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttri

我正在尝试p/调用SetFileTime,但似乎无法使其工作。它总是为我返回一个错误代码5(拒绝访问),我不知道为什么。以下是我正在使用的代码:

void Main()
{
    var pointer = CreateFile(@"C:\Users\User\Desktop\New folder\New Text Document.txt", FileAccess.ReadWrite, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
    Console.WriteLine(pointer);
    var now = DateTime.Now.ToFileTime();
    long lpCreationTime = now;
    long lpLastAccessTime = now;
    long lpLastWriteTime = now;
    if (!SetFileTime(pointer, ref lpCreationTime, ref lpLastAccessTime, ref lpLastWriteTime))
        Console.WriteLine(GetLastError());
    CloseHandle(pointer);
}

[DllImport("kernel32.dll")]
static extern UInt32 GetLastError();

[DllImport("kernel32.dll", SetLastError = true)]
static extern Boolean SetFileTime(IntPtr hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);

[DllImport("kernel32.dll", SetLastError = true)]
static extern Boolean CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr CreateFile(String fileName, [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess, [MarshalAs(UnmanagedType.U4)] FileShare fileShare, IntPtr securityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, [MarshalAs(UnmanagedType.U4)] FileAttributes flags, IntPtr template);
我的指针是有效的(2376),但我看到SetFileTime失败并返回了错误代码5(拒绝访问)。现在,我已经确保我以管理员身份运行,并且我的帐户拥有该路径的权限,但仍然没有权限。有人知道为什么会这样吗

更新


Marshal.GetLastWin32Error()
在调用
SetFileTime
后也返回5。另外,我需要让这个调用工作,这样我就可以在Windows中的长路径上
SetFileTime
,而
CreateFile
支持长路径,但是.NET的当前文件库不支持Windows中的长路径。

来自
SetFileTime
的文档:

文件或目录的句柄。句柄必须是使用具有文件写入属性访问权限的CreateFile函数创建的

您的代码无法做到这一点。.net
文件访问
枚举与Win32访问标志不兼容。您需要定义一个专门用于
CreateFile
的枚举。同样,您使用的
FileShare
FileMode
也不正确

此p/invoke声明应足以:


正如Alexei所说,不要调用
GetLastError
,因为您可能在为框架调用提取错误代码,而不是真正的错误。使用
SetLastError=true
Marshal.GetLastWin32Error()


如果
CreateFile
,也无法检查返回值中的错误

多亏了所有的帮助,我能够通过以下方式实现我的目标(FileAccess.ReadWrite转换为0x3,而FILE_WRITE_属性为0x100):


@Alexandru你有没有想过在谷歌上搜索你试图调用SetFileTime的方法。我已经完全阅读了它的API文档。除了
API
之外,还有更多的资源/示例。有没有理由忽略.net framework方法来实现这一点?@DavidHeffernan有没有.net framework方法来实现这一点?我可以使用Reflector查看源代码。我不知道您为什么继续使用
FileShare
FileMode
。它们与
FileAccess
FileShare
FileMode
一样错误。它们与
CreateFile
一起工作。它们只是没有包含所有可能的选项(对于我所需要的来说,这些选项太过分了),我不相信它们是正确的。你检查过数值了吗?@DavidHeffernan我没有,但我知道,通过我自己的实验(我在CreateFile方面做了很多工作),它们可以达到预期的目的。如果您不相信我,您可以看到使用它们的不仅仅是我,因为在调用CreateFile()时还有各种其他方法签名使用它们。我不认为有那么多人会像这样P/Invoke,如果它对他们不起作用的话。但是,最重要的是,请记住这些是位标志,其中最重要的是标志包含它们所需的位。不,我在回答中提到的pinvoke.net签名使用适当的位标志定义枚举。恰好
FileShare
匹配。大概这是故意的,我怀疑这些价值观是否会改变
FileMode
有一个额外的值
FileMode.Append
,该值
CreateFile
无法理解<代码>文件模式是真正的枚举,而不是位标志。在我看来,你应该停止滥用这些类型,并按照pinvoke.net显示的方式来做。那么,为什么他们在这里建议在顶部部分使用.net文件访问?@IronHide抱歉,我不理解你的问题我是在链接下引用这段代码的
[DllImport(“kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true)]公共静态外部IntPtr CreateFile([Marshallas(UnmanagedType.LPTStr)]字符串文件名,[Marshallas(UnmanagedType.U4)]FileAccess访问,
这里是.netFileAccess@IronHide好吧,我觉得这是错的。
FileAccess
的序号与
GENERIC\u READ
GENERIC\u WRITE
不匹配。更深奥的标志根本不存在。
[DllImport("kernel32.dll", SetLastError = true)]
static extern Boolean SetFileTime(SafeFileHandle hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern SafeFileHandle CreateFile(String fileName, uint fileAccess, [MarshalAs(UnmanagedType.U4)] FileShare fileShare, IntPtr securityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, [MarshalAs(UnmanagedType.U4)] FileAttributes flags, IntPtr template);

static void Main(string[] args)
{
    var handle = CreateFile(@"C:\Users\User\Desktop\FileTimeTest.txt", (uint)(0x3 | 0x100), FileShare.None, IntPtr.Zero, FileMode.Create, FileAttributes.Normal, IntPtr.Zero);
    if (!handle.IsInvalid)
    {
        using (var stream = new FileStream(handle, FileAccess.ReadWrite))
        using (var writer = new StreamWriter(stream))
        {
            writer.WriteLine("Hello, world.");
            var now = DateTime.MaxValue.ToFileTime();
            if (!SetFileTime(handle, ref now, ref now, ref now))
                Console.WriteLine(Marshal.GetLastWin32Error());
        }
    }
}