現在使用中のファイルを移動する方法

概要

Win32 アプリケーションで、システムが現在使用中のファイルに対して、削除、移動、またはファイル名の変更が必要になる場合があります。よくある例は、セットアップ プログラムが、ソフトウェア パッケージのセットアップの完了時に、ユーザーのハード ディスクからセットアップ プログラム自体を削除する場合です。現在システムが使用中のデバイス ドライバの移動が必要な場合もあります。アプリケーションでこれらのファイルを削除または移動するためには、オペレーティング システムによる支援が必要です。


Windows 95 および Windows NT では、使用中のファイルまたはディレクトリに対してアプリケーションから削除、置き換え、ファイル名の変更を行うことができる独自のメソッドが提供されています。これらのメソッドの実装方法はプラットフォームごとに異なりますが、全般的な方針は共通しており、処理するファイルをアプリケーションから指定し、再起動時にシステムが指定されたファイルを処理するという方法を採用しています。この資料では、それぞれの Windows プラットフォームが提供するメソッドをアプリケーションから使用する方法について説明します。

詳細

Windows NT におけるファイルの移動

Windows NT 上で稼働する Win32 ベースのアプリケーションでは、使用中のファイルまたはディレクトリを移動、置き換え、または削除するために、MOVEFILE_DELAY_UNTIL_REBOOT フラグを指定して、MoveFileEx() を使用します。システムが次回再起動されると、指定したファイルまたはディレクトリが Windows NT 起動プログラムによって移動、置き換え、または削除されます。


使用中のファイルまたはディレクトリを移動または置き換えるには、同一ボリューム (ドライブ C: など) 上の移動元と移動先のパスを指定する必要があります。移動先のパスが既存のファイルの場合は、それが上書きされます。移動先のパスが既存のディレクトリの場合は、上書きされず、移動元と移動先のパスは以前のまま変更されません。次の例では、ファイルが移動または置き換えられるか、ディレクトリが移動されます。
   // Move szSrcFile to szDstFile next time system is rebooted
MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);
ファイルまたはディレクトリを削除するには、移動先のパスを NULL にする必要があります。移動元のパスがディレクトリの場合は、それが空のときのみ削除されます。なお、MoveFileEx() を使用してディレクトリからファイルを削除する必要があるときは、MoveFileEx() によって実際にディレクトリが削除される前にコンピュータを再起動する必要があります。次の例ではファイルが削除されるか、ディレクトリが空にされます。

   // Delete szSrcFile next time system is rebooted
MoveFileEx(szSrcFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

Windows 95 におけるファイルの移動

Windows 95 には MoveFileEx() は実装されていませんが、Win32 ベース、16 ビット Windows ベース、および MS-DOS ベースのすべてのアプリケーションを対象に、現在使用中のファイル (ディレクトリは対象外) を移動、置き換え、削除するための代替手段が提供されています。この機能は、Wininit.ini というファイルの [rename] セクションを使用して実装されます。Wininit.ini が Windows ディレクトリに存在する場合、システムの起動時に Wininit.exe がそれを処理します。Wininit.ini の処理が完了すると、Wininit.exe はその名前を Wininit.bak に変更します。


[rename] セクションの構文は次のとおりです。

   DestinationFileName=SourceFileName
DestinationFileName と SourceFileName は、同一ボリュームに存在する必要があります。また、(8.3) 形式の短いファイル名である必要もあります。これは、Wininit.ini はプロテクト モードのディスク システムが読み込まれる前に処理されるためです。長いファイル名を使用できるのは、プロテクト モードのディスク システムが実行されているときのみです。Wininit.ini 内で移動元と移動先に長いファイル名を指定してもそれらのファイルは無視されます。


[rename] セクションには、1 行に 1 ファイルずつ、複数の行を記述できます。ファイルを削除するには、DestinationFileName として NUL を指定します。次に入力例を示します。
   [rename]
NUL=C:\TEMP.TXT
C:\NEW_DIR\EXISTING.TXT=C:\EXISTING.TXT
C:\NEW_DIR\NEWNAME.TXT=C:\OLDNAME.TXT
C:\EXISTING.TXT=C:\TEMP\NEWFILE.TXT
1 行目は、Temp.txt を削除します。2 行目は、Existing.txt を新しいディレクトリへ移動します。3 行目は、Oldname.txt を移動して名前を変更します。4 行目は、既存のファイルに Newfile.txt を上書きします。


アプリケーションから WritePrivateProfileString() を使用して [rename] セクションに行を直接書き込まないでください。これを行うと、同じ DestinationFileName の行が複数存在する場合があるためです (特に DestinationFileName が NUL の場合など)。行を追加するには、Wininit.ini の内容を解析した上で、[rename] セクションの最後に行を追加します。


注 : Wininit.ini を解析するときは必ず大文字と小文字を区別しない検索を行います。[rename] セクションのタイトルや、そこに記述されるファイルの名前は、大文字と小文字の任意の組み合わせが使用される可能性があるためです。


Wininit.ini を使用するアプリケーションでは、Wininit.ini が Windows ディレクトリに存在するかどうかを確認します。Wininit.ini が存在する場合は、前回システムが再起動されてから後に別のアプリケーションがそれを書き込んだことを意味します。したがって、そのファイルを開き、[rename] セクションに行を追加する必要があります。Wininit.ini が存在しない場合は、それを作成してから [rename] セクションに行を追加します。これにより、他のアプリケーションによって追加された行を誤って削除することがなくなります。


システムが再起動される前にファイル名の変更操作を取り消すには、対応する行を Wininit.ini ファイルの [rename] セクションから削除する必要があります。

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 140570 (最終更新日 2004-09-27) を基に作成したものです。


この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
プロパティ

文書番号:140570 - 最終更新日: 2008/02/20 - リビジョン: 1

フィードバック