質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

3回答

2865閲覧

SaveFileDialogで文字コードをユーザが指定できるようにしたい

BeatStar

総合スコア4958

C#

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2021/08/09 07:20

編集2021/08/12 02:44

趣味でプログラミングしています。

C#のSystem.Windows.Forms.SaveFileDialogを使ってテキストファイルを保存するときに、
Windows付属のメモ帳のような『文字コード』をユーザが指定できるようにしたいのですが、これは可能でしょうか。

メモリ等の関係上、VC#を入れることができず、csc.exeで直接コンパイルしています。(オンラインすらできない…)

なのでCommonFileDialog等は使えません。

その場合は決め打ち等しかないのでしょうか。

できればメモ帳のやつみたいに文字コードを指定できたら良いのですが…

『C# SaveFileDialog 文字コード』で検索してみましたが、

良くてもCommonFileDialogを使う方法、関係のないものだと『ファイルの書き込みについて』でした…

やはり無理なのでしょうか?

[情報]
言語: C#
.NET Framework: 4.0
コンパイラ: csc
種類: WinForm


[追記1]

失礼しました。

イメージとしてはこちらにある、画像の『文字コード(E):』の部分です。

C#のSaveFileDialogを使ってみると文字コード指定できるComboxがありません。
(まあ、WinAPIでもそうだけど)

公式でプロパティを調べてもそれらしきものすら見当たらず…

あのコンボボックスとかの部分でユーザに選択させたいのですが、これって無理でしょうか?


[追記2]

一応、別途用意すること自体は頭の片隅にありましたが、ユーザー目線で考えると煩わしいかなぁと思ったので今回の質問に至りました。

(説明下手ですみません…)


[追記3]
皆様ありがとうございます。
今すぐには試せない環境で、調べてみるとDLLのアクセスが必要であることがわかったため、その使い方を一旦学んでから今回の質問を閉じる事にします。

(今回初めてNuGetと言うものを使いましたのでちょっと手間取っています……)


[追記3]

CommonSaveFileDialogをやってみました。

NuGetで 適当なところに Microsoft.WindowsAPICodePack.dll をDLし、
net48ディレクトリに入っている Microsoft.WindowsAPICodePack.dll を
今回のプロジェクトの、VC#等でいうReleaseディレクトリ内に相当する場所( binディレクトリ ) に配置。

そして、Cygwin上で

C:/Windows/Microsoft.NET/Framework/v4.0.30319/csc /nologo -reference:./bin/Microsoft.WindowsAPICodePack.dll /target:winexe /out:.\bin\Main.eXe .\src\main.cs .\src\sub\MainForm.cs

とコンパイルしました。

コードは、

C#

1using System; 2using System.Windows.Forms; 3 4using Sample.Forms; 5 6using Microsoft.WindowsAPICodePack; 7using Microsoft.WindowsAPICodePack.Dialogs; 8 9namespace Sample{ 10 class EntryPoint{ 11 [STAThread] 12 static void Main( string[] args ){ 13 try{ 14 // メインウィンドウの生成と起動 15 Application.Run( new MainForm( args ) ); 16 17 CommonSaveFileDialog dialog = new CommonSaveFileDialog(); 18 19 // ここで処理する 20 21 }catch( System.Exception err ){ 22 MessageBox.Show( err.Message, "例外発生" ); 23 } 24 } 25 } 26}

としました。

すると、

src\main.cs(17,17): error CS0246: 型または名前空間名 'CommonSaveFileDialog' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。 src\main.cs(17,51): error CS0246: 型または名前空間名 'CommonSaveFileDialog' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。 make: *** [makefile:69: .\bin\Main.eXe] Error 1

とエラーを吐きます。

ちなみに sub\MainForm.cs に書こうとすると usingディレクティブを追加しただけで下記のエラーを吐きます。

src\sub\MainForm.cs(8,17): error CS0234: 型または名前空間名 'WindowsAPICodePack' は名前空間 'Microsoft' に存在しません。アセンブリ参照が不足しています。 make: *** [makefile:72: .\bin\Testor.eXe] Error 1

と出ます。

DLLのファイル名自体に "." を含んでいるためかと思い、
./bin/WindowsAPICodePack.dll
のようにしてみましたが変わらず。

"/" がスイッチと解釈されているのかと思い、(コンパイル時に) -reference:.\bin\WindowsAPICodePack.dll のようにしてみましたが、
それでも変わらず。

メッセージ的には「名前空間が違う」か「(usingしている)名前空間が足りない」的な意味でしょうけど、
「WindowsAPICodePack CommonSaveFileDialog」と検索しても

using Microsoft.WindowsAPICodePack;

を追加しろ…とだけなので……

[構成]

+ binディレクトリ + WindowsAPICodePack.dll + (ここに実行ファイルが生成される) + srcディレクトリ + main.cs + subディレクトリ + MainForm.cs + (ここからコンパイルしたりしている)

※ NuGet は ここからダウンロードしました。

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

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

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

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

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

Zuishin

2021/08/09 07:48

どういう意味かよくわかりません。保存するテキストファイルの文字コードのことなら、ダイアログとは無関係です。 ダイアログはあくまでファイル名の選択に使われます。
BeatStar

2021/08/09 08:18

@ Zuishinさん 失礼しました。追記したのでお願いします。
Zuishin

2021/08/09 08:34

理解しました。私も Windows API Code Pack がいいのではないかと。
BeatStar

2021/08/09 09:46

すみません(汗 大事な情報、抜けていました… WinFormでやっているので、WPF特有のものは使えません。 (本文に追記しておきました…)
dodox86

2021/08/12 03:57 編集

[6 追記3 2021/08/12 11:37]以降の質問編集を読んで: 直接関係はないかもしれませんが、もともとがcsc.exeを直接使ったイリーガルで一般向けではない方法でビルドされているので、発生し得る問題を最小限にするためにもCygwinのシェル上で実行するのではなく、コマンドプロンプトで試すべきだと思います。 Cygwinのターミナル上ではPATHの扱いが変わり、コマンドラインの解釈が意図したとおりにならない可能性が増えます。
BeatStar

2021/08/12 05:10

@ dodox86さん ありがとうございます。 確かにパスの区切り文字が違いますね。この件についても考慮しておきます。
guest

回答3

0

ベストアンサー

Windows API Code Packを使えば簡単に実現できるのでは?

C#

1private void button1_Click(object sender, EventArgs e) 2{ 3 CommonSaveFileDialog dialog = new CommonSaveFileDialog(); 4 CommonFileDialogComboBox comboBox = new CommonFileDialogComboBox(); 5 comboBox.Items.Add(new CommonFileDialogComboBoxItem("SHIFT-JIS")); 6 comboBox.Items.Add(new CommonFileDialogComboBoxItem("UTF-8")); 7 comboBox.Items.Add(new CommonFileDialogComboBoxItem("UNICODE")); 8 comboBox.Items.Add(new CommonFileDialogComboBoxItem("EUC")); 9 comboBox.SelectedIndex = 0; 10 dialog.Controls.Add(comboBox); 11 12 if (dialog.ShowDialog() == CommonFileDialogResult.Ok) 13 { 14 label1.Text = dialog.FileName; 15 label2.Text = comboBox.Items[comboBox.SelectedIndex].Text; 16 } 17}

こんな感じで


追記
CommonSaveFileDialogを利用するにはWindowsAPICodePack-Shellをインストールしなくてはなりません。
これをインストールするとWindowsAPICodePack-Coreもインストールされます。
使用するDLLは
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
の2つのDLLとなります。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /nologo -reference:./bin/Microsoft.WindowsAPICodePack.dll -reference:./bin/Microsoft.WindowsAPICodePack.Shell.dll /target:winexe /out:.\bin\Main.exe .\src\main.cs .\src\sub\MainForm.cs

といった感じでコンパイルすれば使用できるはずです。

./src/main.cs

C#

1using System; 2using System.Windows.Forms; 3 4using Sample.Forms; 5 6namespace Sample{ 7 class EntryPoint{ 8 [STAThread] 9 static void Main( string[] args ){ 10 // メインウィンドウの生成と起動 11 Application.Run( new MainForm( ) ); 12 } 13 } 14}

./src/sub/MainForm.cs

C#

1using System; 2using System.Drawing; 3using System.Windows.Forms; 4using Microsoft.WindowsAPICodePack; 5using Microsoft.WindowsAPICodePack.Dialogs; 6using Microsoft.WindowsAPICodePack.Dialogs.Controls; 7 8namespace Sample.Forms 9{ 10 public partial class MainForm : Form 11 { 12 13 Label label1,label2; 14 15 public MainForm() 16 { 17 Button b = new Button(); 18 b.Location = new Point(10,10); 19 b.Size = new Size(100,50); 20 b.Text = "button"; 21 b.Click += button_Click; 22 this.Controls.Add(b); 23 24 label1 = new Label(); 25 label1.Location = new Point(10,150); 26 label1.AutoSize = true; 27 label2 = new Label(); 28 label2.Location = new Point(10,170); 29 label2.AutoSize = true; 30 this.Controls.Add(label1); 31 this.Controls.Add(label2); 32 33 } 34 35 private void button_Click(object sender, EventArgs e) 36 { 37 CommonSaveFileDialog dialog = new CommonSaveFileDialog(); 38 CommonFileDialogComboBox comboBox = new CommonFileDialogComboBox(); 39 comboBox.Items.Add(new CommonFileDialogComboBoxItem("SHIFT-JIS")); 40 comboBox.Items.Add(new CommonFileDialogComboBoxItem("UTF-8")); 41 comboBox.Items.Add(new CommonFileDialogComboBoxItem("UNICODE")); 42 comboBox.Items.Add(new CommonFileDialogComboBoxItem("EUC")); 43 comboBox.SelectedIndex = 0; 44 dialog.Controls.Add(comboBox); 45 46 if (dialog.ShowDialog() == CommonFileDialogResult.Ok) 47 { 48 label1.Text = dialog.FileName; 49 label2.Text = comboBox.Items[comboBox.SelectedIndex].Text; 50 } 51 } 52 } 53} 54

といったコードと上記のコマンドにてコンパイル、動作の確認ができました。
./binには
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
のDLLを置いてあります。

投稿2021/08/09 08:29

編集2021/08/12 11:07
YAmaGNZ

総合スコア10242

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

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

BeatStar

2021/08/09 09:48

ご回答ありがとうございます。 CommonSaveFileDialogはWinFormでも使えますか? 公式(.NET Framework)で調べてもヒットしないので…
YAmaGNZ

2021/08/09 09:52

「Windows API Code Packを使えば」と書いています。 Nugetでインストールするなりしてください。
BeatStar

2021/08/09 10:00 編集

ありがとうございます! その方向性で調べてみます
BeatStar

2021/08/12 09:09 編集

追記ありがとうございます。 たびたびすみません。 Mainメソッドで同じのようにやってみたところ、 CommonFileDialogComBoxをインスタンス化したところで、 『error CS0234: 型または名前空間名'CommonFileDialogCombox'が見つかりませんでした。usingディレクティブまたはアセンブリ参照が不足しています』と出ます。 ちなみに、using Microsoft.WindowsAPICodePack.Shell; も追加しました。
YAmaGNZ

2021/08/12 10:01

提示されたソースがちょっと何をしたいのか分からなかったので、こちらでフォームにボタンを追加し、そのボタンを押したらダイアログが表示されるようなソースを用意して VisualStudioがインストールされた環境ではありますが回答に書いたコマンドにてコンパイルしたところ、コンボボックスの追加されたダイアログが表示されました。 また、using Microsoft.WindowsAPICodePack.Shell;は追加する必要はありません。
YAmaGNZ

2021/08/12 10:08

コンパイルはコマンドプロンプトにて行っておりCygwinは利用していません。
YAmaGNZ

2021/08/12 10:23

提示されたソースですが using Microsoft.WindowsAPICodePack.Dialogs.Controls; が足りないですね
BeatStar

2021/08/12 10:54

ありがとうございます! Controlsの方のnamespaceをusingしたところ、コンパイルが通りました! ですが、これをMainメソッドではなく、(subディレクトリの)MainForm.csに using Microsoft.WindowsAPICodePack; を差し込んだところ、 『error CS0234: 型または名前空間'WindowsAPICodePack'は名前空間'Microsoft'に存在しません。アセンブリ参照が不足しています』と出ます。 コンパイル時のオプションはMainメソッドのときと同じです。
BeatStar

2021/08/15 10:27

出来ました! 微妙に違うので自己回答しておきますが、方向性はYAmaGNZさんの回答通りなのでBAとします。
guest

0

やっと解決しました!

方向性はYAmaGNZさんの回答通りですが、微妙に違うところがあるので書いておきます。

ーーーー

YAmaGNZさんの仰るように、必要なDLLを入れたりすることに関しては同じですが、

./Sub/SubForm.cs のようにmainメソッドがあるファイル以外に書く場合も含めて、
『コンパイル時のオプションを指定する場合には、DLLを使うソースコードの前に-referenceを置く』です。

です。

つまり、

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /nologo /target:winexe /out:.\bin\Main.exe .\src\main.cs -reference:./bin/Microsoft.WindowsAPICodePack.dll -reference:./bin/Microsoft.WindowsAPICodePack.Shell.dll .\src\sub\MainForm.cs

のように、

<referenceオプション> <DLLを 使うソースコードのファイル>

のような並びっぽいです。

投稿2021/08/15 10:38

BeatStar

総合スコア4958

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

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

YAmaGNZ

2021/08/15 11:11

VisualStudioがインストールしてあるかで違いがあるのですかね? こちらでは、 csc /nologo /r:./bin/Microsoft.WindowsAPICodePack.dll /r:./bin/Microsoft.WindowsAPICodePack.Shell.dll /out:./bin/test.exe /target:winexe .\src\main.cs .\src\sub\mainform.cs としても csc /nologo /out:./bin/test.exe /target:winexe .\src\main.cs .\src\sub\mainform.cs /r:./bin/Microsoft.WindowsAPICodePack.dll /r:./bin/Microsoft.WindowsAPICodePack.Shell.dll とソース指定の後ろに持ってきても正常にコンパイルできましたし、作成されたEXEも実行できました。
BeatStar

2021/08/15 11:50

@ YAmaGNZさん > VisualStudioがインストールしてあるかで違いがあるのですかね ですかねぇ…。 YAmaGNZさんのお書きになったものだとコンパイル自体が通りませんでした。『アセンブリが不足している』と。 MinGWで C/C++をやっている時もリンク順で揉めることがあったので、 念のためにmain.csよりもMainForm.csを前に置いてreferenceの直後にやったところ、コンパイル自体が通りました。
guest

0

SaveFileDialogの前に、文字コード選択のダイアログを出せばいいのでは

#まあ、文字コード選択付きのSaveFileDialog(のようなもの)を自作するってのもテですが

投稿2021/08/09 08:11

編集2021/08/09 08:12
y_waiwai

総合スコア87749

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

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

dodox86

2021/08/09 08:15

いえそういう話ではなく、 > Windows付属のメモ帳のような『文字コード』をユーザが指定できるようにしたいのですが、これは可能でしょうか。 メモ帳の「名前を付けて保存(A)...」メニューで出るダイアログボックスに、.NETで使えるSaveFileDialogが似ているから、SaveFileDialogで文字コード指定ができないか、と言う質問なのだと思います。
BeatStar

2021/08/09 08:22

ご回答ありがとうございます。 意図としてはdodox86さんの仰ることそのものです。 一応、別途用意すること自体は頭の片隅にありましたが、ユーザー目線で考えると煩わしいかなぁと思ったので…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問