VB.NETでファイル削除して、ごみ箱に送るには?

解決


yuu  2003-10-29 21:08:20  No: 109539

VB.NETでファイル削除して、ごみ箱に送りたいと思うのですが、
System.IO.File.Delete("ファイルパス")ですと、ごみ箱に残りませんでした?

VB6.0のころは、APIのSHFileOperationAを使ってやっていたので、それをつかえばと思いやってみたのですが、(以下ソース)

    Private Structure SHFILEOPSTRUCT
        Public hWnd As IntPtr
        Public wFunc As Integer
        <MarshalAs(UnmanagedType.LPStr)> Public pFrom As String
        <MarshalAs(UnmanagedType.LPStr)> Public pTo As String
        Public fFlags As Integer
        Public fAnyOperationsAborted As Boolean
        Public hNameMappings As Integer
        <MarshalAs(UnmanagedType.LPStr)> Public lpszProgressTitle As String
    End Structure

    Private Declare Function SHFileOperation Lib "shell32" _
        Alias "SHFileOperationA" (ByRef lpFileOp As SHFILEOPSTRUCT) As Integer
    Public Const FO_MOVE = &H1                           'ファイルの移動(pFrom から pTo へ移動)
    Public Const FO_COPY = &H2                           'ファイルのコピー(pFrom から pTo へコピー)
    Public Const FO_DELETE = &H3                         'ファイルの削除(pFrom を削除 pTo は無視されます)
    Public Const FO_RENAME = &H4                         'ファイル名変更(pFrom の名前変更)

    Public Const FOF_MULTIDESTFILES = &H1                '受け側に複数のファイルを指定
    Public Const FOF_CONFIRMMOUSE = &H2                  '処理なし
    Public Const FOF_SILENT = &H4                        '進捗ダイアログボックス非表示
    Public Const FOF_RENAMEONCOLLISION = &H8             '同一ファイル名の場合名前変更(コピ〜○○○)
    Public Const FOF_NOCONFIRMATION = &H10               '確認操作なし
    Public Const FOF_WANTMAPPINGHANDLE = &H20            'マッピングハンドル取得
    Public Const FOF_ALLOWUNDO = &H40                    '削除の際ごみ箱に移動する
    Public Const FOF_FILESONLY = &H80                    'ファイルのみを対象(*.* が指定された時)
    Public Const FOF_NOCONFIRMMKDIR = &H200              'フォルダ作成確認なし
    Public Const FOF_SIMPLEPROGRESS = &H100              '進捗ダイアログボックス表示

    Public Function FileDelete(ByVal hwnd As IntPtr, ByVal FileName As String) As Integer

        Dim SFO As New SHFILEOPSTRUCT

        SFO.hWnd = hwnd
        SFO.wFunc = FO_DELETE
        SFO.pFrom = "D:\test\新規テキスト文書.txt"
        SFO.fFlags = FOF_ALLOWUNDO

        FileDelete = SHFileOperation(SFO)

        If FileDelete <> 0 Then
            If FileDelete <> 7 Then
                MsgBox("ファイル削除に失敗しました。")
            End If
        End If
    End Function

"D:\test\新規テキスト文書.txt"は確かに存在しているのですが、
ファイルまたはフォルダの削除エラー
ファイルを削除できません。送り側のファイルまたはディスクから読み取れません。というエラーがでてしまいます。

なぜでしょうか?


魔界の仮面弁士  2003-10-29 21:57:12  No: 109540

> Private Structure SHFILEOPSTRUCT
APIに構造体を渡すときは、StructLayoutAttribute属性クラスも指定しましょう。
特に、Packフィールドの設定は非常に重要です。

.NETの既定のパッキングサイズは 8 ですが、多くのAPIは、4バイトのアライメントを期待して設計されています。
ただし、SHFILEOPSTRUCT は 1バイトアライメントで設計されていますので、

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)>
が必要になります。

# ちなみに、VB6のユーザー定義型は、Pack=4に相当しています。

> Public Const FO_MOVE = &H1
『As データ型』の記述が抜けていますよ。(Option Strict On時に警告されます)


yuu  2003-10-29 22:07:02  No: 109541

指摘の行を追加後、ためしましたら、見事動きました。
本当にありがとうございます。

VB6.0からVB.NETに移行し、まだまだわからないことばかりで、ご迷惑をかけるかもしれませんが、よろしくお願いいたします。

PS.  APIは、まだまだ必須ですね。


魔界の仮面弁士  2003-10-29 22:09:06  No: 109542

# あう、書きかけで送信してしまった…。

ただし、これらの事は直接の問題では無いと思います。
(Pack=8だとしても、pToまでのメンバについては影響が無いため)

考えられる原因としては、ファイルをロックしているか、もしくは
ファイルが存在しないか、のいずれかのような気がします。

> "D:\test\新規テキスト文書.txt"は確かに存在しているのですが、
『テキスト』という4文字の、全角と半角を間違えているという事はありませんか?


yuu  2003-10-30 01:53:41  No: 109543

すみません。いろいろためしたのでが、
エラーが出るファイルとエラーなしで消えるファイルがあるようです。

>考えられる原因としては、ファイルをロックしているか、もしくは
>ファイルが存在しないか、のいずれかのような気がします。

これも確かめてみましたが、確かにありますし。

構造体の宣言や、APIの呼び出しに問題があるのでしょうか?
   Private Structure SHFILEOPSTRUCT
        Public hWnd As IntPtr
        Public wFunc As Integer
        <MarshalAs(UnmanagedType.LPStr)> Public pFrom As String
        <MarshalAs(UnmanagedType.LPStr)> Public pTo As String
        Public fFlags As Integer
        Public fAnyOperationsAborted As Boolean
        Public hNameMappings As Integer
        <MarshalAs(UnmanagedType.LPStr)> Public lpszProgressTitle As String
    End Structure


yuu  2003-10-30 17:17:29  No: 109544

SFO.pFrom = "D:\test\新規テキスト文書.txt"
この部分の指定が間違っておりました。大変申し訳ありませんでした。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加