Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# 如何使用空参数P/调用SetFileTime?_C#_.net_File Io_Pinvoke - Fatal编程技术网

C# 如何使用空参数P/调用SetFileTime?

C# 如何使用空参数P/调用SetFileTime?,c#,.net,file-io,pinvoke,C#,.net,File Io,Pinvoke,尝试从我的C#程序p/调用,我使用以下签名: [DllImport(@"kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SetFileTime( IntPtr hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLas

尝试从我的C#程序p/调用,我使用以下签名:

[DllImport(@"kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetFileTime(
    IntPtr hFile,
    ref long lpCreationTime,
    ref long lpLastAccessTime,
    ref long lpLastWriteTime);
BOOL WINAPI SetFileTime(
  __in      HANDLE hFile,
  __in_opt  const FILETIME *lpCreationTime,
  __in_opt  const FILETIME *lpLastAccessTime,
  __in_opt  const FILETIME *lpLastWriteTime
);
文档中说明了以下非托管签名:

[DllImport(@"kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetFileTime(
    IntPtr hFile,
    ref long lpCreationTime,
    ref long lpLastAccessTime,
    ref long lpLastWriteTime);
BOOL WINAPI SetFileTime(
  __in      HANDLE hFile,
  __in_opt  const FILETIME *lpCreationTime,
  __in_opt  const FILETIME *lpLastAccessTime,
  __in_opt  const FILETIME *lpLastWriteTime
);
对于第2、第3和第4个参数,它们可以是可选的:

如果应用程序不需要更改此信息,则此参数可以为NULL

这正是我想要做的:只传递三个日期时间值中的一个,并将其他值设置为
null

我完全不知道如何用p/Invoke签名来表达这一点

因此我的问题是:

哪一种是正确的p/Invoke签名(或正确的调用方式),能够将
null
传递给
SetFileTime
函数参数

编辑1:

由于已经提供了一个可写属性来设置文件时间,您可能会问,为什么我要自己做而不是使用该类

原因是我计划在我的库中使用此函数,该函数用于克服
MAX\u PATH
限制,因此无法使用标准的.NET函数

因此,不幸的是,使用
FileInfo
类不是一个选项

编辑2:

我用汉斯建议的方法解决了这个问题。之后,我发现上面写着:

此外,为其中一个参数指定零值与指定NULL具有相同的效果


虽然我没有检查这是否正确,但对于其他有类似要求的人来说,这可能仍然是一个选项。

您不能使用C#中的ref关键字对其建模,该关键字在运行时始终生成非空指针。实际上,您必须声明它
long*
,这需要使用不安全关键字。使用
&local var
语法传递参数,或使用
null

避免使用“不安全”的一个可能技巧是使用不同名称声明此方法的3个版本,使用DllImport的EntryPoint属性将它们全部映射到SetFileTime()。指定不希望设置为IntPtr的项,以便可以传递IntPtr.Zero,即确实希望设置为ref long的项。例如:

[DllImport("kernel32.dll", SetLastError = true, EntryPoint="SetFileTime", ExactSpelling=true)]
internal static extern bool SetFileCreateTime(
    IntPtr hFile,
    ref long lpCreationTime,
    IntPtr lpLastAccessTimeUnused,
    IntPtr lpLastWriteTimeUnused);

对SetFileAccessTime和SetFileWriteTime重复上述操作。

您可以使用IntPtr,但…为什么要使用p/Invoke?!为什么不使用System.IO.FileInfo?这些属性是R/W。它可以在C#中完成,而无需调用本机API。谢谢,@Adriano关于
FileInfo
class:-)的观点很好。实际上,我正计划在我的库中使用此函数,该函数用于克服
MAX\u PATH
限制,因此无法使用标准的.NET函数。谢谢,Hans,我更新了我的问题,解释了我认为无法使用标准的.NET文件I/O类的原因。这就解决了问题,非常感谢,Hans。