tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルProcessによるアプリの起動について
記事No11204
投稿日: 2014/01/23(Thu) 19:18
投稿者しん

ファイルの拡張子に紐ずくアプリケーションを起動させたく悪戦苦闘しています
さらに起動したアプリは他のウィンドウより最前面に固定表示させたいと思っています

ネットでは NOTEPAD.EXE を起動するサンプルがありこれを試してみると正常動作するのですが
EXCEL や WORD 等ほかのアプリファイルを起動するとエラーが発生したりしてうまくいきません
ですが拡張子を判断して下記のコーディングで何とか思い通りの動作をするようになりました

ところが PDFファイルの場合起動するのですがウィンドウの最前面に固定できなくて
他のウィンドウをクリックしたりすると、他のウィンドウの下に隠れてしまったりします

どのようにしたらPDFファイルを最前面に固定させる事ができますでしょうか
または拡張子ごとにロジックを書かなくてもいいようなコーディングはないでしょうか

=====================================================================
Dim strFName As String = ""
Dim strExt As String = ""

strFName = XXXXXX.XXX
'ファイルパスから拡張子を取得します
strExt = System.IO.Path.GetExtension(strFName)

If strFName.Trim <> "" Then
    Try
        Dim p As New Process
        p = System.Diagnostics.Process.Start(strFName)
        Select Case StrConv(strExt, VbStrConv.Uppercase)
            Case ".TXT", ".XLS", ".XLSX"
                p.WaitForInputIdle()
                SetWindowPos(p.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
            Case ".DOC"
                p.WaitForExit()
            Case Else
                SetWindowPos(p.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
        End Select
    Catch
        Return
    End Try
End If


====================
環境
VB2010

[ツリー表示へ]
タイトルRe: Processによるアプリの起動について
記事No11205
投稿日: 2014/01/24(Fri) 13:34
投稿者魔界の仮面弁士
> Dim p As New Process
> p = System.Diagnostics.Process.Start(strFName)
New が余計ですよ。


> または拡張子ごとにロジックを書かなくてもいいようなコーディングはないでしょうか

残念ながら無理だと思います。そもそも、何の画面も表示させずに動くタイプの
アプリもありますし、既存のウィンドウ内で開くものもあれば、起動時に
複数の画面が開かれる物もあるわけですから。

あるいは PBrush.exe や write.exe のように、実際に使われる本体アプリを起動し、
自分自身は即座に終了してしまうタイプのソフトもあります(PDF 閲覧ソフトにも、
このタイプの物があります)。この場合、起動されたプロセスはすぐに閉じられるため、
p.WaitForInputIdle() や p.MainWindowHandle が意味を成さなくなります。

[ツリー表示へ]
タイトルRe^2: Processによるアプリの起動について
記事No11206
投稿日: 2014/01/27(Mon) 11:16
投稿者しん

魔界の仮面弁士さん レスをありがとうございます

> > Dim p As New Process
> > p = System.Diagnostics.Process.Start(strFName)
> New が余計ですよ。

ご指摘ありがとうございます


> > または拡張子ごとにロジックを書かなくてもいいようなコーディングはないでしょうか
>
> 残念ながら無理だと思います。そもそも、何の画面も表示させずに動くタイプの
> アプリもありますし、既存のウィンドウ内で開くものもあれば、起動時に
> 複数の画面が開かれる物もあるわけですから。
>

私の質問のしかたが曖昧だったようです
すみません

それでは質問を変えまして
AcrobatReader を Process で起動した場合、ウィンドウの最前面に固定する方法は
ありませんでしょうか

よろしくお願いいたします

[ツリー表示へ]
タイトルRe^3: Processによるアプリの起動について
記事No11207
投稿日: 2014/01/27(Mon) 14:28
投稿者魔界の仮面弁士
> AcrobatReader を Process で起動した場合、ウィンドウの最前面に固定する方法は
AcrobatReader ではなく、
Adobe Reader ですよね。

Adobe Acrobat Reader はバージョン 5.x が最後のバージョンであり、
6 以降では Adobe Reader という製品名に改名されています。

で、これもまた、バージョンによって微妙に動作が異なりますし、
シェルの設定(PDF ハンドラー)によっても変わってきます。


とりあえず、現行バージョン(Adobe Reader XI)の動きをみたところ、

(1)最初に開かれたドキュメントであれば、Process.Start の戻り値で
 そのまま管理できる。MainWindowHandle プロパティからは HWND が返され、
 Id プロパティからは PID が返されるし、WaitForExit メソッドを呼べば
 リーダーが閉じられるまで待機される。

(2)二番目以降に開かれたドキュメントの場合、AcroRd32.exe は起動された途端に
 終了するとともに、別プロセスで AcroRd32.exe が再起動されて開かれる。
 最初の Process は、HasExited プロパティが True を返すことになるし、
 WaitForExit メソッドを呼び出しても、既に終了済みのため待機しない。
 なお、Process クラスの Id プロパティは、起動したときの PID を返す。

という動作となっているようです。


厄介なのは後者です。起動したプロセスを追うことができないのであれば、
現在起動している Reader を列挙するために
 Process.GetProcessesByName("AcroRd32")
を使うという手もありますが、exe が再起動するまでのタイムラグがあるので
有効な MainWindowTitle が得られるまで、一定時間は検索を続けるなどの
対処が必要かと思います。

[ツリー表示へ]
タイトルRe^4: Processによるアプリの起動について
記事No11208
投稿日: 2014/01/28(Tue) 10:41
投稿者しん
魔界の仮面弁士様

ありがとうございます

WaitForExit メソッド を使う事により無事、最前面に PDFファイルを表示する事が
できました

大変感謝です!!

[ツリー表示へ]