トップ回答者
フォルダを指定して、別のフォルダにコピーしたい

質問
回答
-
White Eagle さんからの引用 出来れば、System.IO.File.Copyと、folderBrowserDialogの組み合わせ方を教えて頂けないでしょうか。
File.Copyは指定した1つのファイルをコピーするメソッドです。
目的のことを実現するためには、FolderBrowserDialogから指定されたパスの取得、対象のファイルの列挙、ファイルのコピー等でしょう。
この辺は言語を問いません。
メソッドが分からないというのであれば、System.IO名前空間のヘルプやMSDNサイトをご覧下さい。
色々と見つかると思います。
ところで、C++ではどうやって実現しますか?
それが分かっていれば、あとはC#のメソッドに置き換えていくだけのような気がします。
-
外池と申します。「組み合わせ方」と仰る意味がよくわかりませんが・・・、関連するクラスをいくつかご紹介しておきます。
FolderBrowserDialogは選択されたフォルダーのPathをString型で返します。
特定のフォルダーを意味するオブジェクトは、System.IO.Directoryクラスから生成しますが、そのとき上述のString型のPathが使えます。既存のフォルダーを、その内容物(サブ・フォルダーやファイル)も含めて別の場所へ移す(移す先は新規であること)には、DirectoryクラスのMoveメソッドが使えますが、
たぶん、ご質問は既存のフォルダーから、別の既存のフォルダーへの、内容物のコピーですよね?
そうしますと、Directoryクラスのメソッドを駆使して内容物(サブ・フォルダーやファイル)をひとつひとつ拾い上げて、個別にコピーしないといけません。コピーはtrapemiyaさんの仰るSystem.IO.FileのCopyで行えますが、コピーする対象のファイルなどを拾い上げる操作はご自分でプログラムするしかないと思います。
-
きっと参考になると思うのですが、オライリーの「プログラミングC#」(第4版)という書籍で、
TreeViewを使ったファイルのコピー方法がサンプル用のプログラムとして解説されています。
folderBrowserDialogを使わずにTreeViewを使っていますが、
左右にフォルダとファイルの一覧をツリーで選べるようにして、コピーをおしたら左から右へコピーできるというもので、
White Eagleさんが作ろうとしているプログラムとほぼ同じような機能を実装していると思います。
「C++プログラマ向け」という注釈も随所にあってC++との違いを補足説明していますし、理解しやすいのではないでしょうか。
この機会に一冊購入してみては如何でしょうか。 -
とりあえず、White Eagle さんの残る質問は以下の2つということで、解答させていただきます。
【OKを押してもfolderBrowserDialog2が表示されない】
private void button1_Click(object sender, EventArgs e)
{
・・・・
・・・・
if ( MessageBox.Show("続けますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.Cancel) {
Close();}
}
この記述は「OKキャンセルメッセージボックスを表示させて、キャンセルボタンを押したら閉じる」です。
つまり、OKを押した時の処理が何も記述されていないので、当然folderBrowserDialog2は表示されません。
以下のようにするとでてきます。
if ( MessageBox.Show("続けますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.OK){
//ダイアログ2の設定を記述
・・・
//ダイアログ2表示
if (folderBrowserDialog2.ShowDialog() == DialogResult.OK)
{
// bにコピー先のディレクトリを代入
b = (folderBrowserDialog2.SelectedPath);
}
}
【File.Copyの使い方がわからない】
きちんと全員の方の返信を読み直してください。Azuleanさんが参考サイトを教えてくれています。
http://dobon.net/vb/dotnet/file/copyfolder.html
このページのC#版のCopyDirectoryメソッドを自分のクラスにコピーし、bにコピー先の
ディレクトリを代入したあとメッセージボックスでも表示させて、OKを押した時に
CopyDirectory(@a, @b);
と記述すればいいだけです。
すべての返信
-
White Eagle さんからの引用 出来れば、System.IO.File.Copyと、folderBrowserDialogの組み合わせ方を教えて頂けないでしょうか。
File.Copyは指定した1つのファイルをコピーするメソッドです。
目的のことを実現するためには、FolderBrowserDialogから指定されたパスの取得、対象のファイルの列挙、ファイルのコピー等でしょう。
この辺は言語を問いません。
メソッドが分からないというのであれば、System.IO名前空間のヘルプやMSDNサイトをご覧下さい。
色々と見つかると思います。
ところで、C++ではどうやって実現しますか?
それが分かっていれば、あとはC#のメソッドに置き換えていくだけのような気がします。
-
あとは、どぼんさんのサイトも参考になるかもしれません。
http://dobon.net/vb/dotnet/file/copyfolder.html
※Googleで「フォルダ コピー C#」を検索した場合、一番最初に表示されます。
-
C#はどの程度わからないのでしょうか? 基礎的な学習がまだであれば何か一冊本を読んで勉強されるのがお勧めです。ネットであれば、
連載 改訂版 C#入門
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/index/などもあります。
いずれにしてもC#を全体的に大まかに体系付けて説明されているものを読まれるのが良いと思います。
その上で、「FolderBrowserDialog C#」や「File.Copy C#」で検索されれば、サンプルコードはたくさん見つかるので、それを組み合わせてみて下さい。コードを書いてみてうまくいかなければ、また質問して下さい。
-
外池と申します。「組み合わせ方」と仰る意味がよくわかりませんが・・・、関連するクラスをいくつかご紹介しておきます。
FolderBrowserDialogは選択されたフォルダーのPathをString型で返します。
特定のフォルダーを意味するオブジェクトは、System.IO.Directoryクラスから生成しますが、そのとき上述のString型のPathが使えます。既存のフォルダーを、その内容物(サブ・フォルダーやファイル)も含めて別の場所へ移す(移す先は新規であること)には、DirectoryクラスのMoveメソッドが使えますが、
たぶん、ご質問は既存のフォルダーから、別の既存のフォルダーへの、内容物のコピーですよね?
そうしますと、Directoryクラスのメソッドを駆使して内容物(サブ・フォルダーやファイル)をひとつひとつ拾い上げて、個別にコピーしないといけません。コピーはtrapemiyaさんの仰るSystem.IO.FileのCopyで行えますが、コピーする対象のファイルなどを拾い上げる操作はご自分でプログラムするしかないと思います。
-
皆さん、返信有難うございます。
現在、こんな感じです。
これに、File.Copyを追加すれば完成なのですが・・・。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;namespace iTunesTools
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}private void button1_Click(object sender, EventArgs e)
{
//DialogResult result = this.folderBrowserDialog1.ShowDialog();
//if (result == DialogResult.OK)
//Console.WriteLine("Folder = " + this.folderBrowserDialog1.SelectedPath);
// FolderBrowserDialog の新しいインスタンスを生成する (デザイナから追加している場合は必要ない)
//FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();// ダイアログの説明を設定する
folderBrowserDialog1.Description = "ライブラリに追加したいファイルを、iTunes musicフォルダから選んでください(iTunesMusicフォルダの場所は、C言語ユーザー,コピー元のアカウント,ミュージック,iTunes,iTunes Musicです)。";// ルートになる特殊フォルダを設定する (初期値 SpecialFolder.Desktop)
folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;// 初期選択するパスを設定する
//folderBrowserDialog1.SelectedPath = @"C:\Users\eagle\Music\iTunes\iTunes Music";// [新しいフォルダ] ボタンを表示する (初期値 true)
folderBrowserDialog1.ShowNewFolderButton = true;
// ダイアログを表示し、戻り値が [OK] の場合は、選択したディレクトリを表示する
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
//この行を変える↓File.Copy
MessageBox.Show(folderBrowserDialog1.SelectedPath);}
// 不要になった時点で破棄する (正しくは オブジェクトの破棄を保証する を参照)
folderBrowserDialog1.Dispose();
}private void button2_Click(object sender, EventArgs e)
お願いします。
{
if ( MessageBox.Show("終了しますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.OK ) {
Close();
}
}
}
} -
皆さんの情報を元に、プログラムを書いてみました。
コピーする処理はまだつけていませんが、コピーする方のフォルダ指定の処理までは書けました。
しかし、エラーは出ないのですが、1つ目のフォルダ指定、続けるかどうかの質問までは上手くいくのですが、OKを押してもfolderBrowserDialog2が出てきません。
根本的に間違っているのでは無いかと思っています。
原因は何なんでしょうか。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;namespace iTunesTools
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}string a, b;
private void button1_Click(object sender, EventArgs e)
{
//DialogResult result = this.folderBrowserDialog1.ShowDialog();
//if (result == DialogResult.OK)
//Console.WriteLine("Folder = " + this.folderBrowserDialog1.SelectedPath);
// FolderBrowserDialog の新しいインスタンスを生成する (デザイナから追加している場合は必要ない)
//FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();// ダイアログの説明を設定する
folderBrowserDialog1.Description = "ライブラリに追加したいファイルを、フォルダから選んでください。";// ルートになる特殊フォルダを設定する (初期値 SpecialFolder.Desktop)
folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;// 初期選択するパスを設定する
//folderBrowserDialog1.SelectedPath = @"C:\Users\eagle\Music\iTunes\iTunes Music";// [新しいフォルダ] ボタンを表示する (初期値 true)
folderBrowserDialog1.ShowNewFolderButton = true;
// ダイアログを表示し、戻り値が [OK] の場合は、選択したディレクトリを表示する
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
//MessageBox.Show(folderBrowserDialog1.SelectedPath);
a = (folderBrowserDialog1.SelectedPath);
}// 不要になった時点で破棄する (正しくは オブジェクトの破棄を保証する を参照)
folderBrowserDialog1.Dispose();if ( MessageBox.Show("続けますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.Cancel) {
Close();
}
}
private void folderBrowserDialog2_HelpRequest(object sender, EventArgs e)
{
//コピーするフォルダを指定↓
// ダイアログの説明を設定する
folderBrowserDialog1.Description = "コピーされるフォルダを選んでください。";// ルートになる特殊フォルダを設定する (初期値 SpecialFolder.Desktop)
folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;// 初期選択するパスを設定する
//folderBrowserDialog1.SelectedPath = @"C:\Users\eagle\Music\iTunes\iTunes Music";// [新しいフォルダ] ボタンを表示する (初期値 true)
folderBrowserDialog1.ShowNewFolderButton = true;
// ダイアログを表示し、戻り値が [OK] の場合は、選択したディレクトリを表示する
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
//MessageBox.Show(folderBrowserDialog1.SelectedPath);
b = (folderBrowserDialog1.SelectedPath);
}// 不要になった時点で破棄する (正しくは オブジェクトの破棄を保証する を参照)
folderBrowserDialog1.Dispose();
}private void button2_Click(object sender, EventArgs e)
{
if ( MessageBox.Show("終了しますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.OK ) {
Close();
}
}
}お願いします。
-
White Eagle さんからの引用 しかし、エラーは出ないのですが、1つ目のフォルダ指定、続けるかどうかの質問までは上手くいくのですが、OKを押してもfolderBrowserDialog2が出てきません。
根本的に間違っているのでは無いかと思っています。
その2つ目のFolderBrowserDialogを表示するコードが通る条件を、HelpRequestイベントのヘルプを見て確認して下さい。
どういったときに実行されるかについて理解する、考えてみるべきです。
なお、そのコードが実行されているかどうかは、ブレークポイントをつけることでデバッグしたときに確認できます。
-
White Eagle さんからの引用 File.Copyメソッドでは、フォルダのパスを指定することは出来ないのですか?
それが出来れば、すんなり完成なのですが。
ヘルプ、MSDN等でそのメソッドの仕様を確認すれば済む話です。
一度、ご覧下さい。
http://msdn.microsoft.com/ja-jp/library/system.io.file.copy.aspx
「あるメソッドで何々できないのですか?」と聞く前に、一度ヘルプ(MSDN)を読むクセをつけて下さい。
また、先の発言でも書きましたが、ちゃんと全ての回答を読んで頂いていますか?
このスレッドの全て投稿に目を通していれば、この質問は出てこないと思ったのですが、見落としていませんか?
White Eagle さんからの引用 また、folderBrowserDialogで、フォルダをCドライブからいちいち選ぶのも大変なので、開いたときに、「あるフォルダ」から選ばせるというのは出来ますか?
FolderBrowserDialogのヘルプ(MSDN)をじっくり読めば解決できると思います
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.folderbrowserdialog_members.aspx
-
MSDNで見たところ、RootFolderで指定すれば良いと書かれていたのでパスを指定しようと思ったのですが、パスの指定の仕方はどうすればいいのですか?
調べてみたのですが、全く載っていません。調べ方が浅いのでしょうか。
folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;
これにどのように追加すればいいのか分かりません。
実行してみると、マイコンピュータが最初に指定されているので、認識はしていると思うのですが。MyComputerの後に¥を入れてみると、エラーが出てしまいます。
どうすればいいのでしょうか?
お願いします。
-
White Eagle さんからの引用 MSDNで見たところ、RootFolderで指定すれば良いと書かれていたのでパスを指定しようと思ったのですが、パスの指定の仕方はどうすればいいのですか?
調べてみたのですが、全く載っていません。調べ方が浅いのでしょうか。
いえ、調べ方が悪いのではなく、私の早とちりです、すみません。(初期の選択フォルダを指定するものと解釈していました)
ダイアログ表示時のルートフォルダを特定のフォルダにすることはFolderBrowserDialogでは実現できません。
Win32APIを使えば実現可能だと思われますが、ハードルが高くなりますのでお薦めしません。
顧客からの要求があるのであれば検討せざる得ませんが、簡単ではない点にご留意ください。
(アンマネージメモリを扱うため、メモリリークが起きやすい)
キーワード:
SHBrowseForFolder SHGetPathFromIDList
ハードルが高くなるとする根拠:
・Win32APIを使う必要がある。
・特定のフォルダのIDListを得るためにはILCreateFromPathやIShellFolderを利用する必要がある。特に後者はCOMの知識を要する。
-
White Eagleさんが以前掲載されたコードを見ると、RoofFolderもSelectedPathも出てきています。にもかかわらず、Cドライブからいちいち選択するのが面倒だと言われています。ちょっと論点がずれてきているような気がします。
なので、Azuleanさんが解釈されたように、RootFolderではなくて単にSelectedPathの話のような気がしています。
私はWhite Eagleさんがパスの指定方法がわからないのではないかと解釈して、その検索の仕方などを前回の投稿で書きましたが、先ほども述べましたように、White Eagleさんは掲載されたコードにおいてパスの指定方法を既に書かれていました。このことに気が付かなったので、私の回答がおかしなものになってしまいました。すみません。
ただ、White EagleさんはRootFolderとSelectedPathをきちんと理解されてコードを書かれていますか? MSDNを読めば明確に説明されていますので、今一度確認してみて下さい。以下のページの解説の項です。
FolderBrowserDialog.RootFolder プロパティ
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.folderbrowserdialog.rootfolder(VS.80).aspx -
White Eagle さんからの引用
初期指定のパスの問題は、自己解決しました。双方で思い違いがないように確認させて下さい。SelectedPathを使用されたのでしょうか?
White Eagle さんからの引用 いまだにFile.Copyの使い方が見つからない・・・。
最初の頃にも書いたのですが、「file.copy c#」で検索されたのでしょうか? 以下などたくさん見つかります。
もし、以下のページなどをご覧になっても解決しない場合は、どの辺りが問題になっているのかもう少し具体的に教えていただければ、アドバイスができるのではないかと思います。
ファイルをコピー/削除/リネーム/移動するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/046filecopy/filecopy.html -
一部、このスレッドの私自身の発言を引用しています。
White Eagle さんからの引用 いまだにFile.Copyの使い方が見つからない・・・。
単純なFile.Copyの使い方ならMSDNでも。
Azulean さんからの引用 ヘルプ、MSDN等でそのメソッドの仕様を確認すれば済む話です。
一度、ご覧下さい。
http://msdn.microsoft.com/ja-jp/library/system.io.file.copy.aspx
しかし、今回はフォルダ自体をコピーしたいか、フォルダの中の全てのファイルをコピーしたいかですよね?
それであれば、File.Copyだけじゃできません。
理由として、File.Copyは1ファイルのコピーしか機能が存在しないため、フォルダをコピーしたり、複数のファイルをコピーすることができないためです。
File.Copyを使って実現するためには繰り返し(ループ)の処理が必要になります。
そのため、次のようなページを示しました。
Azulean さんからの引用 あとは、どぼんさんのサイトも参考になるかもしれません。
http://dobon.net/vb/dotnet/file/copyfolder.html
※Googleで「フォルダ コピー C#」を検索した場合、一番最初に表示されます。
今回の場合に限りませんが、実現したいこと(目的)を満たすためには、複数の要素を組み合わせる、応用する必要があることが多いと言えます。
引数にさえ書けば何でもできるような、便利なメソッドは少ないのが現実です。
-
きっと参考になると思うのですが、オライリーの「プログラミングC#」(第4版)という書籍で、
TreeViewを使ったファイルのコピー方法がサンプル用のプログラムとして解説されています。
folderBrowserDialogを使わずにTreeViewを使っていますが、
左右にフォルダとファイルの一覧をツリーで選べるようにして、コピーをおしたら左から右へコピーできるというもので、
White Eagleさんが作ろうとしているプログラムとほぼ同じような機能を実装していると思います。
「C++プログラマ向け」という注釈も随所にあってC++との違いを補足説明していますし、理解しやすいのではないでしょうか。
この機会に一冊購入してみては如何でしょうか。 -
とりあえず、White Eagle さんの残る質問は以下の2つということで、解答させていただきます。
【OKを押してもfolderBrowserDialog2が表示されない】
private void button1_Click(object sender, EventArgs e)
{
・・・・
・・・・
if ( MessageBox.Show("続けますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.Cancel) {
Close();}
}
この記述は「OKキャンセルメッセージボックスを表示させて、キャンセルボタンを押したら閉じる」です。
つまり、OKを押した時の処理が何も記述されていないので、当然folderBrowserDialog2は表示されません。
以下のようにするとでてきます。
if ( MessageBox.Show("続けますか?","Tools",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question )
==System.Windows.Forms.DialogResult.OK){
//ダイアログ2の設定を記述
・・・
//ダイアログ2表示
if (folderBrowserDialog2.ShowDialog() == DialogResult.OK)
{
// bにコピー先のディレクトリを代入
b = (folderBrowserDialog2.SelectedPath);
}
}
【File.Copyの使い方がわからない】
きちんと全員の方の返信を読み直してください。Azuleanさんが参考サイトを教えてくれています。
http://dobon.net/vb/dotnet/file/copyfolder.html
このページのC#版のCopyDirectoryメソッドを自分のクラスにコピーし、bにコピー先の
ディレクトリを代入したあとメッセージボックスでも表示させて、OKを押した時に
CopyDirectory(@a, @b);
と記述すればいいだけです。