3

VB .NET で簡単なシステム サービスを作成するのは簡単なことだと思いました。少年、私は間違っていました。まず、Windows.Forms.Timer を使用する必要があるという一般的な投稿を Google で見つけました。次に、コードを使用してタイマークラスからタイマーを派生させて機能させる必要があるという矛盾する情報を見つけました。次に、利用可能なさまざまな種類のスレッドを使用して、あらゆる種類の問題が報告されています。明らかな理由により、VS 2010 Just-in-Time デバッガーを使用してスレッドをデバッグすることはできません (ただし、これを行う別の方法があるかどうかはわかりません)。うわー、決定的なガイドがない場合、これがどれほど混乱するか...

私のプロジェクトは、一定の秒数以内に定期的に起動するアプリケーション ランチャー (cron に似ています) です。Process.Start() メソッドを使用しようとしています。最初の命令として Beep() 関数を使用し、最後の命令として Process.WaitForExit メソッドをブロックする Process.WaitForExit メソッドと共に Process.Start を使用しています。タイマーを使用してコードを実行していましたが、現在はスレッドを使用し始めています。実行に違いはありません。オーバーライドされた OnStart メソッドは開始されますが (デバッグを通じて確信しているように)、本番環境でサービスを開始しても、すべてのコードが無視されているかのように何も起こりません。OnStart メソッドにループとロジックを配置すると、開始されないプロセスが生成されます。私はそれがスレッドの問題であることを知っていますが、スレッドを使用することが必須でなければならないことも知っています。私は今、これを機能させる方法について唖然としています。

サービス クラスに加えて、MSDN からそのままコピーした ServiceInstaller と ProcessInstaller を実装しました。

これが私が使用しようとしているコードの一部です。これは、タイマーの代わりにスレッド内にロジックを実装しようとしているコードの現在の状態を反映しているだけであることに注意してください (これが最適です)。

    Dim config As String
    Dim configValues(2) As String
    Dim objReader As System.IO.StreamReader
    Dim interval As Integer
    Dim launchProcess As Process

    While True
        Beep()
        ' This sub runs every time the elapsed milli-seconds of the timer pass
        ' Sp add your code here.

        config = "30 c:\WiFiDropOutFix\start.vbs"

        Try
            objReader = New System.IO.StreamReader("C:\WiFiDropOutFix\config.txt")
            config = objReader.ReadToEnd
            objReader.Close()
        Catch ex As Exception

        End Try

        configValues = config.Split(New Char() {" "c})
        interval = Convert.ToInt32(configValues(0))

        If Not interval > 0 And Not interval < 61 Then
            interval = 10
        End If

        launchProcess = Process.Start(configValues(1))
        launchProcess.WaitForExit()

        Thread.Sleep(interval * 1000)

    End While
End Sub

リクエストによる私のOnStartコードは次のとおりです。

Protected Overrides Sub OnStart(ByVal args() As String)

    appLaunchLogicThread = New Thread(AddressOf appLaunchLogic)
    appLaunchLogicThread.Start()

End Sub

ティア。

4

2 に答える 2

1

サービス コントロール パネルに移動して、サービスのプロパティを編集し、「対話型サービス」または「デスクトップとの対話をサービスに許可する」というオプションを確認してください。新しいプロセスを起動して画面に表示しようとしている場合、このオプションが有効になっていない限り何も起こりません。

また、サービスのログオン資格情報を管理者に設定して、権限の問題ではないことを確認します。動作する場合は、問題を発見したことになります。

もう 1 つのヒント:すべての処理コードを、簡単にデバッグできる通常のアプリとして記述します。すべてのバグが解決され、コードに問題がないことを確認したら、それをサービスとして実装します

于 2012-04-05T19:57:52.383 に答える
0

わかりました、プロジェクトが機能しなかった理由の背後にある理由を見つけることができました。[STAThread] ディレクティブは、開始されたプロセスがサービス内で実行されるために必要であり、Main 関数の直前に配置する必要があると誰かが言ったのを見たのを覚えています。Codeproject はC# の Windows サービス用のcron プロジェクトを発行しており、このディレクティブを使用しています。この発行されたプロジェクトをもっと調べる必要がありますが、おそらく VB .NET では実装できないでしょう。この時点で、VB .NET Visual Studio Service テンプレートを介して Main 関数/クラスを介してサービス ランチャーを組み込む方法がわかりません。既にそれ自体で起動しているように見えるからです。

また、必須の商用ライセンスがなく、無料で使用でき、手頃な価格の登録が可能な、数秒以内に動作する Windows cron サービス プログラムをようやく見つけることができました (Web サイトに示されている内容から)。それはWinCronと呼ばれます。

于 2012-04-06T17:49:57.323 に答える