Windowsで無人で長期間実行する必要があるアプリがありますXPおよび7。LogMeInを備えたリモートマシンで実行しています遠くからでも見ることができるようにインストールされています。プログラムには、タイマーによってペースが調整される定期的なロギングタスクがあります。
少し遅れてPCがスクリーンセーバーに設定されていて、スクリーンセーバーの終了時にユーザーログイン画面を表示すると、PCがスクリーンセーバーに入るとアプリが機能しなくなることに気づきました。
リモートでログインしてスクリーンセーバーから追い出すと、中断したところから続行しますが、その間にデータが記録されません。
スクリーンセーバーオプションの[再開時にウェルカム画面を表示する]チェックボックスをオフにすることで解決したと思いましたが、問題は再び発生したようです。スクリーンセーバーを完全に無効にしてみましたが、うまくいきませんでした。
プログラムが常に実行されていることを確認するにはどうすればよいですか?ウェルカム画面でWindowsから「x個のプログラムが実行中」と表示されますが、Windowsタイマーには拡張されていないようです。少なくとも時々。
いくつかのデバッグコードを追加し、もう少し情報があります。
このアプリはDelphi2006GUIアプリです。それが行う通常のタスクの1つは、レポートを生成することです。レポートが生成されている間(時間がかかる場合があります)、進行状況バーが表示されます。これは、すべての処理がOnPaint
ハンドラーで行われるモーダル形式として実装されます。
スクリーンセーバーが起動した後にレポートがトリガーされ、[再開時にウェルカム画面を表示する]チェックボックスがオンになっている場合、このモーダルフォームのOnPaint
メソッドは起動しないことがわかりました。フォームのOnShow
イベントが発生し、アプリがハングします。スクリーンセーバーを起動して再開するとすぐに、OnPaint
イベントが実行され、すべてが発生します。
スクリーンセーバーがアクティブなときにタイマーイベントが発生しないという私の当初の想定は間違っていました。実際、タイマーイベントの再入を防ぐための他のコードは、レポートが終了するまで何も起こらないようにし、レポートはOnPaint
イベントに引っ掛かりました。
PCがウェルカム画面に画面保存されたときに実行されるようにこの進行状況フォームを実装する方法に関する提案はありますか?
プログラムをサービスとして実行するように設定できます。このようにして、常にバックグラウンドで実行されます。
そうすれば、システムをロックしても、アプリケーションは引き続き実行されます。
無料ツール Servify This はあなたのニーズに完全に合うでしょう。
この考え方についての質問には十分なデータがありません。
それで、私はあなたが答えをさらに読むために最初に断言できるいくつかの仮定から始めます。
したがって、これが当てはまる場合、(セッションの終了時に)アクセスが取り消されたためにアプリケーションがアクティビティを完了できず、システムを「ロック解除」するために再度ログインすると、セッションが再開され、アプリケーションも再起動できます(結果に到達せずにタイムアウトして停止した可能性があります)。ただし、新しいセッションを実行しているため、正常に再開されます(ただし、実行したままにすると同じ問題が発生し、最終的にセッションが終了して画面がロックされます)。
これはもっとハックされた解決策のように聞こえるかもしれませんが、数分ごとにマウスをTwitchに少しコードを追加するだけではいけませんか?大きな問題はありません。いずれかの軸の現在のマウス位置に1を加算し、1を減算するだけです。
私が採用しなければならなかった最終的な解決策は、FormActivate
ハンドラーで処理を行うことでした。次に、Close
ハンドラーが呼び出されるまで、OnPaint
メソッドは機能しないため、メッセージを投稿してフォームを閉じる必要がありました。 OnPaint
イベントとは異なり、OnActivate
イベントis PCがスクリーンセーバーにあるときに呼び出されます。
procedure TReportForm.FormShow (Sender: TObject) ;
begin
OnActivate := FormActivate ; // reinstate the handler (it will be nil from any prior call)
end;
procedure TReportForm.FormActivate (Sender: TObject) ;
begin
OnActivate := nil ; // prevent it being called recursively
GenerateReport ;
PostMessage (Handle, WM_CLOSE, 0, 0) ;
end ;