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

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

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

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

WPF

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

Q&A

解決済

3回答

1681閲覧

WPF(C#)で作成したアプリケーションを関連付けを行ったファイルから起動する方法

KKEENN

総合スコア12

C#

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

WPF

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

0グッド

0クリップ

投稿2019/06/10 23:51

編集2019/06/11 01:07

前提・実現したいこと

WPF(C#)にて開発を行っています。
上記で作成したアプリケーション(アプリケーション名「WPF.exe」)
では、ファイルの関連付けを行いexe起動の他に
関連付けたファイル(拡張子が「ファイル名.abc」をダブルクリックした場合にも起動
するように作成しております。

当アプリでは「ファイル名.abc」にアプリの情報を保存しております。
アプリを起動する場合「ファイル名.abc」を読込処理を行う関係上
「ファイル名.abc」の指定が必須となります。

そのためアプリを開き「ファイル名.abc」を選択するというオペレーションだけではなく
「ファイル名.abc」を直接実行しアプリを起動とする方式を取り入れたいと考えております。

発生している問題・エラーメッセージ

exeをたたいて実行した場合は問題なく動作するのですが
関連付けたファイル(拡張子が「ファイル名.abc」をダブルクリックした場合に
「クラス名タイプの初期化子が例外をスローしました」と例外が発生します。

関連付けたファイル(拡張子が「ファイル名.abc」がカレントディレクトリになっていると考え
以下を設定しましたがそれでも解決に至っていない状況です。
System.Environment.CurrentDirectory
System.IO.Directory.SetCurrentDirectory

関連付けたファイル(拡張子が「ファイル名.abc」と同一フォルダにアプリケーションの
資材(dllなど)を配置すると動作するため実行ディレクトリなどの設定が
漏れているようなのですが実行ディレクトリの設定方法などどのように行えばよろしいでしょうか?

コード

/// <summary> /// App.xaml の相互作用ロジック /// </summary> public partial class App : Application {' public App() {' try { var cmd = System.Environment.GetCommandLineArgs(); string exePath = cmd[0]; string startupname = System.IO.Path.GetFileName(exePath); string startupPath = System.IO.Path.GetDirectoryName(exePath); if (cmd.Length > 1) {' // 関連付けファイルから起動された場合の処理 System.Environment.CurrentDirectory = startupPath; System.IO.Directory.SetCurrentDirectory(startupPath); // 以下グローバル変数参照時に「クラスGlobalVariableタイプの初期化子が例外をスローしました」と例外発生 GlobalVariable.ProjectWorkPath = cmd[1]; } else { GlobalVariable.ProjectWorkPath = string.Empty; } GlobalVariable.db = new DataAccess.DataAccessor(); } catch (System.Exception ex) { MessageBox.Show(ex.Message); MessageBox.Show(ex.StackTrace); } }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/06/11 00:02 編集

そういうことをする元々の目的はなんでしょうか? (XY 問題の Y を質問されているような気がするのですが・・・)
KKEENN

2019/06/11 00:09

ご回答ありがとうございます。 現在作成中のアプリはアプリで登録した情報を「ファイル名.abc」と言うファイルに保存しているめ アプリを使用するためには「ファイル名.abc」が必須となります。 そのためアプリ起動時に保存した情報「ファイル名.abc」を必ず選択しなくてはならないのです。 そのため選択するのではなく関連付けを行い「ファイル名.abc」をダブルクリックし起動とする 方式も取り入れたいと考えております。
takabosoft

2019/06/11 00:19

> 「クラス名タイプの初期化子が例外をスローしました」と例外 これはどこで発生しているのでしょうか?コードを提示してください。
KKEENN

2019/06/11 00:54 編集

引き続きのご回答に感謝いたします。 以下コードとなります。 <code> /// <summary> /// App.xaml の相互作用ロジック /// </summary> public partial class App : Application {' public App() {' try { var cmd = System.Environment.GetCommandLineArgs(); string exePath = cmd[0]; string startupname = System.IO.Path.GetFileName(exePath); string startupPath = System.IO.Path.GetDirectoryName(exePath); if (cmd.Length > 1) {' // 関連付けファイルから起動された場合の処理 System.Environment.CurrentDirectory = startupPath; System.IO.Directory.SetCurrentDirectory(startupPath); // 以下グローバル変数参照時に「クラスGlobalVariableタイプの初期化子が例外をスローしました」と例外発生 GlobalVariable.ProjectWorkPath = cmd[1]; } else { GlobalVariable.ProjectWorkPath = string.Empty; } GlobalVariable.db = new DataAccess.DataAccessor(); } catch (System.Exception ex) { MessageBox.Show(ex.Message); MessageBox.Show(ex.StackTrace); } } </code>
退会済みユーザー

退会済みユーザー

2019/06/11 00:41 編集

> そのため選択するのではなく関連付けを行い「ファイル名.abc」をダブルクリックし起動とする 方式も取り入れたいと考えております。 個人的意見ですが、それはやっぱり XY 問題の Y だと思います。「アプリで登録した情報」というののが具体的にどういうものか不明ですが、Settings ファイルとか Resouces.resx ファイルが使えればそれを使った方がよさそうな気がします。
退会済みユーザー

退会済みユーザー

2019/06/11 00:40

コードを書く場合は質問欄を編集して、そこで ``` と ``` で囲って(インデントされて見やすくなるようにして)追記してください。インデントされてないコードは多分ほとんどの人は読む気がしないと思います。閲覧者に読んでもらえないと話が始まらないわけですから、読んでもらえる努力をしましょう。 あと、質問者さんが上のコメント欄の 2019/06/11 09:09 に書いた本来の理由も回答欄を編集して最初の方に追記していただければと思います。
takabosoft

2019/06/11 01:05

カレントディレクトリが違うとDLLインポート(?)の処理に失敗したどこかのクラスがSystem.TypeInitalizationException例外を投げるって感じなんでしょうかね。
KKEENN

2019/06/11 01:13

諸々ご指摘ありがとうございます。 カレントディレクトリ(System.Environment.CurrentDirectory )には当アプリで使用するdllは全て 配置されていますがご認識の通りクラス参照にてそんなものないよと言った感じで例外となっているようです。 dllなどを関連付けを行った「ファイル名.abc」と同じディレクトリに配置するとご機嫌に動きます。 そのためSystem.Environment.CurrentDirectory以外にも実行ディレクトリなどが を変更する何かが他にあるのかと言ったところで悩んでおります。
Zuishin

2019/06/11 01:33

> クラス参照にてそんなものないよと言った感じで例外となっているようです。 そんな情報はどこにもありませんが。
Zuishin

2019/06/11 01:39

私は日常で人に物を尋ねる時には、必要となりそうな資料をまとめて相手に見せます。あなたは違うのですか? それとも、日常で顔を合わせるときにはそれをしても、顔の見えない相手はバカにして、言われていないことはなるべくせずに済ませる方針ですか?
KKEENN

2019/06/11 01:39

ソースコードの以下個所となります。クラス「GlobalVariable」の初期化に失敗 // 以下グローバル変数参照時に「クラスGlobalVariableタイプの初期化が例外をスローしました」と例外発生 GlobalVariable.ProjectWorkPath = cmd[1];
Zuishin

2019/06/11 01:41

「そんなものないよと言った感じの例外」ではありません。GlobalVariable というクラスの初期化に失敗しているという例外です。
Zuishin

2019/06/11 01:43

名前から察するに、グローバル変数を保持しているクラスだと思いますが、グローバル変数を使うことによって依存関係がグチャグチャになっている可能性もあります。
guest

回答3

0

カレントディレクトリの設定場所(=関連付けされたファイルのパスから自身のEXEのパスに戻す箇所)
がApp()にあるのが原因と思われます。

エントリポイントであるMainメソッドの中でセットし直すようにしてください。

※WPFではデフォルトだとMainが自動生成されてしまい触れませんが、
App.xamlのプロパティを「page」にすると自動生成が無くなり、
自身でApp.xaml.cs上に書けるようになります。

投稿2019/06/11 03:45

NORIII

総合スコア14

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

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

0

GlobalVariable クラスの初期化部分が間違っているので直してください。

投稿2019/06/10 23:57

編集2019/06/11 01:04
Zuishin

総合スコア28656

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

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

KKEENN

2019/06/11 00:00

関連付けしたファイルから起動された場合以下コードにて exeのディレクトリを取得してカレントディレクトリに設定を行っています。 string exePath = cmd[0]; string startupPath = System.IO.Path.GetDirectoryName(exePath); System.Environment.CurrentDirectory = startupPath; System.IO.Directory.SetCurrentDirectory(startupPath);
Zuishin

2019/06/11 00:04

少しのミスで動かなくなりますから、読み込む部分の間違っているところを全部直してください。
guest

0

ベストアンサー

手元でDLL参照やdllimportを使って関連付けからEXEを呼び出してみてもうまく再現しないので、別の方法をとりあえず提示してみます。

Launcher.exeのような関連付けを受ける専用のEXEを作成してください(試すだけならバッチファイルでも良さそう)。
その中では
0. カレントディレクトリを本家EXEのパスに設定する
0. 本家のexeをキックする(もちろん引数に自分が受け取ったファイルをそのまま渡す)

といった処理を書いてください。

これで

dllなどを関連付けを行った「ファイル名.abc」と同じディレクトリに配置するとご機嫌に動きます。

と似たような状況を作れるのではないかと思われます。

検証していないので動いたらラッキーぐらいな感覚です。
正しき解決方法は、もうちょっと情報が無いと出せそうにありません。

投稿2019/06/11 01:46

takabosoft

総合スコア8356

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

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

KKEENN

2019/06/11 01:56

takabosoft様 ご回答ありがとうございます。 提示いただいた内容ついて実行済でこちらは問題なく動きます。 一般的に「Launcher.exeのような関連付けを受ける専用のEXE」のようなものを作成するのか それとも私が現在ご質問させているように該当のexeを直接関連付けについてどのようにするのが正解なのでしょうか?
takabosoft

2019/06/11 02:19

それはもちろんエラー原因の究明が一番良いです。ただ、納期などもあるでしょうから、その辺は上司や同僚と相談して決めてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問