🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

4112閲覧

C#でフォルダのコピーを行いたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2019/09/20 02:02

前提・実現したいこと

WPFでフォルダのコピーを行いたいと思っています。
コピー時に、進捗確認を行いつつ、上書きがある場合はすべてTRUEにしたいと思っています。
しかし、下記のメソッドではUI表示はできても上書きができず、もう1つは上書きはできてもUI表示ができません。
この2つを同時に行う方法はありますでしょうか?

進捗確認

C#

1Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(srcPath, desPath, UIOption.AllDialogs);

同一ファイルがある場合はすべて上書き

C#

1Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(srcPath, desPath, true);

補足情報(FW/ツールのバージョンなど)

Windows10 Pro
.NetframeWork 4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/09/20 02:13

途中で「すべて上書き」ボタンのついたダイアログが出てきませんか?
退会済みユーザー

退会済みユーザー

2019/09/20 02:15

そのダイアログを出さず、すべて上書きを行いたいです。
Zuishin

2019/09/20 02:19 編集

それなら自分で作るか、他の人の作ったものを探すしかありません。 プログレスバーとキャンセルボタンだけの簡単な UI なので、そう難しくはないと思います。
Zuishin

2019/09/20 02:23 編集

コピーはコピー元ディレクトリを深さ優先探索し、処理中のディレクトリで見つかったファイルの数をプログレスバーの Maximum に足していき、コピーが終わったファイルを Value に足していくといいでしょう。 コピー処理は非同期で行い、CancellationToken を使って中断可能にします。
退会済みユーザー

退会済みユーザー

2019/10/16 06:16 編集

返答が遅れて大変申し訳ございません。Zuishin様の意見を参考に作成することができました。ありがとうございます。
Zuishin

2019/10/16 06:46

何もしていませんが、できて良かったです。KOZ6.0 さんの SHFileOperation は盲点でした。
guest

回答2

0

SHFileOperation を使ってみてはどうでしょう。

API の宣言

C#

1 static class NativeMethods 2 { 3 public enum FileFuncFlags : uint 4 { 5 FO_MOVE = 0x1, 6 FO_COPY = 0x2, 7 FO_DELETE = 0x3, 8 FO_RENAME = 0x4 9 } 10 11 [Flags] 12 public enum FILEOP_FLAGS : ushort 13 { 14 FOF_MULTIDESTFILES = 0x1, 15 FOF_CONFIRMMOUSE = 0x2, 16 FOF_SILENT = 0x4, 17 FOF_RENAMEONCOLLISION = 0x8, 18 FOF_NOCONFIRMATION = 0x10, 19 FOF_WANTMAPPINGHANDLE = 0x20, 20 FOF_ALLOWUNDO = 0x40, 21 FOF_FILESONLY = 0x80, 22 FOF_SIMPLEPROGRESS = 0x100, 23 FOF_NOCONFIRMMKDIR = 0x200, 24 FOF_NOERRORUI = 0x400, 25 FOF_NOCOPYSECURITYATTRIBS = 0x800, 26 FOF_NORECURSION = 0x1000, 27 FOF_NO_CONNECTED_ELEMENTS = 0x2000, 28 FOF_WANTNUKEWARNING = 0x4000, 29 FOF_NORECURSEREPARSE = 0x8000 30 } 31 32 [StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)] 33 public struct SHFILEOPSTRUCT 34 { 35 public IntPtr hwnd; 36 public FileFuncFlags wFunc; 37 [MarshalAs(UnmanagedType.LPTStr)] 38 public string pFrom; 39 [MarshalAs(UnmanagedType.LPTStr)] 40 public string pTo; 41 public FILEOP_FLAGS fFlags; 42 [MarshalAs(UnmanagedType.Bool)] 43 public bool fAnyOperationsAborted; 44 public IntPtr hNameMappings; 45 [MarshalAs(UnmanagedType.LPTStr)] 46 public string lpszProgressTitle; 47 } 48 49 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 50 struct SHFILEOPSTRUCT64 51 { 52 public IntPtr hwnd; 53 public FileFuncFlags wFunc; 54 [MarshalAs(UnmanagedType.LPTStr)] 55 public string pFrom; 56 [MarshalAs(UnmanagedType.LPTStr)] 57 public string pTo; 58 public FILEOP_FLAGS fFlags; 59 [MarshalAs(UnmanagedType.Bool)] 60 public bool fAnyOperationsAborted; 61 public IntPtr hNameMappings; 62 [MarshalAs(UnmanagedType.LPTStr)] 63 public string lpszProgressTitle; 64 } 65 66 [DllImport("shell32.dll", CharSet = CharSet.Auto, EntryPoint = "SHFileOperation")] 67 static extern int SHFileOperation32(ref SHFILEOPSTRUCT lpFileOp); 68 69 [DllImport("shell32.dll", CharSet = CharSet.Auto, EntryPoint = "SHFileOperation")] 70 static extern int SHFileOperation64(ref SHFILEOPSTRUCT64 lpFileOp); 71 72 public static int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp) { 73 if (IntPtr.Size == 4) { 74 return SHFileOperation32(ref lpFileOp); 75 } else { 76 var lpFileOp64 = new SHFILEOPSTRUCT64(); 77 lpFileOp64.hwnd = lpFileOp.hwnd; 78 lpFileOp64.wFunc = lpFileOp.wFunc; 79 lpFileOp64.pFrom = lpFileOp.pFrom; 80 lpFileOp64.pTo = lpFileOp.pTo; 81 lpFileOp64.fFlags = lpFileOp.fFlags; 82 lpFileOp64.fAnyOperationsAborted = lpFileOp.fAnyOperationsAborted; 83 lpFileOp64.hNameMappings = lpFileOp.hNameMappings; 84 lpFileOp64.lpszProgressTitle = lpFileOp.lpszProgressTitle; 85 86 int result = SHFileOperation64(ref lpFileOp64); 87 88 lpFileOp.fAnyOperationsAborted = lpFileOp64.fAnyOperationsAborted; 89 return result; 90 } 91 } 92 } 93

実行

C#

1 static class Program 2 { 3 [STAThread] 4 static void Main() { 5 var fileOp = new NativeMethods.SHFILEOPSTRUCT(); 6 fileOp.wFunc = NativeMethods.FileFuncFlags.FO_COPY; 7 fileOp.pFrom = "C:\work\*.*\0\0"; 8 fileOp.pTo = "C:\Work2\0\0"; 9 fileOp.fFlags = NativeMethods.FILEOP_FLAGS.FOF_NOCONFIRMATION | NativeMethods.FILEOP_FLAGS.FOF_NOCONFIRMMKDIR; 10 fileOp.fAnyOperationsAborted = true; 11 fileOp.hNameMappings = IntPtr.Zero; 12 fileOp.lpszProgressTitle = "コピー中・・・"; 13 NativeMethods.SHFileOperation(ref fileOp); 14 } 15 }

投稿2019/09/20 03:04

KOZ6.0

総合スコア2707

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

Zuishin様の意見を参考に作成しました。ありがとうございました。

C#

1private void Button_Click_Start(object sender, RoutedEventArgs e) 2{ 3 4 //プログレスバーの設定変更 5 prog.IsIndeterminate = false; 6 prog.Maximum = _srcData.Count(); 7 prog.Minimum = 0; 8 prog.Value = 0; 9 prog.Visibility = Visibility.Visible; 10 11 this.startBtn.IsEnabled = false; 12 13 //非同期処理 14 if (_tokenSource == null) _tokenSource = new CancellationTokenSource(); 15 var token = _tokenSource.Token; 16 17 Task task = Task.Factory.StartNew(() => MyAction(), _tokenSource.Token); 18 19 task.ContinueWith((t) => 20 Finishing(true), 21 new CancellationToken(), 22 TaskContinuationOptions.OnlyOnRanToCompletion, 23 _uiSyncContext 24 ); 25 task.ContinueWith((t) => 26 Finishing(false), 27 new CancellationToken(), 28 TaskContinuationOptions.OnlyOnCanceled, 29 _uiSyncContext 30 ); 31 32} 33 34private void MyAction() 35{ 36 DateTime startDt = DateTime.Now; 37 long currentSize = 0; 38 39 for (int i = 0; i < _srcData.Count(); i++) 40 { 41 string lfileName = _srcData[i].PathName.Remove(0, _srcPath.Length); 42 string lfilePath = _desPath + lfileName; 43 44 //対象ファイル先のフォルダがない場合は作成 45 SafeCreateDirectory(System.IO.Path.GetDirectoryName(lfilePath)); 46 //ファイルのコピー 47 System.IO.File.Copy(_srcData[i].PathName, lfilePath, true); 48 49 //進捗画面の更新 50 currentSize += _srcData[i].FileSize; 51 copyDataProc(_srcData[i], i, startDt, currentSize); 52 53 //プログレスバーの更新 54 var progresstask = new Task(() => this.prog.Value = i); 55 progresstask.Start(_uiSyncContext); 56 _tokenSource.Token.ThrowIfCancellationRequested(); 57 58 } 59} 60 61/// <summary> 62/// 進捗情報の変数更新 63/// </summary> 64/// /// <param name="fi"></param> 65/// /// <param name="cnt"></param> 66/// /// <param name="startDt"></param> 67/// /// <param name="currentSize"></param> 68private void copyDataProc(FileInfo fi, int cnt, DateTime startDt, long currentSize) 69{ 70 71 //処理中のファイル名 72 _viewModel.fileName = System.IO.Path.GetFileName(fi.PathName); 73 //残り時間 74 DateTime endDt = DateTime.Now; 75 TimeSpan ts = endDt - startDt; 76 double d = ts.TotalSeconds; 77 double KBs = (currentSize / 1024) / d; 78 double timeAns = ((_copySize - currentSize) / 1024) / KBs; 79 _viewModel.Remaining_time = timeAns.ToString("F1") + " [s]"; 80 //残り項目 81 string dispCurr = String.Format("{0:#,0}", currentSize / 1024); 82 string dispSum = String.Format("{0:#,0}", _copySize / 1024); 83 string reItems = (cnt + 1).ToString() + " / " + _srcData.Count() 84 + " (" + dispCurr + " / " + dispSum + " KByte)"; 85 _viewModel.Remaining_items = reItems; 86 //スピード 87 _viewModel.Speed = ((int)KBs).ToString() + " [KByte/s]"; 88} 89 90/// <summary> 91/// 非同期処理中の完了、未完了後の処理 92/// </summary> 93/// <param name="flg"></param> 94private void Finishing(bool flg) 95{ 96 if (flg) 97 { 98 MessageBox.Show("completed."); 99 } 100 else 101 { 102 Directory.Delete(_desPath, true); 103 //none 104 } 105 this.Close(); 106} 107 108/// <summary> 109/// フォルダが存在しない場合は作成する 110/// </summary> 111/// <param name="path"></param> 112private DirectoryInfo SafeCreateDirectory(string path) 113{ 114 if (Directory.Exists(path)) 115 { 116 return null; 117 } 118 return Directory.CreateDirectory(path); 119} 120 121/// <summary> 122/// データコピーのキャンセル 123/// </summary> 124/// <param name="sender"></param> 125/// <param name="e"></param> 126private void Button_Click_Cancel(object sender, RoutedEventArgs e) 127{ 128 if (_tokenSource != null) _tokenSource.Cancel(); 129 this.IsCancel = true; 130 this.Close(); 131}

投稿2019/10/16 05:42

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問