Skip to content

Instantly share code, notes, and snippets.

@souri-t
Created June 3, 2025 22:15
Show Gist options
  • Save souri-t/0677a86ea4e77afa350194af583bfeb6 to your computer and use it in GitHub Desktop.
Save souri-t/0677a86ea4e77afa350194af583bfeb6 to your computer and use it in GitHub Desktop.
@echo off
setlocal enabledelayedexpansion
REM --- 設定項目 ---
REM コピー元 (Sourceフォルダ) のパス
set "SOURCE_FOLDER=C:\Path\To\Your\SourceFolder"
REM コピー先 (Destinationフォルダ) のパス、クリーンアップ対象
set "DESTINATION_FOLDER=C:\Path\To\Your\DestinationFolder"
REM Destinationフォルダで保持し、Sourceフォルダからのコピー時に除外するファイル (スペース区切りで複数指定)
REM 前提1: これらのファイルは DESTINATION_FOLDER 直下に初期状態で存在することを想定しています (一時退避のため)。
REM 前提2: これらのファイルは SOURCE_FOLDER 直下にも存在する可能性があり、robocopyでのコピー対象から除外します。
set "CONFIG_FILES=web.config appsettings.json"
REM 一時退避フォルダ (システムの一時フォルダ内に作成)
set "TEMP_DEPLOY_DIR=%TEMP%\WebAppDeployTemp"
REM --- 初期チェック ---
if not exist "%SOURCE_FOLDER%" (
echo エラー: Sourceフォルダ "%SOURCE_FOLDER%" が見つかりません。
goto :eof
)
if not exist "%DESTINATION_FOLDER%" (
echo エラー: Destinationフォルダ "%DESTINATION_FOLDER%" が見つかりません。
goto :eof
)
REM --- 確認 ---
echo === 設定内容 ===
echo コピー元 (Sourceフォルダ) : %SOURCE_FOLDER%
echo コピー先 (Destinationフォルダ) : %DESTINATION_FOLDER%
echo Destinationで保持/Sourceから除外するファイル: %CONFIG_FILES%
echo.
echo 処理を開始します...
echo.
REM --- 一時退避フォルダの準備 ---
if exist "%TEMP_DEPLOY_DIR%" (
echo 一時フォルダ "%TEMP_DEPLOY_DIR%" をクリーンアップします。
rd /s /q "%TEMP_DEPLOY_DIR%"
)
mkdir "%TEMP_DEPLOY_DIR%"
if not exist "%TEMP_DEPLOY_DIR%" (
echo エラー: 一時フォルダ "%TEMP_DEPLOY_DIR%" を作成できませんでした。
goto :eof
)
REM --- 1. Destinationフォルダから保持するファイルを一時退避 ---
REM (前提1に基づき、CONFIG_FILES に指定されたファイルは必ず DESTINATION_FOLDER 直下に存在するものとして処理します)
echo === Destinationフォルダの指定ファイルを一時退避 ===
for %%c in (%CONFIG_FILES%) do (
echo "%DESTINATION_FOLDER%\%%c" を退避中...
move /y "%DESTINATION_FOLDER%\%%c" "%TEMP_DEPLOY_DIR%\%%c" > nul
)
echo.
REM --- 2. Destinationフォルダの内容を全て削除 (サブフォルダ含む) ---
echo === Destinationフォルダ "%DESTINATION_FOLDER%" の内容をクリーンアップ ===
pushd "%DESTINATION_FOLDER%"
if errorlevel 1 (
echo エラー: Destinationフォルダ "%DESTINATION_FOLDER%" にアクセスできません。退避ファイルを戻します。
goto :restore_and_exit
)
echo ファイル削除中 (サブフォルダ含む)...
del *.* /s /q /f > nul 2>nul
echo フォルダ削除中...
for /d %%d in (*) do (
rd /s /q "%%d"
)
popd
echo Destinationフォルダのクリーンアップ完了。
echo.
REM --- 3. 退避したファイルをDestinationフォルダに戻す ---
echo === 退避したファイルをDestinationフォルダに戻します ===
for %%c in (%CONFIG_FILES%) do (
REM 退避先にファイルが存在する場合のみ戻す (退避処理でエラーが起きなかった前提)
if exist "%TEMP_DEPLOY_DIR%\%%c" (
echo "%%c" を "%DESTINATION_FOLDER%" に戻し中...
move /y "%TEMP_DEPLOY_DIR%\%%c" "%DESTINATION_FOLDER%\%%c" > nul
)
)
echo.
REM --- 4. SourceフォルダからDestinationフォルダへファイルコピー (指定ファイル除外) ---
echo === SourceフォルダからDestinationフォルダへコピー (除外あり) ===
echo コピー元: %SOURCE_FOLDER%
echo コピー先: %DESTINATION_FOLDER%
REM robocopyで除外するファイル名のリストを作成 (スペース区切り、各ファイル名は引用符で囲む)
set "ROBOCOPY_EXCLUDE_LIST="
for %%c in (%CONFIG_FILES%) do (
set "ROBOCOPY_EXCLUDE_LIST=!ROBOCOPY_EXCLUDE_LIST! "%%c""
)
echo 除外 : %CONFIG_FILES%
REM /XF オプションに組み立てたファイルリストを渡す
robocopy "%SOURCE_FOLDER%" "%DESTINATION_FOLDER%" /E /XF %ROBOCOPY_EXCLUDE_LIST% /NFL /NDL /NJH /NJS
if errorlevel 8 (
echo 警告: ROBOCOPYでいくつかのファイルがコピーに失敗しました。(エラーコード: %errorlevel%)
) else if errorlevel 1 (
echo 情報: ROBOCOPYでファイルが正常にコピーされました。(コード: %errorlevel%)
) else if errorlevel 0 (
echo 情報: ROBOCOPYでコピーするファイルはありませんでした。(コード: %errorlevel%)
)
echo.
:cleanup_and_exit
REM --- 一時退避フォルダを削除 ---
if exist "%TEMP_DEPLOY_DIR%" (
rd /s /q "%TEMP_DEPLOY_DIR%"
)
echo 全ての処理が完了しました。
goto :eof
:restore_and_exit
REM エラー発生時に退避ファイルを戻す試み
popd
for %%c in (%CONFIG_FILES%) do (
if exist "%TEMP_DEPLOY_DIR%\%%c" (
move /y "%TEMP_DEPLOY_DIR%\%%c" "%DESTINATION_FOLDER%\%%c" > nul
)
)
echo エラーが発生したため処理を中断しました。退避ファイルの復元を試みました。
goto cleanup_and_exit
:eof
pause
@souri-t
Copy link
Author

souri-t commented Jul 4, 2025

@echo off
setlocal

:: --- 変数設定 ---
set "TEMP_DIR=%TEMP%\FileCopyTemp_%RANDOM%"

:: 退避・復元するファイルリスト
:: 複数のファイルを指定する場合は、"ファイルパス1" "ファイルパス2" のように半角スペースで区切って記述してください。
set "FILES_TO_PRESERVE=wwwroot\appsettings.json appsettings.json web.config"

:: --- コマンドライン引数のチェック ---
IF "%~1"=="" (
echo.
echo エラー: コピー元フォルダが指定されていません。
echo.
echo 使用法: %~nx0 ^<コピー元フォルダ^> ^<コピー先フォルダ^>
echo 例: %~nx0 C:\Source D:\Destination
goto :EOF
)

IF "%~2"=="" (
echo.
echo エラー: コピー先フォルダが指定されていません。
echo.
echo 使用法: %~nx0 ^<コピー元フォルダ^> ^<コピー先フォルダ^>
echo 例: %~nx0 C:\Source D:\Destination
goto :EOF
)

set "SOURCE_DIR=%~1"
set "DEST_DIR=%~2"

:: --- フォルダの存在チェック ---
IF NOT EXIST "%SOURCE_DIR%" (
echo.
echo エラー: コピー元フォルダ "%SOURCE_DIR%" が見つかりません。
goto :EOF
)

IF NOT EXIST "%DEST_DIR%" (
echo.
echo エラー: コピー先フォルダ "%DEST_DIR%" が見つかりません。
goto :EOF
)

echo.
echo コピー元フォルダ: %SOURCE_DIR%
echo コピー先フォルダ: %DEST_DIR%
echo.

:: --- 一時フォルダの作成 ---
echo 一時フォルダを作成しています: %TEMP_DIR%
md "%TEMP_DIR%"
IF ERRORLEVEL 1 (
echo エラー: 一時フォルダの作成に失敗しました。
goto :EOF
)

:: --- 特定ファイルの退避 ---
echo 特定ファイルを一時フォルダに退避します...

FOR %%F IN (%FILES_TO_PRESERVE%) DO (
IF EXIST "%DEST_DIR%%%~F" (
echo - 退避中: "%DEST_DIR%%%~F"
xcopy "%DEST_DIR%%%~F" "%TEMP_DIR%" /Y >nul
IF ERRORLEVEL 1 (
echo 警告: ファイル "%DEST_DIR%%%~F" の退避に失敗しました。スキップします。
)
) ELSE (
echo - ファイルは存在しません (スキップ): "%DEST_DIR%%%~F"
)
)

echo.

:: --- AフォルダからBフォルダへのコピー ---
echo Aフォルダの内容をBフォルダにコピーします...
echo (既存のファイルは上書きされますが、退避された特定ファイルは除く)
xcopy "%SOURCE_DIR%*" "%DEST_DIR%" /E /I /Y
IF ERRORLEVEL 1 (
echo エラー: ファイルのコピー中に問題が発生しました。
goto :CLEANUP
)

echo.
echo コピーが完了しました。

:: --- 特定ファイルの復元 ---
echo 特定ファイルを元の場所に戻します...

FOR %%F IN (%FILES_TO_PRESERVE%) DO (
IF EXIST "%TEMP_DIR%%%~nxF" (
echo - 復元中: "%DEST_DIR%%%~F"
xcopy "%TEMP_DIR%%%~nxF" "%DEST_DIR%%%~F" /Y >nul
IF ERRORLEVEL 1 (
echo 警告: ファイル "%DEST_DIR%%%~F" の復元に失敗しました。手動で確認してください。
)
) ELSE (
echo - 退避されたファイルが見つかりません (スキップ): "%%~nxF"
)
)

echo.
echo 特定ファイルの復元が完了しました。

:: --- クリーンアップ ---
:CLEANUP
echo 一時フォルダを削除しています: %TEMP_DIR%
rmdir /S /Q "%TEMP_DIR%"
IF ERRORLEVEL 1 (
echo 警告: 一時フォルダの削除に失敗しました。手動で削除してください。
)

echo.
echo 処理が完了しました。
endlocal
goto :EOF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment