tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル他アプリを起動するサービスを作れますか?
記事No7374
投稿日: 2008/04/21(Mon) 11:14
投稿者ヤマザキ
ヤマザキと申します。よろしくお願いします。
VB 6.0 にて何年もプログラミングをしてきましたが、遅まきながら VB2005 に
移行する決意をして1か月目です。VB6.0 で実現できなかった処理を中心に学習中です。

VB2005 (Professional Edi.) で Windows アプリケーションを作成し、
ボタンイベント中にて下記の処理を実行します。
1.FindWindow で他アプリケーションの動作状況を確認する。
2.稼動していなければ System.Diagnostics.Process.Start で強制起動する。
これは正常動作しました。

同一処理を実行する Windows サービスを作成し、WinXP Pro (SP2) のPCに
インストールしましたが、目的通りに動作しません。
サービス中では System.Timers.Timer で定期的に上記処理を実行します。
同一タイマー中でログファイルを出力させており、そのログファイルの内容から
タイマーが稼動していることは確認できております。
またサービスの開始・停止時や、稼働中に Windows イベントログにエラーは
あがりません。

サービスにて FindWindow, Process.Start を使用することができないのでしょうか?
教えていただきたくお願いします。
使用可能との回答をいただいた場合は、ソースや、詳しい動作状況を
報告しますので、あらためてご助言いただきたく思います。

[ツリー表示へ]
タイトルRe: 他アプリを起動するサービスを作れますか?
記事No7380
投稿日: 2008/04/22(Tue) 07:36
投稿者y4yama
> サービスにて FindWindow, Process.Start を使用することができないのでしょうか?

聞く前に、まずは Process.Start だけ使用できるかどうか確認テストをされてみたら
問題の切り分けができそうですが・・・

[ツリー表示へ]
タイトルRe^2: 他アプリを起動するサービスを作れますか?
記事No7381
投稿日: 2008/04/22(Tue) 09:23
投稿者ヤマザキ
> > サービスにて FindWindow, Process.Start を使用することができないのでしょうか?
>
> 聞く前に、まずは Process.Start だけ使用できるかどうか確認テストをされてみたら
> 問題の切り分けができそうですが・・・

y4yama 様
アドバイスありがとうございます。
では、長文になりますが、私がテストした内容について書かせていただきます。
そうすれば、サービスにて FindWindow の使用可否, Process.Start の使用可否が
問題なのか、コーディングの問題なのかの切り分けもできますね。
サービスを作成するのが初めてなのでコーディングに問題ありの可能性大ですし。

[開発マシン]
WinXP Pro SP2
VS2005 Pro(日本語 SP1 適用)

[サービスインストール先端末=開発マシン]
.NET Framework 2.0 SP1
.NET Framework 2.0 SP1 Language Pack - JPN
.NET Framework 3.0 SP1
.NET Framework 3.0 SP1 Language Pack - JPN
(他、1.1, Compact Framework 2.0 等)

[不具合内容]
1.
監視しているアプリケーションが動作していなくても、
FindWindow の返り値が 0 にならない。
2.
Start しようとしているアプリケーションが起動しない。

[ソース(抜粋)]
Public Class myService
    <System.Runtime.InteropServices.DllImport("user32.dll", _
       CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
    Private Shared Function FindWindow( _
       ByVal lpClassName As String, _
       ByVal lpWindowName As String) As IntPtr
    End Function

    Private LoopTmr As System.Timers.Timer = Nothing    ' 監視用タイマー

    ' サービス開始
    Protected Overrides Sub OnStart(ByVal args() As String)

        ' サーバベースタイマインスタンス作成
        LoopTmr = New System.Timers.Timer

        With LoopTmr
            .Interval = 5000
            .Enabled = True
        End With

        ' イベントハンドラの関連付け
        AddHandler LoopTmr.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf Me.myTimer_Elapsed)
    End Sub

    ' タイマー処理
    Private Sub myTimer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs)

        ' 動作確認
        Dim hwnd As IntPtr
        hwnd = FindWindow(vbNullString, "無題 - メモ帳")
        Call WriteToLog(hwnd)

        ' 起動
        ' If (hwnd = 0) Then    ' 本来ならコメントアウトしないが、試験のため
                System.Diagnostics.Process.Start("C:\WINDOWS\system32\notepad.exe")
        ' End If
    End Sub

End Class

[特記]
・上記ソース中、OnStop, WriteToLog メソッドは略しましたが実際には存在します。
  WriteToLog メソッドは稼動時刻(Now)と hwnd 値をテキストファイルに出力します。
・サービスの作成に際し、下記チュートリアルを参考にしました。
 「http://msdn2.microsoft.com/ja-jp/library/zt39148a.aspx
 サービス名や処理内容は変更し、サービスの StartType=Manual としましたが、
 それ以外はチュートリアルに従ったつもりです。
・サービスインストール後、コンピュータの管理画面のサービス一覧にて
 インストールしたサービスが存在します。開始・停止でも、稼働中も
 Windows イベントログにエラーはあがりません。
・稼働中 myTimer_Elapsed 中の WriteToLog にて、ログファイルには
 タイマーが稼動した時刻、hwnd が随時追加出力されていきます。
 ただし "無題 - メモ帳" が稼動していない時でも、hwnd の値は
 0以外の値になります(例:CStr(hwnd) = 10224714)。
・サービスを実行しているプロセスにデバッガをアタッチすることによる
 サービスのデバッグ方法は、現時点では実施していません。
・Windows アプリケーションを作成し、myTimer_Elapsed 中の処理を
 ボタンクリックイベント中で実行させると、"無題 - メモ帳" が
 稼動していなければ hwnd=0 になり、強制起動も成功しました。

説明が不足している点についてはご質問下さい。
また「これを試してみた方がいい」のアドバイスも歓迎しますのでよろしくお願いします。

[ツリー表示へ]
タイトルRe: 他アプリを起動するサービスを作れますか?
記事No7388
投稿日: 2008/04/22(Tue) 17:09
投稿者y4yama
興味を持って拝見させていただきました。
ぐぐってみると、
http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-23747.htm

とかのHintがありますが・・・

[ツリー表示へ]
タイトルRe^2: 他アプリを起動するサービスを作れますか?
記事No7390
投稿日: 2008/04/22(Tue) 18:07
投稿者ヤマザキ
> 興味を持って拝見させていただきました。
> ぐぐってみると、
> http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-23747.htm
>
> とかのHintがありますが・・・

y4yama様
解決しました。ありがとうございます。
まさしくこれでした。

サービス稼働中 FindWindow の値が0でない時にタスクマネージャの
プロセスで見ると、画面に表示されていない notepad.exe がいました。
notepad.exe を「プロセスの終了」にて終了させると、FindWindow=0 となり、
再度 notepad.exe がプロセスの一覧に出現しました。
サービスのプロパティを「デスクトップとの対話を許可する」に変更したところ
メモ帳がデスクトップに表示されるようになりました。

よって FindWindow, Process.Start のどちらも、Windows サービスで使用可能でした。
またサービスから他アプリを起動するには、サービスのプロパティを
「デスクトップとの対話を許可する」に変更する必要がある事がわかりました。

今回は趣味的に作成してみたのですが、実際に使用するには(教えていただいたページに
もありますように)未ログオン時にどうあるべきか、仕様の検討が必要ですね。

y4yama様、ありがとうございました。

[ツリー表示へ]