トップ回答者
RibbonアプリとWindows 10 Annivarsary Update

質問
-
お世話になります。
Visual C++ 2010 Feature PackにてRibbonインターフェイスをもつアプリケーションを作成しております。
Windows 10 Annivarsary UpdateされたOS上で、
myappに関連づいているファイルのダブルクリックを行うと、起動に失敗する現象が起きました。
※「myappにより情報を回復しております」ダイアログがちらっと表示され消えて終わってしまいます。通常起動(スタートボタンから)からは、正常に起動されます。
落ちている箇所は、CMFCRibbonBar::LoadFromResource()関数でした。
BOOL bCreate = m_wndRibbonBar.Create(this);
if(bCreate){
bLoadResource = m_wndRibbonBar.LoadFromResource(IDR_RIBBON1);//ここで落ちている。
}LoadFromResource関数の前に MessageBox()を置くとなぜか失敗しません。
※但し、DDEには失敗してファイルは開きませんが、これは想定内です。
BOOL bCreate = m_wndRibbonBar.Create(this);
if(bCreate){
MessageBox(_T(""),_T(""));
bLoadResource = m_wndRibbonBar.LoadFromResource((UINT)IDR_RIBBON1);//ここで落ちている。}
ちなみに、Windows 10 Annivarsary Updateのビルド前に戻すを行うことで、
関連づいたファイルをダブルクリックしても正常に起動されます。
解決方法があれば教えてください。
回答
すべての返信
-
VS2015 Update3 & 最新パッチで、同じような感じで作ってみましたが、特に問題なく動作しています。
AppWizardで吐き出し、リソースエディタでリボン上にフォントコンボを2個貼っただけです。
関連付けはどのように行っていますか?
テストはインストールしたわけではなく、管理者権限を与えて自己登録しただけなので、そのあたりに違いがあるかもしれません。
実際にデバッグして、MFCのソースに潜りどこで落ちているか(例外が出た時点でJustInTimeでデバッグ可能)を調査したほうがいいかもしれません。
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx
-
動作しますか。。。
私の開発環境はWindows7+VisualStudio2015Professional(14.0.25425.01) UPDATE3
です。関連付けも管理者権限で実行での自己登録です。
但し、Windows7+VisualStudio2015UP3で作成したEXEを
Windows 10 Annivarsary Updateで実行した結果です。
ただ、Windows 10 Annivarsary Update+VisualStudio2010Sp1でも
同じ結果となるので、こちらで調査しているのですが、
エラーになってもJustInTimeは起動しません。
このJustInTimeはどのようなときに起動しますか?
ためしにNULL参照してみたのですが、JustInTimeデバッガーが実行しません。
教えてください。
オプションでのデバックのjust-In-Timeはすべてチェックが入っています。
- 編集済み Brillia 2016年11月4日 5:02
-
私のビルド、実行環境は、Win10(Build14955なのでひとつ前のIP-FastRing)+VS2015 Update3 + 最新パッチ + 最新Win10SDKインストール環境です。
SDKはたぶん関係ないと思いますが、VSのパッチの最新版は影響するかもしれません。
Just-In-Timeですが、通常は、OSがエラーを検出できた場合(ランタイムの abort() での終了は、OS的には正常系の終了処理を通るので、エラー検知されない)に発動します。
通常は、ハンドルされない例外などで発動します。
ちなみに、落ちるという動作はどういう動作でしょうか?
OSか何も通知されずに、ひっそりとプログラムが終了しますか?
それともメッセージボックスなど、何かしら画面表示がでますか?
何か画面に出るならそれをヒントにできるかもしれません。
ちなみに、関連付けはどういう形で行っていますか?
%1 であれば、デバッグ実行時にパラメータとして、ドキュメントファイルパスをセットすれば、そのままデバッグ実行できます。
おそらく再現できると思います。
/dde であれば、/dde をつけてデバッグ実行した状態で、エクスプローラで、ファイルをダブルクリックします。
これで、デバッグ実行しているアプリにDDE経由でファイルパスが送られてきます。
デバッガ経由で起動しているという点が異なる点を除けば、通常のアプリケーション実行シーケンスをほぼ100%トレースします。
どうしても、Just-In-Time でのデバッグができない場合はそれも考えてみてください。
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx
-
Windows10 Version 1607(OSビルド 14393.223)にてテストしております。
KB3197954のアップデートができそうなので試したらアップデートに失敗するので、これを今調査中です。
>ちなみに、落ちるという動作はどういう動作でしょうか?
ファイルをダブルクリックすると何かがちらっと表示されて起動が終了しているようです。
なんとかキャプチャに成功したのですが、「MyAppにより情報を回復しています」というダイアログが表示されているようでした。>/dde であれば、/dde をつけてデバッグ実行した状態で、エクスプローラで、ファイルをダブルクリックします。
アプリケーションが起動した後で、ファイルのダブルクリックでは正常に起動するのです。
アプリケーションが起動していない状態からのファイルのダブルクリックのみが起動に失敗します。p.s.
まずWindows10の最新アップデートを行ってからテストを行ってみようと思っています。
また報告させていただきますが、何回してもアップデートに成功しないので。。。。VisualStuido2015でも最新にしてテストをしてみようと思います。
-
Windows10 Version 1607(OSビルド 14959.1000)+Visual Studio 2015 の Visual C++ 再頒布可能パッケージ
Visual Studio Professional 2015 Version 14.0.25431.01 on Windows7
MFCApp(x86)
-MDI
-Project形式:Office
-visual スタイルと色:Windows7
-共有DLL
-ナビゲーションペイン:無効
-キャプションバー:無効※一部コードの修正
ファイルのダブルクリックをすると、「コマンドの送信エラー」が発生するので、次の4行を、「// メイン MDI フレーム ウィンドウを作成します。」の上に移動※コマンドの送信エラーは、Windows7,Windows10ともに出ます。
// DDE、file open など標準のシェル コマンドのコマンド ラインを解析します。
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// DDE Execute open を使用可能にします。
EnableShellOpen();
RegisterShellFileTypes(TRUE);■テスト内容:関連づいたファイルのダブルクリック
・フォントコントロールなし: Windows7,Windows10ともに正常起動。
※Windows10はなぜか10回に5回、「動作は停止しました」ダイアログが表示され失敗する。・フォントコントロール1つ: Windows7,Windows10ともに正常起動。
※Windows10はなぜか10回に5回、「動作は停止しました」ダイアログが表示され失敗する。・フォントコントロール2つ: Windows7正常起動,Windows10はタスクバーに何かがちらっと表示されて起動しない。
やはり、フォントコントロール2つのとき動作しません。
p.s.
動作するモジュールがほしい。。。確認したい。。。
また、Windows10 Version 1607(OSビルド 14959.1000)ですが、グラフィックがおかしくなって、スタートボタンをおすと、文字のところが白い四角が表示されるだけになってしまった。
なにが書いてあるのかわからない。。。。
- 編集済み Brillia 2016年11月8日 7:57
-
私が試したときは、テンプレのコードをそのまま使って実行してます。
リボンにはしていますが、
>-ナビゲーションペイン:無効
>-キャプションバー:無効ここの部分は設定していません。あと、ファイルのダブルクリック対応のために適当な拡張子を作っています。
それよりも気になるのは
>※一部コードの修正
>ファイルのダブルクリックをすると、「コマンドの送信エラー」が発生するので、次の4行を、「// メイン MDI フレーム ウィンドウを作成します。」の上に移動のところ。
試しに動かした見たプログラムではここは変更していません。
その部分に原因があるなどはないでしょうか?
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx
-
確かに、戻してみると起動しましたが、ファイルが開いた状態になっていません。
「ファイルは開いた状態となっていますでしょうか?」
なぜかだかわかりませんが、「コマンド送信のエラー」も表示しなくなりましたが、
ファイルが開いた状態となっていないので、おそらく失敗しているのではと思います。このモジュールを「Windows7」で動かしてみたのですが、「コマンド送信のエラー」が表示され、
ファイルが開いた状態になっていません。しかし、「コマンド送信のエラー」を回避するためには、移動するしかないのです。。。
ファイルが開いた状態となっていない場合、それはそれで問題なので、
確認していただけますでしょうか。 -
元の状態で動かしてみました。確かにファイルを開いてくれませんね。
動きをみる限りでは、メインウィンドウの構築(LoadFrame 内)で、メッセージポンプが動いているような気がします。
恐らくそれが原因でDDEコマンドをうまく受けとれていないんだと思います。ただ、だとするとそれを回避するのはかなり難しいんですよね。。。
段取り的には
- LoadFrame から戻ってくる時点で非表示のままになるように調整する。
- OnCreateの処理を別途メソッドとして用意しておき、LoadFrame の後で実行する
という段階を経て、最終的にうまく動くようになったら、1と2の間に EnableShellOpen() を入れればいいのかな?と思います。
まぁ思うだけで、実装してみたわけじゃないから何とも言えませんが。。。
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx
-
確認ありがとうございます。
「DDE通信はファルマネージャと直接やりとりを行っているが、
メッセージポンプが動いてしまうとメッセージ処理が優先されタイムアウトになり、
コマンド送信エラーが発生する。」という感じなのでしょうか?
それなら、LoadFrame()の前で、EnableOpen()を実行することで解決することになります。
現に、その対応で、
Windows7,Windows8,Windows10(OSBuild1607未満)では、ファイルのダブルクリックで正常(ファイル開く)に起動します。
また、Windows10(OSBuild1607以降)でも、フォントコントロールがリボンに設置されていない場合は、
正常(ファイル開く)に起動します。これは、OS側の問題としていいのか、アプリ側で対処すべきなのかどう判断するべきでしょうか。。。
-
DDEは、プロセス間通信を行うために、Windowsのメッセージを利用して送受信します。
アプリが、DDE通信できるためには
- 送受信するウィンドウがある
- 適切なDDEコマンドを処理する
- メッセージの受信が可能になっている
の3つができる必要があります。
このうち、1は、CFrameWnd の派生クラスのウィンドウを作成し、theApp.m_pMainWnd に設定されていることで成立します。
2は、EnableShellOpen を呼び出して、DDEコマンド反応用のデータを生成することで対応できます。
そして、最後の3は、AfxPumpMessage あるいは、CWinThread::Run() が呼び出される、または、MessageBox などのモーダルウィンドウ表示APIが呼び出されることで成立します。
ソースを見ていないので、これ以上はわかりませんが、CMFCRibbonBar の Create を行い、リボンバーが完全に初期化完了していない状態でDDEコマンドを処理してしまうと、MFC内部の処理で、リボンバーにアクセスする何かが発生してしまい、結果としてクラッシュするのではないか?と想像します(デバッグしていないので正直なところはあまりよく分かっていません)。
恐らく、この処理そのものが非常にタイトなタイミングで行われると発生するため、Windows10 で最適化が進んでいる今の実装だとエラーになってしまうのではないか?
と思います。
さて、対策。これはOSの問題ではなく、アプリケーション側の問題です。エラーの直接的な原因は、CMFCRibbonBar にあると思いますが、回避策自体があるかどうかわからないので、やはり前述した、OnCreate 処理をウィンドウ作成後(アプリケーションクラスの m_pMainWnd に代入した後)に行うようにしたほうがいいのかもしれません。
試行錯誤してみて、うまくいくタイミングなどがつかめればいいのですが、これにがっつりかかわれる時間は取れないので、少しあがいてみてください。
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx
-
まずテストで作ったモジュールですが、次のようにすることで、ダブルクリックで起動するようになりました。
ファイルも開いた状態です。(開発環境 VS2015)m_pMainWnd = pMainFrame; // 接尾辞が存在する場合にのみ DragAcceptFiles を呼び出します。 // MDI アプリケーションでは、この呼び出しは、m_pMainWnd を設定した直後に発生しなければなりません。 // ドラッグ/ドロップ オープンを許可します。 m_pMainWnd->DragAcceptFiles(); // DDE、file open など標準のシェル コマンドのコマンド ラインを解析します。 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // DDE Execute open を使用可能にします。 EnableShellOpen(); RegisterShellFileTypes(TRUE); pMainFrame->CreateRibbonBar();// OnCreate関数をコピー
ただ本来のアプリケーションで、同じように実装してみたのですが、ダメでした。
上記CreateRibbonBar()関数内の次の箇所で落ちているようです。
そして原因は、やはりフォントコントロールでした。(フォントコントロールを削除したら起動することで確認。)m_wndRibbonBar.LoadFromResource(IDR_RIBBON1);
ただ、この落ち方は初めに質問させてもらったちらっと何かが表示されて落ちたという感じではありません。
アプリケーション自体は表示され、リボンもフォントコントロールが配置されているタブまでは、表示されて落ちるという感じです。テストモジュールと異なるところは、実際のアプリケーションでは、EnableShellOpen()でシリアライズ等が実行されているからかなって。
本来のアプリケーションは、VS2010の開発環境でビルドしたものを、Windows10でテストしています。
今後の予定は、VS2015に開発環境に移行してテストしようと思っています。また結果報告させていただきます。ただ、ほかに試すべきなにかがあれば教えてください。。。。。。。。
-