WSH (Windows Script Host)を使い、言語はVBScriptで、特定のフォルダにあるファイルを別の特定のフォルダに移動させるプログラム(VBSファイル)を作り、そのプログラムをタスクスケジューラで、数分に一度チェックする形で動かすことにしました。


ところが、エラーのため移動できないファイルが出てきました。
そのファイルを調べてみると、MS-DOSファイル名が空であることが分かりました。
VBSでファイル名をチェックしたときに空であるために移動できないようです。
このファイルも移動できるようにするいい方法はないでしょうか?(VBScriptではなく別言語にする、あるいは、VBScriptでもこのようにすればうまく移動できる、など)

ちなみにファイルはMacintosh上で扱っているファイルです。ネットワークでMacintoshのマシンにあるファイルを、Windowsのマシンに移動します。エクスプローラではドラッグ&ドロップで問題なく移動できるので、何か手段はあると思うのですが…。
よろしくお願いします。

回答の条件
  • 1人10回まで
  • 登録:2007/11/19 10:12:09
  • 終了:2007/11/26 09:51:38

ベストアンサー

id:venzou No.9

venzou回答回数9ベストアンサー獲得回数12007/11/23 13:17:02

ポイント15pt

>インターネットエクスプローラではありません。


激しく勘違いしている部分がありましたので、復活します。(^^;


>移動元のマシンの中でドラッグ&ドロップはできますが、


この操作が、MACからの操作だと勘違いしていました。NAS内であれば、Windowsのエクスプローラで操作可能と言うことですね。


VBScriptで、NAS内でリネームを行うプログラムを書いてみました。


cFolderFromのファイルを、cFolderToへコピーします。コピーに失敗した場合は、リネームを行い、リネームしたファイルをコピーします。


ファイルのコピー終了後、エラーが無ければ、cFolderFromを削除します。


Unicodeのファイル名に対応するために、スクリプトはUnicodeで保存して下さい。ログファイルもUnicodeで出力しています。


Option Explicit

Const cFolderFrom = "\\ServerFrom\FolderTestFrom" ' 移動元のフォルダ
Const cFolderTo = "\\ServerTo\FolderTestTo" ' 移動先のフォルダ

Dim FSO
Dim LOG

test()

Sub test()
  Dim folder
  
  On Error Resume Next
  
  Set FSO = CreateObject("Scripting.FileSystemObject")
  
  If Not ( FSO.FolderExists(cFolderFrom) And FSO.FolderExists(cFolderTo) ) Then
    Exit Sub
  End If
  
  'Unicodeでログファイルを作ります。
  Set LOG = FSO.OpenTextFile(FSO.BuildPath(cFolderTo, "MoveFile.log"), 8, True, -1)

  Set folder = FSO.GetFolder(cFolderFrom)
  
  If allCopy(folder, cFolderTo) <> 0 Then
    LOG.WriteLien "エラーが発生、ファイルが残っています。"
  Else
    'エラーがない場合は移動元フォルダを削除
    Err.Clear
    FSO.DeleteFolder cFolderFrom
    If Err.Number <> 0 Then
      LOG.WriteLien "移動元フォルダの削除に失敗"
    End If
  End If
  LOG.Close
End Sub

'サブフォルダも含めファイルをコピー
Function allCopy(fld, folderTo)
  Dim obj
  Dim countError
  
  On Error Resume Next
  
  LOG.WriteLine fld.Path & " → " & folderTo
  countError = 0
  
  If Not FSO.FolderExists(folderTo) Then
    'フォルダが存在しない場合は作る
    FSO.CreateFolder folderTo
  End If
  
  For Each obj In fld.Files
    LOG.WriteLine obj.Path & " コピー開始"
    Err.Clear
    obj.Copy FSO.BuildPath(folderTo, obj.Name), True
    If Err.Number <> 0 Then
      'コピーに失敗した場合、リネームを試みる
      LOG.WriteLine obj.Path & " エラー発生、リネームします"
      Err.Clear
      obj.Name = FSO.GetTempName
      If Err.Number <> 0 Then
        'リネームも失敗
        LOG.WriteLine obj.Path & " リネーム失敗"
        countError = countError + 1
      Else
        'リネームに成功した場合は、コピーする
        LOG.WriteLine obj.Path & " リネーム成功"
        Err.Clear
        obj.Copy FSO.BuildPath(folderTo, obj.Name), True
        If Err.Number <> 0 Then
          'リネームしたファイルのコピーに失敗
          LOG.WriteLine obj.Path & " コピー失敗"
          countError = countError + 1
        Else
          'リネームしたファイルのコピー成功
          LOG.WriteLine obj.Path & " コピー完了"
        End If
      End If
    Else
      'コピー成功
      LOG.WriteLine obj.Path & " コピー完了"
    End If
  Next
  
  'サブフォルダを再起処理
  For Each obj In fld.SubFolders
    countError = countError + allCopy(obj, FSO.BuildPath(folderTo, obj.Name))
  Next
  'エラー数を返す
  allCopy = countError
End Function
id:tail_furry

ありがとうございます。

リネームに成功して、無事転送することができました。

ただ、このプログラムだと、転送元のフォルダ自体が消えてしまうため、

こちらで若干改造(といっても削除されたcFolderFromをCreateFolderするような簡単な改造)をして使用したいと思います。

どうもありがとうございました。

2007/11/26 09:50:05

その他の回答(8件)

id:venzou No.1

venzou回答回数9ベストアンサー獲得回数12007/11/19 13:44:55

ポイント16pt

現在どのような方法で移動させていますか?具体的なソースを教えて下さい。

特にエラーが出ている部分のソース分からないと、回答が難しいと思いますよ。


FileSystemObjectを使っているとすれば、FileオブジェクトのMoveメソッドでエラーが出ると言う事ですか?


もし、FileSystemObjectを使っていなければ、使ってみて下さい。

http://officetanaka.net/excel/vba/filesystemobject/index.htm

id:tail_furry

FileSystemObjectは使っています。

Move(MoveFile)は使っていません。CopyFileしてからDeleteFileをしています。(MoveFileだと、移動先にファイルがあった時に上書きできないため。上書きはしてもよいという条件です。)CopyFile(またはCopyFolder)が失敗します。

ちょっと長くなりますがソースを。(フォルダ名などは実際のものと変えてあります。あと、見やすいようにタブを全角スペース2つに置き換えてあります。)

Option Explicit


Const cFolderFrom = "\\ServerFrom\FolderTestFrom" ' 移動元のフォルダ

Const cFolderTo = "\\ServerTo\FolderTestTo" ' 移動先のフォルダ


Dim objWshShell

Dim objFS

Dim objLogFile

On Error Resume Next


'WshShellオブジェクトを生成する

Set objWshShell = WScript.CreateObject("WScript.Shell")


'FileSystemObjectを生成する

Set objFS = WScript.CreateObject("Scripting.FileSystemObject")


'引数があるかチェック

If not (objFS.FolderExists(cFolderFrom)) Then

  objWshShell.LogEvent 1, WScript.ScriptFullName & Chr(13) & Chr(10) & "送信元フォルダが未指定。"

  Call ExitFunction

ElseIf not (objFS.FolderExists(cFolderTo)) Then

  objWshShell.LogEvent 1, WScript.ScriptFullName & Chr(13) & Chr(10) & "送信先フォルダが未指定。"

  Call ExitFunction

Else

  ' MoveFileおよびMoveFolderでは上書きできないためCopyFileおよびCopyFolderを使っています

  Set objLogFile = objFS.OpenTextFile(objFS.BuildPath(cFolderTo, "MoveFile.log"), 8, True)

  Call WriteFilePathAll (objFS.GetFolder(cFolderFrom), objLogFile)

  Dim cntFile, cntFolder

  cntFile = 0

  cntFolder = 0

  If objFS.FileExists(objFS.BuildPath(cFolderFrom, "MoveFile.log")) then

    objFS.DeleteFile objFS.BuildPath(cFolderFrom, "MoveFile.log"), False

  End If

  Call CheckFileAndFolder (objFS.GetFolder(cFolderFrom), cntFile, cntFolder)

  If cntFile > 0 then

    objFS.CopyFile objFS.BuildPath(cFolderFrom, "*.*"),objFS.BuildPath(cFolderTo, "\"), True

    If Err.number = 0 then

      objFS.DeleteFile objFS.BuildPath(cFolderFrom, "*.*"), False

      If Err.number <> 0 then

        objLogFile.WriteLine Now & vbTab & "エラー【1】(" & Err.description & ")"

      End If

    Else

      objLogFile.WriteLine Now & vbTab & "エラー【2】(" & Err.description & ")"

    End If

  End If

  If cntFolder > 0 and Err.number = 0 then

    objFS.CopyFolder objFS.BuildPath(cFolderFrom, "*"),objFS.BuildPath(cFolderTo, "\"), True

    If Err.number = 0 then

      objFS.DeleteFolder objFS.BuildPath(cFolderFrom, "*"), False

      If Err.number <> 0 then

        objLogFile.WriteLine Now & vbTab & "エラー【3】(" & Err.description & ")"

      End If

    Else

      objLogFile.WriteLine Now & vbTab & "エラー【4】(" & Err.description & ")"

    End If

  End If

  objLogFile.Close

End If


'フォルダ内に含まれるファイルやフォルダを検索する(この関数はWeb上で見つけたものを改造したもの)

Sub WriteFilePathAll(ByVal objFolder, ByVal strm)

  ' ファイルの書き出し

  Dim objFile, files

  Set files = objFolder.Files

  For Each objFile In files

    strm.WriteLine Now & vbTab & objFile.Path

  Next

  ' サブフォルダに対して再帰処理

  Dim subfolders, objSub

  Set subfolders = objFolder.SubFolders

  For Each objSub In subfolders

    strm.WriteLine Now & vbTab & objSub.Path

    Call WriteFilePathAll( objSub, strm )

  Next

End Sub


Sub CheckFileAndFolder(ByVal objFolder, ByRef cntFile, ByRef cntFolder)

  ' ファイル

  Dim objFile, files

  Set files = objFolder.Files

  For Each objFile In files

    cntFile = cntFile + 1

  Next

  ' サブフォルダ

  Dim subfolders, objSub

  Set subfolders = objFolder.SubFolders

  For Each objSub In subfolders

    cntFolder = cntFolder + 1

  Next

End Sub

問題となっているファイルのみを移動元に置いた状態でプログラムを動かすと、エラー収集用のログには次のようなエラーが出力されます。この時、問題になっているファイルは、移動元には残っており、移動先にはありません。

移動先のフォルダの直下に問題のファイルがある場合には次のエラーです。

エラー【2】(ファイルの名前または数が不正です。)

移動先のフォルダにサブフォルダがあり、その下に問題のファイルがある場合には次のエラーです。

エラー【4】(ファイルの名前または数が不正です。)


問題になっているファイルの名前は「Icon・」(拡張子なし)です。「・」はたぶん文字が表示できなくて「・」になっているものと思われます。プロパティで開いたときに本来ファイル名を表示するテキストボックスが空になっています。サイズは0バイトです。


以上、よろしくお願いします。

2007/11/19 15:55:13
id:venzou No.2

venzou回答回数9ベストアンサー獲得回数12007/11/19 16:40:07

ポイント16pt

問題になっているファイルの名前は「Icon・」(拡張子なし)です。


確認ですが、このファイルはエクスプローラでドラッグ&ドロップで移動出来る状態ですよね?


FileSystemObjectのエラーの原因がよく分からないので、対処するのは難しそうですね。


方法を変えて、コマンドプロンプトからはコピーできますか?


例えば下記のような感じで、コピーした場合どうなります?

Dim objWS
Set objWS = WScript.CreateObject("WScript.Shell")
objWS.Run "cmd.exe /C ""copy """ & cFolderFrom & """ """ & cFolderTo & """ /y /z"""
id:tail_furry

はい、該当ファイルはエクスプローラでドラッグ&ドロップで移動出来る状態です。エクスプローラ上でのカット・コピー・ペーストもできます。


コマンドプロンプトから次のコマンドを実行してみました。(フォルダ名は実際のものと変えてあります。)

copy \\ServerFrom\FolderTestFrom \\ServerTo\FolderTestTo /Y /Z

結果は次のようになりました。

\\ServerFrom\FolderTestFrom\Icon
ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
    0 個のファイルをコピーしました。
2007/11/19 17:06:55
id:venzou No.3

venzou回答回数9ベストアンサー獲得回数12007/11/19 17:44:45

ポイント16pt

COPYがダメなら、XCOPYやMOVEもダメでしょうね


残る方法は、WindowsAPIかな?


VBScriptからは使えないので、VB(VBA)やVCなどでプログラミングが必要です。

面倒くさい上に、これでコピーできる保障もありませが・・・

http://www.winapi-database.com/File/File/index.html


あと思いつく対策は、コピーできそうなフリーウェアを探してみるとか。

http://www.vector.co.jp/vpack/filearea/win/util/file/copy/


あまりお役に立てませんでしたね。ごめんなさい。

id:tail_furry

フリーウェアのうち、移動の機能があって人気の高い次の5つのソフトを使って、該当ファイルの移動を指示してみました。

  • FCP(File Compare coPy) 2.1 … 「該当ファイルはありません。」のメッセージが表示され、該当ファイルを認識できない。
  • Zcopy for Win 1.23 … Move Error(123)のダイアログを表示。メッセージは「Icon ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。」
  • DirClone 1.21 … 「More than 1 faile fail to copy or remove」と「Copied 0 files, Removed 0 files」を表示。
  • Trapy 1.00 … 「2個のファイルの移動が完了しました」とダイアログが出るが、実際は移動されていない。また、移動先のフォルダを指定するダイアログが出るまでの処理が重い。
  • Just Bytes … 移動されたように見えるが実際は移動できていない。

うーん、フリーウェアを使ってもダメそうです。。。


VBやVCでのプログラミングが必要かな、とも思ったのですが、上で試したフリープログラムは全てexeファイルですから、おそらく、exeに変換する前はVBやVC++などで書かれていることが多いと思われるので、やっても無駄な気がします。(ただ、他の言語からもexeは作れますので、その言語で移動ができるというなら可能性はありますが。)


エクスプローラでのドラッグ&ドロップの移動が可能なので、それがどのように動いているか判れば手がかりがつかめるような気もします。

2007/11/20 10:35:37
id:venzou No.4

venzou回答回数9ベストアンサー獲得回数12007/11/20 13:16:57

ポイント16pt

エクスプローラでのドラッグ&ドロップの移動が可能なので、それがどのように動いているか判れば手がかりがつかめるような気もします。

そうですね。逆に、エクスプローラだけ操作可能なのが謎ですね。(^^;


VBやVCでプログラムを書く場合、APIを直接操作せず、言語に用意された標準の関数を使うのが普通です。APIを直接操作して、コピー可能か調べてみる価値はあるかも。


VBA用のAPIを使ったコピーのプログラムを書いてみました。(Excel2000で動作確認)


cFolderFrom フォルダのファイルを cFolderTo へコピーします。サブフォルダはコピーしません。


これで、エラーが出るか出ないか確認してみて下さい。


Option Explicit

Const INVALID_HANDLE_VALUE = &HFFFFFFFF          'エラーのとき
Const MAX_PATH = 256

Type FILETIME
    dwLowDateTime As Long                               '下位32ビット値
    dwHighDateTime As Long                              '上位32ビット値
End Type

Type WIN32_FIND_DATA
    dwFileAttributes As Long                            'ファイル属性(CreateFile関数を参照)
    ftCreationTime As FILETIME                          'ファイルの作成日時
    ftLastAccessTime As FILETIME                        'ファイルに最後にアクセスした日時
    ftLastWriteTime As FILETIME                         'ファイルに書き込んだ日時
    nFileSizeHigh As Long                               'ファイルサイズの上位32ビット値
    nFIleSizeLow As Long                                '同、下位32ビット値
    dwReserved0 As Long                                 '常に0
    dwReserved1 As Long                                 '常に0
    cFileName As String * MAX_PATH                      'ファイル名・ディレクトリ名
    cAlternate As String * 14                           'ファイル名
End Type

'dwFileAttributesの定数
Public Const FILE_ATTRIBUTE_ARCHIVE = &H20              'アーカイブ属性
Public Const FILE_ATTRIBUTE_COMPRESSED = &H800          '圧縮ファイル
Public Const FILE_ATTRIBUTE_DIRECTORY = &H10            'ディレクトリ属性
Public Const FILE_ATTRIBUTE_HIDDEN = &H2                '隠しファイル属性
Public Const FILE_ATTRIBUTE_NORMAL = &H80               'ファイル属性をもたない
Public Const FILE_ATTRIBUTE_READONLY = &H1              '読み込み専用属性
Public Const FILE_ATTRIBUTE_SYSTEM = &H4                'システムファイル属性
Public Const FILE_ATTRIBUTE_TEMPORARY = &H100           '一時ファイル属性


Declare Function CopyFile Lib "kernel32.dll" Alias "CopyFileA" _
    (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, _
     ByVal bFailIfExsts As Long) As Long

Declare Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileA" _
    (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long

Declare Function FindNextFile Lib "kernel32.dll" Alias "FindNextFileA" _
    (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long

Declare Function FindClose Lib "kernel32.dll" _
    (ByVal hFindFile As Long) As Long

Const cFolderFrom = "\\ServerFrom\FolderTestFrom" ' 移動元のフォルダ
Const cFolderTo = "\\ServerTo\FolderTestTo" ' 移動先のフォルダ

Public Sub test()

  Dim hFind As Long
  Dim FindData As WIN32_FIND_DATA
  Dim Msg As String
  Dim bResult As Long
  
  Dim FileName As String
  Dim ShortName As String
  
  '最初のファイル検索
  hFind = FindFirstFile(cFolderFrom & "\*.*", FindData)

  '検索失敗か?
  If hFind = INVALID_HANDLE_VALUE Then
    MsgBox "検索失敗"
    Exit Sub   '******** エラー終了 ********
  End If

  Do
    'ディレクトリは処理しない
    If (FindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = 0 Then
      
      'NULL文字を取り除く
      FileName = Trim(Left(FindData.cFileName, InStr(FindData.cFileName, vbNullChar) - 1))
      Debug.Print "ファイル名:" & FileName
  
      'コピーする(上書き許可)
      bResult = CopyFile(cFolderFrom & "\" & FindData.cFileName, cFolderTo & "\" & FindData.cFileName, 0)
      If bResult = 0 Then
        MsgBox "コピー失敗:" & FileName
      End If
    End If

    '次を検索
    bResult = FindNextFile(hFind, FindData)

  Loop While bResult <> 0

  '検索の終了
  FindClose hFind

End Sub


後、気になるのは、例のエラーが出るファイルは、MAC側から見るとどうなってます?

id:tail_furry

ありがとうございます。


動作させるマシンなんですが、Officeが入っていませんでした。わざわざソースをつけていただいたのに、申し訳ありません。


あと、動作させるマシン、移動元側のマシン、移動先側のマシンについて、次のことがわかりました。

  • 移動元のマシンは最初の聞き取りではMacintoshだったのですが、NAS(ネットワークアタッチトストレージ)だということが判りました。動作させるマシンのOSはWindows 2000 SP4、移動先のマシンはWindows 2003 Server SP2です。移動元のマシンに、複数のWindowsマシン、および、複数のMacintoshマシンから、ファイルが送信されてきて、移動元フォルダにたまっていきます。
  • カット&ペースト、あるいはドラッグ&ドロップができる、と聞いていたのですが、実際に試してみたところ、移動元のマシンの中でドラッグ&ドロップはできますが、移動元から移動先、および、移動元から動作させるマシンへのカット&ペースト、ドラッグ&ドロップはできませんでした。次のエラーになります。「Icon ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。」

以上の二点に関して、最初お伝えしていたのと条件が変わってしまいました。申し訳ありません。

  • 問題となっているファイル「Icon・」は、Macintosh側からNASに渡されてきたファイルです。

例のエラーが出るファイルは、MAC側から渡されてきているので、MACでは問題なく扱えています。NAS上では見ることができませんが、MAC側から渡すことができてWinのエクスプローラ上からも見えている状態です。

2007/11/20 14:56:44
id:venzou No.5

venzou回答回数9ベストアンサー獲得回数12007/11/20 14:34:44

ポイント16pt

先ほどのVBAのプログラムですが、ファイル名にUnicodeが含まれているだけで、エラーになりました。これでチェックしても意味無さそうです。失礼しました。



移動元から移動先、および、移動元から動作させるマシンへのカット&ペースト、ドラッグ&ドロップはできませんでした。


こういう事なら、ファイル名にWindowsで使用できない文字が含まれているだけかも知れませんね。

Windows側からは操作できないと思うので、MAC側で対処するしかないのでは?


とりあえず見つけた、MAC用のファイル名をチェックするソフト

非互換ネームcheck

http://www.vector.co.jp/soft/mac/util/se300547.html


探せばもっと便利なソフトがあるかも。

id:tail_furry

ちょっとごたごたしてしまいすみません。

移動が目的のため、ファイル名のチェックだけではダメです。

問題のあるファイルの名前を変更してから移動したらうまくできるのでは、とか考えているのですが、今までの状況から言うとWinマシンからファイル名をコマンドプロンプトでチェックできないために変更ができるかどうか疑問です。

あ、あと、回答可能回数を増やしました。

2007/11/20 15:00:32
id:venzou No.6

venzou回答回数9ベストアンサー獲得回数12007/11/20 16:17:02

ポイント15pt

先ほどは急いで回答を書いたので、もう一度まとめます。


最初の前提条件が異なっていたので、2~4の回答は無視して下さい。

結局の所、Windowsでのコピーは一度も成功してないので、不可能である可能性が高いと思います。


推測ですが、MACの機種依存文字がファイル名に使われているのでは?

MAC側で、ファイル名がどうなっているのか、もう一度確認してみて下さい。

http://bird.zero.ad.jp/~zar26542/keio/let_table/for_win_main.htm...


Winマシンからファイル名をコマンドプロンプトでチェックできないために変更ができるかどうか疑問です。

仰るとおり、ファイル名に不正な文字が使われている場合、Windowsからの変更は不可能かもしれません。


まずは、原因特定の為にファイル名のチェックをして下さい。

id:tail_furry

OS10から、NAS上にあるファイルをチェックしたところ、

「Icon

↑改行みたいなのが入っていて、特定の文字としては見えない

というファイル名でした。


「ファイル名に改行」でちょっと調べてみたら、どうもこれが怪しいようです。

2007/11/20 17:07:49
id:venzou No.7

venzou回答回数9ベストアンサー獲得回数12007/11/20 19:56:02

ポイント15pt

NAS上のファイルも既に文字化けしているのでは?(^^;


そもそものコピー元のMACで不正な文字を使わない様にするのがベストだと思います。ファイル名の命名規則を決めて、それに従ってもらう事は出来ませんか?


出来てしまった、不正なファイル名はMACで改名するしかないでしょう。この処理とWindows側のスクリプトを同期させるのは困難だと思います。

id:tail_furry

ちょっと調べてみましたが、問題になっているファイルは、「カスタムアイコン」というらしいです。

おたすけチップス 第2回 WindowsとMacを共存させたい!! | 大塚商会

フォルダに対してアイコンを付与した場合は、そのフォルダの直下に『Icon』という不可視ファイルができます。ただできるだけなら良いのですが、このファイルの最大の問題はファイル名にMacの改行コードが入っていることです。場合によってはこれがシステム障害の原因にもなり兼ねませんので注意が必要です。

Windows ネットワークとの相性 - [Mac OSの使い方]All About

もう一つ Mac OS では特殊な仕組みがあります。「カスタムアイコン」です。アプリケーションや、書類データにアイコンをつける時は、「リソースフォーク」としてファイルに付加されますが、フォルダにカスタムアイコンをつけた場合「Icon」という不可視のファイルがフォルダ直下にできてしまいます。

このファイルがWindows 環境で問題なのは、ファイル名の最後に“Mac の改行文字コード”が入っている点です。

これらのページによると、Iconファイルは自動的にできるようですので、ファイルの命名規約でどうこうできるものではないようです。


Mac→Winへのファイル交換時「Icon」ファイルを外すには? - 教えて!goo

似たような質問が「教えて!goo」にあるのを見つけましたが、今回やりたいことと若干違います…。


>不正なファイル名はMACで改名するしかないでしょう。

ただ、Win側のエクスプローラを使って、NASのフォルダ上にある問題のファイルのコピーや削除、改名はできちゃうんですよね。ということは、Windows側でも、ファイル名の変更など、何か手段があるような気はしますが…。(APIを使ってファイル名を変更し、その後移動、とか。)

とりあえず、MAC側でNASのフォルダを監視してカスタムアイコン(ないし、リソースフォーク)を自動的に削除することができないか調べてみます。

2007/11/21 11:40:42
id:venzou No.8

venzou回答回数9ベストアンサー獲得回数12007/11/21 15:09:27

ポイント15pt

>ただ、Win側のエクスプローラを使って、NASのフォルダ上にある問題のファイルのコピーや削除、改名はできちゃうんですよね。


このエクスプローラと言うのはブラウザの事ですか?

ブラウザで開いた管理画面か何かで、操作可能と言う意味でしょうか?


そうだとすれば、ブラウザ(HTTP)経由で操作可能かも知れませんね。VBScriptからブラウザを操作出来ますので。しかし、管理画面の詳細が分からないと、プログラムは書けません。とりあえずNASの型番など書いて頂いた方が良いかも。詳しい方から回答があるかもしれません。


もう1つ気になるのは、Iconファイルはコピー先のWinodwsには不要ですよね? 強制的に削除するとか、削除出来ない場合はそのままコピー元に残すとか。そういう対応は不可ですか?



>これらのページによると、Iconファイルは自動的にできるようですので、ファイルの命名規約でどうこうできるものではないようです。


では、カスタムアイコンを作らない、と言うのを規則に入れるとか。


詳しい状況が分からないのですが、NASでファイル共有しているのであれば、同じ会社の社員とかでは? 共有フォルダにファイルをコピーするのですから、何らかのルールは必要だと思いますが・・・。コピー元のMACユーザは、そういう制限が掛けられない相手なのでしょうか?


MACとWindowsではファイル名に使える文字が違いますので、「ルール無し」では、不正な文字を使ったファイルが、Icon以外にも作られる可能性があります。その場合どう対処するか? そのままのファイル名ではWinodwsに保存できません。改名出来たとしても、元のファイル名の情報は失われます。この辺りの仕様をも少し煮詰めた方が良いのでは?




VBScriptの問題だと思って回答を始めて、ずるずると回答を続けましたが、MACやNASに関しては詳しくないので、私はここでリタイヤします。自分の回答を振り返ってみると、役に立つ情報はほとんど無いですね。問題点のヒアリングに少し貢献した程度かな。では、がんばって下さい。

id:tail_furry

エクスプローラは、ファイル一覧とかを見る時のエクスプローラです。スタートで右クリックしたときの選択肢の中にある、よく使うやつです。インターネットエクスプローラではありません。

Iconファイルはコピー先のWindowsには不要です。強制的に削除してもいいと聞いています。

カスタムアイコンを作らない、と言うのを規則に入れることはできないそうです。


ボクもMACに詳しくないので、WIN内で解決できる予定が、かなり訳がわからなくなっています。最初の質問内容と中身が少し変わってきたので、いったん質問を締め切って立て直すことも考えています。

でも、venzouさんのおかげで、かなり問題の元になっている箇所まで近づけたと思います。今まで回答していただいてどうもありがとうございました。

2007/11/21 16:21:22
id:venzou No.9

venzou回答回数9ベストアンサー獲得回数12007/11/23 13:17:02ここでベストアンサー

ポイント15pt

>インターネットエクスプローラではありません。


激しく勘違いしている部分がありましたので、復活します。(^^;


>移動元のマシンの中でドラッグ&ドロップはできますが、


この操作が、MACからの操作だと勘違いしていました。NAS内であれば、Windowsのエクスプローラで操作可能と言うことですね。


VBScriptで、NAS内でリネームを行うプログラムを書いてみました。


cFolderFromのファイルを、cFolderToへコピーします。コピーに失敗した場合は、リネームを行い、リネームしたファイルをコピーします。


ファイルのコピー終了後、エラーが無ければ、cFolderFromを削除します。


Unicodeのファイル名に対応するために、スクリプトはUnicodeで保存して下さい。ログファイルもUnicodeで出力しています。


Option Explicit

Const cFolderFrom = "\\ServerFrom\FolderTestFrom" ' 移動元のフォルダ
Const cFolderTo = "\\ServerTo\FolderTestTo" ' 移動先のフォルダ

Dim FSO
Dim LOG

test()

Sub test()
  Dim folder
  
  On Error Resume Next
  
  Set FSO = CreateObject("Scripting.FileSystemObject")
  
  If Not ( FSO.FolderExists(cFolderFrom) And FSO.FolderExists(cFolderTo) ) Then
    Exit Sub
  End If
  
  'Unicodeでログファイルを作ります。
  Set LOG = FSO.OpenTextFile(FSO.BuildPath(cFolderTo, "MoveFile.log"), 8, True, -1)

  Set folder = FSO.GetFolder(cFolderFrom)
  
  If allCopy(folder, cFolderTo) <> 0 Then
    LOG.WriteLien "エラーが発生、ファイルが残っています。"
  Else
    'エラーがない場合は移動元フォルダを削除
    Err.Clear
    FSO.DeleteFolder cFolderFrom
    If Err.Number <> 0 Then
      LOG.WriteLien "移動元フォルダの削除に失敗"
    End If
  End If
  LOG.Close
End Sub

'サブフォルダも含めファイルをコピー
Function allCopy(fld, folderTo)
  Dim obj
  Dim countError
  
  On Error Resume Next
  
  LOG.WriteLine fld.Path & " → " & folderTo
  countError = 0
  
  If Not FSO.FolderExists(folderTo) Then
    'フォルダが存在しない場合は作る
    FSO.CreateFolder folderTo
  End If
  
  For Each obj In fld.Files
    LOG.WriteLine obj.Path & " コピー開始"
    Err.Clear
    obj.Copy FSO.BuildPath(folderTo, obj.Name), True
    If Err.Number <> 0 Then
      'コピーに失敗した場合、リネームを試みる
      LOG.WriteLine obj.Path & " エラー発生、リネームします"
      Err.Clear
      obj.Name = FSO.GetTempName
      If Err.Number <> 0 Then
        'リネームも失敗
        LOG.WriteLine obj.Path & " リネーム失敗"
        countError = countError + 1
      Else
        'リネームに成功した場合は、コピーする
        LOG.WriteLine obj.Path & " リネーム成功"
        Err.Clear
        obj.Copy FSO.BuildPath(folderTo, obj.Name), True
        If Err.Number <> 0 Then
          'リネームしたファイルのコピーに失敗
          LOG.WriteLine obj.Path & " コピー失敗"
          countError = countError + 1
        Else
          'リネームしたファイルのコピー成功
          LOG.WriteLine obj.Path & " コピー完了"
        End If
      End If
    Else
      'コピー成功
      LOG.WriteLine obj.Path & " コピー完了"
    End If
  Next
  
  'サブフォルダを再起処理
  For Each obj In fld.SubFolders
    countError = countError + allCopy(obj, FSO.BuildPath(folderTo, obj.Name))
  Next
  'エラー数を返す
  allCopy = countError
End Function
id:tail_furry

ありがとうございます。

リネームに成功して、無事転送することができました。

ただ、このプログラムだと、転送元のフォルダ自体が消えてしまうため、

こちらで若干改造(といっても削除されたcFolderFromをCreateFolderするような簡単な改造)をして使用したいと思います。

どうもありがとうございました。

2007/11/26 09:50:05
  • id:cx20
    試してないのでコメント欄にて。

    不正なファイル名でファイル操作ができない場合は、
    「 \\?\ドライブ名\パス名\ファイル名」
    と表記することでファイル操作ができる場合があります。
    例)
    「copy \\ServerFrom\FolderTestFrom \\ServerTo\FolderTestTo /Y /Z」
      ↓
    「NET USE X: \\ServerFrom\FolderTestFrom」
    「NET USE Y: \\ServerTo\FolderTestTo」
    「COPY \\?\X:\*.* \\?\Y:\ /Y /Z」
    (「\\?\~」の表記は FileSystemObject では使えなかった気がします。コマンドプロンプト(またはバッチファイル)で指定してください。)

    <参考情報>
    ■ @IT:Windows TIPS -- Tips:不正な名前のファイルを削除する
    http://www.atmarkit.co.jp/fwin2k/win2ktips/526badfile/badfile.html
    ■ NTFS ファイル システム上のファイルまたはフォルダを削除できない
    http://support.microsoft.com/kb/320081/ja
    ■ 禁則文字のファイル名
    http://q.hatena.ne.jp/1193380269
    ■ MacOSXの大量のファイル(数十万ファイル程度)をwindowsにコピーするツール
    http://q.hatena.ne.jp/1193650851
  • id:tail_furry
    >cx20さん
    なるほど、禁則文字の可能性を考えていませんでした。

    ただ、実際にコマンドプロンプトで試してみた結果は次のとおりです。
    (フォルダ名は実際と変えてあります)
    >|
    copy \\?\X:\hogehoge\*.* \\?\Y:\poipoi\ /y /z
    \\?\X:\hogehoge\Icon
    ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
        0 個のファイルをコピーしました。
    |<
  • id:venzou
    venzouです。

    >現在、動作させるマシンにOfficeをインストールしています。もう少しお待ちください。

    あぁ・・ごめんなさい。
    先ほどの回答に書きましたが、そこまでして実行して頂く価値はないです。
    間に合わなかったかな。orz
  • id:tail_furry
    すみません、インストールしようとしたのですが、共有マシンのために再起動できる時間帯に制限があり、翌日以降にしてといわれてしまいました。
    その後、VBAプログラムがエラーとのことでしたので、インストールについてはなくなりました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません