別アプリを起動すると異常終了する

[戻る]
らっきー 2007/07/23(月) 10:47:49
お世話になります。
自分のプログラム上からTifファイルをオープンするのに、
標準でインストールされている「イメージング」を呼び出そうとしています。
ネットの情報を参考に、ShellExecute()とCreateProcess()と2通りの方法が
あるのがわかり、ソースを書いて実行してみたところ、どちらの場合もイメージング
の起動直後に自分のアプリが異常終了してしまいます。
(Debug Assertion Failed!!とダイアログが出ます。)

起動したイメージングにはちゃんと指定したイメージが表示され、
問題なく動いています。何がいけないのでしょうか?
またこの2つの関数の違いが良くわかりません。
Imagingは起動しっぱなしで良くImagingの終了はユーザに任せて、
自作のアプリ側に操作を戻したいと思ってます。
(Imagingが終らなくてもロックしない)
----------------------------------------------------------------------
// パターン1

    CString CommandStr;
    CommandStr = "C:\\Program Files\\(中略)\\kodakimg.exe "; // Imagingのパス

    HINSTANCE ret = ShellExecute(this->m_hWnd,
                                 "open",
                                 CommandStr,
                                 strOpenFileName, // 開きたいTifファイル名
                                 NULL, SW_SHOW);

    if((int)ret <= 32) AfxMessageBox("起動に失敗");
----------------------------------------------------------------------
// パターン2

    CString CommandStr;
    CommandStr = "C:\\Program Files\\(中略)\\kodakimg.exe "; // Imagingのパス
    CommandStr += strOpenFileName; // 開きたいTifファイル名(フルパス)

    STARTUPINFO SInfo;
    PROCESS_INFORMATION PInfo;
    char *Path = CommandStr.GetBuffer(CommandStr.GetLength() + 1);
    GetStartupInfo(&SInfo);
    
    CreateProcess(0, Path, 0, 0, FALSE, DETACHED_PROCESS,
                  0, 0, &SInfo, &PInfo);
---------------------------------------------------------------------

環境はWindows2K、VC++6.0で開発しております。
宜しくお願い致します。

らっきー 2007/07/23(月) 10:51:05
すみません。自己レスです。

>またこの2つの関数の違い

http://rararahp.web.fc2.com/vc/200303/03030129.html

こちらの掲示板の中に回答がありました。

異常終了の件宜しくお願い致します。

Blue 2007/07/23(月) 10:55:36
>パターン2>char *Path = CommandStr.GetBuffer(CommandStr.GetLength() + 1);
に対応するReleaseBufferをCreatePorcessの後に入れないとCommandStrを変更したり
するときに正しい処理が出来なくなります。

>(Debug Assertion Failed!!とダイアログが出ます。)
はどこで発生していますか?
デバッグモードで実行して、続行を選択してASSERTと書かれている行を特定して、
コールスタックウィンドウを使って、自分で書いているソースのどこが問題なのか
を調べてみてください。

らら 2007/07/23(月) 13:03:34
私は時々、パターン1の方を使いますが、普通に動いていますよ。
メモリがちゃんと足りてないと、大きなメモリを使うアプリとの共存ができなくなりこともあり
ますが、大丈夫ですか?
いずれにせよ、Blueさんと同じ意見で、別アプリ起動後の処理をデバッガで追ってみてどこで
落ちるのか確認したほうがよいと思います。

らっきー 2007/07/23(月) 13:13:42
[[解決]]
Blueさんレスありがとうございます。

この処理を行った場合、後続の処理は行わない筈
だったのですが、実行していたためにぶっとんでた様です。
ブレークポイントを間違えた所に張っていたため気がつきません
でした。お恥ずかしい限りです。

ちなみに、
>ReleaseBufferをCreatePorcessの後に入れないとCommandStrを変更したり
>するときに正しい処理が出来なくなります。

と、ありますがこれって、得たポインタを使って中身を書き換えたりする場合に
はReleaseBuffer使わないと駄目なんですよね?

<MSDN>
GetBuffer関数から返されるポインタを使って文字列の内容を変更するときは、次に他の
CStringメンバ関数を使う前に、ReleaseBuffer関数を呼び出す必要があります。
</MSDN>

今回の件では引数のポインタとしてしか使用しない為、敢えて書かなかったのですが、
書いたほうが良いのでしょうか?
もっとも、CreateProcessの引数はLPCTSTRでないのでいじられる可能性は0じゃ
ないとは思いますが・・・。

お騒がせして申し訳ありません。
解決とさせて頂きます。m(__)m

Blue 2007/07/23(月) 13:20:54
本当にいじられる可能性がないのであれば、const_castではずすのが普通でしょう。

>もっとも、CreateProcessの引数はLPCTSTRでないのでいじられる可能性は0じゃ
>ないとは思いますが・・・。
私もそう思うので、ReleaseBufferは入れて置くべきだと思いますよ。
(GetBuffer(SetLength)とReleaseBufferは対で使うべき)


参考)CStringのconst_castについて触れている過去ログ
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200606/06060020.txt

Blue 2007/07/23(月) 13:25:55
><MSDN>
>GetBuffer関数から返されるポインタを使って文字列の内容を変更するときは、次にの
>CStringメンバ関数を使う前に、ReleaseBuffer関数を呼び出す必要があります。
></MSDN>
>
>今回の件では引数のポインタとしてしか使用しない為、敢えて書かなかったのですが、
>書いたほうが良いのでしょうか?

について

CStringのGetBuffer関数について
http://forums.belution.com/ja/vc/000/243/88s.shtml

というスレが別の掲示板でありました。

古いスレッドには追加発言できません。