3

SetFileTimeC#プログラムから関数を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
);

2番目、3番目、4番目のパラメーターについては、オプションである可能性があることを示しています。

アプリケーションがこの情報を変更する必要がない場合、このパラメーターはNULLにすることができます。

そして、これはまさに私がやりたいことです。3つの日時値のうちの1つだけを渡し、他の値をに設定しnullます。

これをP/Invoke署名で表現する方法に完全に迷っています。

したがって、私の質問は次のとおりです。

関数パラメーターに渡すnullことができる正しいP/Invokeシグニチャー(または正しい呼び出し方法)はどれですか?SetFileTime

編集1:

FileInfoクラスにはすでにファイル時間を設定するための書き込み可能なプロパティが用意されているので、クラスを使用する代わりに自分でそれを行う理由を尋ねられるかもしれません。

その理由は、制限を克服するために使用されるロングパスライブラリでこの関数を使用することを計画しているMAX_PATHため、標準の.NET関数を使用できないためです。

したがってFileInfo、残念ながら、クラスを使用することはできません。

編集2:

私はハンスによって提案された解決策を使用してそれを解決しました。その後、関数の下に次のようなユーザー投稿のコメントが見つかりました。

さらに、パラメーターの1つにゼロ値を指定すると、NULLを指定するのと同じ効果があります。

私はこれが本当かどうかを確認しませんでしたが、それでも私と同様の要件を持っている他の人にとっては選択肢かもしれません。

4

1 に答える 1

3

実行時に常にnull以外のポインターを生成するC#のrefキーワードを使用してモデル化することはできません。実際に宣言するlong*必要があります。これには、安全でないキーワードを使用する必要があります。引数を&local-var構文とともに渡すか、を使用しますnull

安全でない使用を回避するための1つの可能なトリックは、DllImportのEntryPointプロパティを使用してそれらすべてをSetFileTime()にマップし、異なる名前でこのメソッドの3つのバージョンを宣言することです。IntPtrとして設定したくないものを指定して、reflongとして設定したいIntPtr.Zeroを渡すことができるようにします。例えば:

[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について繰り返します。

于 2012-07-04T13:34:58.977 に答える