xcopy
にするファイルと同じディレクトリにあるバッチファイルがあります。しかし、何らかの理由でファイルが見つかりません。
現在のディレクトリは常にバッチファイルが置かれている場所だと思いました。
管理者としてバッチファイルを実行します。これは、Windows 7 64ビットデスクトップコンピューターで発生します。
バッチファイル:
@ECHO OFF
XCOPY /y "File1.txt" "File2.txt"
PAUSE
エラー:
File not found - File1.txt
0 File(s) copied
コンテキストメニュー項目でバッチファイルを開始するときに現在の作業ディレクトリがどのディレクトリであるか(== --- ==)管理者として実行はユーザーアカウント制御によって異なります現在のユーザーの(UAC)設定。
これは、次の小さなバッチファイルC:\Temp\Test.bat
で説明できます。
@echo Current directory is: %CD%
@pause
で選択した場合ユーザーアカウント制御設定
デフォルト-プログラムがコンピューターに変更を加えようとしたときにのみ通知する
- Windowsの設定を変更しても通知しない
管理者として実行を使用すると、Windowsはレジストリキーを使用します
HKEY_CLASSES_ROOT\batfile\Shell\runasuser\command
このレジストリキーには、バッチファイルを実行するためのデフォルトの文字列は含まれていません。代わりに、CLSID {ea72d00e-4960-42fa-ba92-7792a7944c1d}
を含む文字列値DelegateExecute
があります。
結果は、タイトルユーザーアカウント制御とテキストを含むダイアログウィンドウを開きます。
次のプログラムがこのコンピュータに変更を加えることを許可しますか?
プログラム名:Windows Command Processor
確認済み発行元:Microsoft Windows
ユーザーによる確認後、Windowsはコマンドライン RunAs で使用する場合と同様に、一時的に新しいユーザーセッションを開きます。
この新しいユーザーセッションでは、現在の作業ディレクトリは%SystemRoot%\System32
です。デフォルトのキー文字列を使用して、Windowsレジストリで定義されたコマンドを実行します。
HKEY_CLASSES_ROOT\batfile\Shell\runas\command
それは:
%SystemRoot%\System32\cmd.exe /C "%1" %*
したがって、コンソールウィンドウはタイトルC:\ Windows\System32\cmd.exeと2行で開かれます。
Current directory is: C:\Windows\System32
Press any key to continue . . .
いずれかのキーを押すと、バッチ実行が終了してcmd.exe
が終了し、ユーザーセッションが終了します。
ただし、ユーザーアカウント制御設定で選択した場合
いつ通知しないでください
プログラムがソフトウェアをインストールするか、コンピューターに変更を加えようとする
Windowsの設定を変更した
ユーザーがすでに昇格した権限を持っているため、動作は異なります。
現在、Windowsはコマンドを直接使用します
%SystemRoot%\System32\cmd.exe /C "%1" %*
キーのデフォルト文字列に従って
HKEY_CLASSES_ROOT\batfile\Shell\runas\command
現在のユーザーセッション。
結果は、タイトルもC:\ Windows\System32\cmd.exeのコンソールウィンドウを開きますが、ウィンドウには次のように表示されます。
Current directory is: C:\Temp
Press any key to continue . . .
この場合、別のユーザーセッションに切り替える必要がなかったため、親ファイルの現在の作業ディレクトリ(デスクトップとしてのWindowsエクスプローラー)がバッチファイルの実行に使用されます。
[〜#〜] pa [〜#〜] は彼の回答にすでに2つの可能な解決策を投稿していますが、これをここで少し改善して(二重引用符で囲んだディレクトリを含むpushd
)および3つ目を追加します。
pushdおよびpopdを使用して、現在のディレクトリをバッチファイルのディレクトリに変更します。
pushd "%~dp0"
%SystemRoot%\System32\xcopy.exe "File1.txt" "File2.txt" /Y
popd
これはUNCパスでも機能します。これがUNCパスでも機能する理由については、コマンドプロンプトウィンドウpushd /?
で実行してください。
ソースと宛先の仕様でバッチファイルのディレクトリを使用:
%SystemRoot%\System32\xcopy.exe "%~dp0File1.txt" "%~dp0File2.txt" /Y
cdを使用して、作業ディレクトリをバッチファイルのディレクトリに変更します。
cd /D "%~dp0"
%SystemRoot%\System32\xcopy.exe "File1.txt" "File2.txt" /Y
コマンドインタープリターcmdはデフォルトで現在のディレクトリとしてUNCパスをサポートしないため、これはUNCパスでは機能しません。たとえば、 CMDは詳細については、現在のディレクトリとしてUNCパスをサポートしない 。
エラーメッセージは非常に自明です。ファイル file1.txt
見つかりません。
ファイル名には絶対パスが含まれていないため、システムは現在のディレクトリでそのファイルを見つけようとします。現在のディレクトリにはこのファイルが含まれていません。
あなたの誤解は、現在のディレクトリではない batファイルを含むディレクトリだということです。これらは2つの無関係な概念です。
この2つのコマンドをbatファイルに追加すると、簡単に確認できます
echo BAT directory is %~dp0
echo Current directory is %CD%
あなたはそれらが異なることに気付くことができ、最後のバックスラッシュが追加されるかどうかに微妙な違いがあることに気づくでしょう。
したがって、この問題に対処するには本質的に2つの方法があります
予想されるディレクトリと一致するように現在のディレクトリを変更するか、
pushd %~dp0
XCOPY /y "File1.txt" "File2.txt"
popd
またはコマンドでフルパスを指定します
XCOPY /y "%~dp0File1.txt" "%~dp0File2.txt"
完全性と曖昧さのために、Windows 8.1で動作することが確認されており、文書化された機能に依存しているため、他の場所で動作することが予想される別の回避策を追加します。
runas
コマンド定義キーを変更できますHKEY_CLASSES_ROOT\batfile\Shell\runas\command
およびHKEY_CLASSES_ROOT\cmdfile\Shell\runas\command
に
%SystemRoot%\System32\cmd.exe /S /C "(for %%G in (%1) do cd /D "%%~dpG") & "%1"" %*
これにより、bat
動詞、または「管理者として実行」メニューエントリをそれぞれ使用して開始すると、その包含ディレクトリでcmd
またはrunas
ファイルが開始されます。
元のコマンドへの追加が正確に行うこと:
cmd /S
は、コマンド文字列の/C
の後の最初と最後の(二重)引用符を取り除きますfor %%G in (%1) do
は、単一のエントリである%1
引数を列挙し、ループ本体の%%G
として展開できるようにします。手紙は任意ですが、一部は「予約」される場合があります%%~dpG
はd riveおよびp ath of %%G
に展開され、〜チルダは引用符を取り除きますif存在するため、明示的に追加し直しますcd /D
はd riveとディレクトリの両方をその引数に変更し、最後に&
は、最初のコマンドの成功に関係なく、2番目のコマンド"%1" %*
を実行します。UNCパスもサポートするpushd
を使用できますが、popd
がsystem32
ディレクトリにスクリプトをランディングしますが、私が好きな動作ではありません。
exefile
エントリでもこれを行うことができる必要がありますが、率直に言って、私はシステムでこれを試みるよりも、一貫性がない状態で暮らしたい、エラーが発生すると、多くの問題が発生する可能性があります。
お使いのオペレーティングシステムのセキュリティメカニズムを打ち負かしてください:)