ファイルに何らかの操作をする際、Drop操作でファイルを選択できると、操作性が良くなります。ファイル名を変更する操作行うアプリケーションを作成します。
Drop操作で、ファイル名を取得する方法については、「TextBoxへのドロップ操作でファイル名を取得する C# WPF」を参照してください。
Windowsアプリケーションで、ファイルの位置を表す方法
ファイル名は、パスとファイル名、拡張子をあわせて取得し、使用します。それぞれを別個に利用したい場合は、別個に取り出す操作が必要です。そして、それぞれを別個に扱う方法は、C#では、システムSystem.IO名前空間のPathクラスに、あらかじめ、用意されています。
Windowsプログラムで使用するファイルの位置を表す表現は、Pathクラスで扱うDosやWindowsシステムで見慣れたパス形式の他に、Uriクラスで扱う、htmlなどネットワーク関連でよく使用されるUri形式があります。
Windowsプログラム内部で使用する場合、パス形式が扱いやすいです。
ファイル名は、パスとファイル名、拡張子をあわせて取得し、使用します。それぞれを別個に利用したい場合は、別個に取り出す操作が必要です。そして、それぞれを別個に扱う方法は、C#では、システムSystem.IO名前空間のPathクラスに、あらかじめ、用意されています。
Windowsプログラムで使用するファイルの位置を表す表現は、Pathクラスで扱うDosやWindowsシステムで見慣れたパス形式の他に、Uriクラスで扱う、htmlなどネットワーク関連でよく使用されるUri形式があります。
Windowsプログラム内部で使用する場合、パス形式が扱いやすいです。
ファイル名から、必要な情報を取り出す
複数の情報を連結してファイル名を作成する
分割したファイル名を連結するには、PathクラスのCombine静的メソッドを使用します。静的メソッドなので、new演算子でインタンスを作成することなく使用できます。
ファイル名を変更する
C#でファイル名を変更する方法には、2つの方法があります。
1つは、FileクラスのFile.Move静的メソッドを使用する方法です。
移動先のパスに、移動元と同じ位置を指定することで、名前を変更することができます。
もう一つは、FileInfoクラスのMoveToメソッドを使用する方法です。こちらは、通常のメソッドなので、newコマンドで、インスタンスを生成して使用する必要があります。
このメソッドも、移動先のパスに、移動元と同じ位置を指定することで、名前を変更することができます。
プログラムの作成
TextBoxにファイルをドロップすると、ファイル名を取得するコードを修正して、ファイル名を変更できるプログラムを作成します。
UIとドロップする部分については、「TextBoxへのドロップ操作でファイル名を取得する C# WPF」を参照してください。
MainWindow.xaml
<Window x:Class="ChangeFileName.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ファイル名変えちゃうぞ!" Height="150" Width="350">
<DockPanel>
<Grid DockPanel.Dock="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Click="Button_Click">ファイル名変更</Button>
<Button Grid.Column="1">Button02</Button>
</Grid>
<TextBox DockPanel.Dock="Top" Name="tb" DragOver="Tb_DragOver" Drop="Tb_Drop" AllowDrop="True" TextWrapping="Wrap">
TextBox
</TextBox>
</DockPanel>
</Window>
MainWindow.xaml.cs
using System.IO;
using System.Windows;
using System.Windows.Controls;
namespace ChangeFileName
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
string fname; // ファイル名(名前と拡張子)
string newfname; // 変更後のファイル名(フルパス)
string oldfname; // 変更前のファイル名(フルパス)
string dir; // パス
public MainWindow()
{
InitializeComponent();
tb.AddHandler(TextBox.DragOverEvent, new DragEventHandler(Tb_DragOver), true);
tb.AddHandler(TextBox.DropEvent, new DragEventHandler(Tb_Drop), true);
}
private void Tb_DragOver(object sender, DragEventArgs e)
{
// マウスポインタを変更する。
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effects = DragDropEffects.All;
}
else
{
e.Effects = DragDropEffects.None;
}
e.Handled = false;
}
private void Tb_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
// TextBoxの中身をクリアする。
tb.Text = string.Empty;
// ファイル名をクリア
fname = null;
// ディレクトリ名をクリア
dir = null;
// ドロップしたファイル名を全部取得する。
string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop);
// フルパスファイル名をoldfnameに入れ、メソッドの外からもアクセスできるようにする。
oldfname = filenames[0];
// ファイル名と拡張子を取得
fname = Path.GetFileName(filenames[0]);
// ディレクトリ名を取得
dir = Path.GetDirectoryName(filenames[0]);
tb.Text = fname;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
newfname = Path.Combine(dir, tb.Text);
// ファイル名を変更する File.Move
File.Move(oldfname, newfname);
}
}
}
実行して動作を確認します。うまく動くようです。
長すぎるファイル名を持ったファイルを扱ったときの動作
しかし、長すぎるファウル名を持つファイルをドロップするとエラーが発生します。
System.Runtime.InteropServices.COMException: 'システム コールに渡されるデータ領域が小さすぎます。 (HRESULT からの例外:0x8007007A)'
私が持っているアプリケーションでは、「TMPGEnc Video Mastering Works 5」が、エクスプローラーで名前変更できない長いファイルを作成することができます。
フルパスで260文字を超えるファイル名を扱う
調べてみたところ、C#で、フルパスで260文字を超えるファイル名を扱うには、.Net Freameworkに含まれるクラスを使うと実現できないようです。Win32APIを使用して操作する必要があるようです。
必要を感じたら、フルパスで260文字を超えるファイル名を扱うアプリケーションに挑戦してみるかもしれませんが、現時点では、これで終了します。