私は最近、Windowsサービスとして実行されるいくつかのアプリケーションを継承しましたが、その両方でGUI(システムトレイのコンテキストメニューからアクセス可能)を提供するのに問題があります。
WindowsサービスにGUIが必要な理由は、停止/再起動に頼らずにWindowsサービスの動作を再設定できるようにするためです。
デバッグモードでコードが正常に機能し、コンテキストメニューが表示され、すべてが正しく動作するなど。
名前付きアカウント(つまり、ローカルシステムアカウントではない)を使用して "installutil"を介してサービスをインストールすると、サービスは正常に実行されますが、システムトレイにアイコンが表示されません( 「デスクトップと対話する」オプションがあります)。
しかし、ここに問題があります-「LocalSystemAccount」オプションを選択し、「デスクトップと対話する」オプションをチェックすると、サービスは明白な理由なしに起動するためにAGESを取り、私はただ取得し続けます
ローカルコンピューターで...サービスを開始できませんでした。
エラー1053:サービスは開始要求または制御要求にタイムリーに応答しませんでした。
ちなみに、Windowsサービスのタイムアウトを、レジストリハックを介してデフォルトの30秒から2分に増やしました( http://support.Microsoft.com/kb/824344 を参照して、セクション3でTimeoutPeriodを検索してください) 、ただし、サービスの起動はまだタイムアウトします。
私の最初の質問は-「Local System Account」ログインが、サービスが非LocalSystemAccountでログインするときよりもずっと長くかかり、Windowsサービスがタイムアウトするのはなぜですか?起動時にこのような異なる動作を引き起こすこれらの2つの違いは何ですか?
第二に-私が達成しようとしていることは、設定のためのGUIを提供する単なるWindowsサービスです-ローカルシステム以外のアカウント(user/pwdという名前)を使用して実行するのは非常に幸せですデスクトップと対話するサービスを取得できる場合(つまり、システムトレイからコンテキストメニューを使用できるようにする場合)。これは可能ですか?
上記の質問へのポインタをいただければ幸いです!
このメッセージと何日も戦った後、友人からリリースビルドを使用する必要があると言われました。デバッグビルドをInstallUtilすると、このメッセージが表示されます。リリースビルドは正常に開始されます。
サービスをユーザーのデスクトップと直接対話させようとすると、失われます。最高の状況(つまり、「Vista」の前)でも、これは非常に注意が必要です。
Windowsは複数の ウィンドウステーション を内部的に管理し、それぞれが独自のデスクトップを備えています。特定のアカウントで実行されているサービスに割り当てられているウィンドウステーションは、ログオンしている対話型ユーザーのウィンドウステーションとはまったく異なります。クロスウィンドウステーションへのアクセスはセキュリティリスクであるため常に嫌われていますが、以前のWindowsバージョンでは一部の例外が許可されていましたが、Vista以降のオペレーティングシステムではこれらのほとんどが排除されました。
サービスが起動時にハングする最も可能性の高い理由は、存在しないデスクトップとやり取りしようとしているため(または、エクスプローラーがシステムユーザーセッション内で実行されていることを前提としています)、または非表示のデスクトップからの入力を待っているためです。
の のみ これらの問題に対する信頼できる修正は、サービスからすべてのUIコードを削除し、インタラクティブユーザーセッション内で実行される別の実行可能ファイルに移動することです(実行可能ファイルは、たとえばグローバルスタートアップグループを使用して開始できます)。
UIコードとサービス間の通信は、任意のRPCメカニズムを使用して実装できます。名前付きパイプは、この目的に特に適しています。通信のニーズが最小限の場合、 application-defined Service Control Managerコマンド を使用してもうまくいく可能性があります。
UIとサービスコードをこのように分離するにはある程度の努力が必要です。ただし、これは物事を確実に機能させるための唯一の方法であり、将来的にも役立ちます。
補遺、2010年4月: この質問は非常に人気が高いため、「サービスが応答しませんでした...」エラーを引き起こす別の一般的なシナリオを修正する方法があります。デスクトップと対話するなどの面白いことを試みない。 行う Authenticode署名済みアセンブリを使用します。 発行者の証拠を作成するために、ロード時にAuthenticode署名の検証を無効にします 、次の要素を.exe.configファイルに追加します。
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
発行者の証拠は、ほとんど使用されていないコードアクセスセキュリティ(CAS)機能です。サービスが実際にPublisherMembershipConditionに依存しているというまれな場合にのみ、それを無効にすると問題が発生します。それ以外の場合はすべて、ランタイムが高価な証明書チェック(失効リストの検索を含む)を行う必要がなくなるため、永続的または断続的な起動エラーがなくなります。
サービスを実行しているボックスにフレームワークがないため、この問題に直面しました。ボックスには.NET 4.0があり、サービスは.NET 4.5の上に記述されていました。
ボックスに次のダウンロードをインストールして再起動すると、サービスが正常に起動しました。 http://www.Microsoft.com/en-us/download/details.aspx?id=3065
サービスの起動をデバッグするには、サービスのOnStart()
メソッドの先頭に次を追加します。
while(!System.Diagnostics.Debugger.IsAttached) Thread.Sleep(100);
これにより、[デバッグ]-> [プロセスにアタッチ]を使用してVisual Studioデバッガーを手動でアタッチするまでサービスが停止します。
注:一般に、ユーザーがサービスと対話する必要がある場合、GUIコンポーネントを、ユーザーのログイン時に実行される別のWindowsアプリケーションに分割することをお勧めします。 GUIアプリとサービス間の通信を確立するためのパイプまたはその他のIPCの形式。これは実際、Windows Vistaで可能なonly方法です。
OnStartメソッド内のサービスクラスでは、巨大な操作を行わないでください。OSは、サービスを実行するために短時間を期待し、スレッド開始を使用してメソッドを実行します。
protected override void OnStart(string[] args)
{
Thread t = new Thead(new ThreadStart(MethodName)); // e.g.
t.Start();
}
私はここでブラインドを撮影していますが、サービスの起動の長い遅延は、多くの場合、アカウントSIDを検索するときにドメインコントローラーに接続しようとするときに、ネットワーク機能のタイムアウトによって直接または間接的に引き起こされることを発見しましたGetMachineAccountSid()
この関数はRPCサブシステムによって呼び出されるため、それを実現するかどうかにかかわらず。
このような状況でデバッグする方法の例については、Mark Russinovichのブログの プロセス起動遅延のケース を参照してください。
サービスで次のようなデバッグコードを使用している場合、問題が発生する可能性があります。
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new EmailService()
};
ServiceBase.Run(ServicesToRun);
#else
//direct call function what you need to run
#endif
これを修正するには、Windowsサービスのビルド中に#if条件を削除します。これはそのままでは機能しなかったためです。
以下のように、代わりにデバッグモードの引数を使用してください。
if (args != null && args.Length > 0)
{
_isDebug = args[0].ToLower().Contains("debug");
}
私が書いていたサービスで同様の問題に直面していました。うまくいきましたが、ある日、開始エラーでタイムアウトが発生し始めました。何が起こっているかに応じて、リリースとデバッグの両方で発生しました。 System.DiagnosticsからEventLoggerのインスタンスを作成しましたが、Loggerが書き込むことができるようになる前に、表示されていたエラーが発生していたに違いありません。
EventLogの検索場所がわからない場合は、VSでサーバーエクスプローラーでマシンにアクセスできます。私は自分のサービス以外のいくつかのイベントログをいじり始めました。 [アプリケーション-.NETRuntime]の下で、起動時のエラーに関連するエラーログが見つかりました。基本的に、サービスのコンストラクターにはいくつかの例外がありました(EventLogインスタンスのセットアップでは例外であることが判明しました。これにより、サービスEventLogにログが表示されない理由が説明されました)。以前のビルドでは、明らかに他のエラーが発生していました(これにより、EventLogのセットアップでエラーにつながる変更を行うことになりました)。
長い話-タイムアウトの理由はさまざまな例外/エラーが原因である可能性がありますが、ランタイムEventLogsを使用すると、何が起こっているかを把握するのに役立つ場合があります(特に、あるビルドが機能するが別のビルドが機能しない場合)。
お役に立てれば!
私の場合、問題は.net framework
のバージョンがありませんでした。
使用したサービス
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
しかし、サーバーの.net Framework
バージョンは4であったため、4.5を4に変更することで問題は修正されました。
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
リリースDLLをコピーするか、デバッグモードではなくリリースモードからdllを取得してインストールフォルダーに貼り付けます。動作するはずです。
私はこの問題を抱えていたので、2日間夢中になりました…もしあなたの問題が私のものに似ていたら:
Windowsサービスには「ユーザー設定」という設定があります。そのため、サービスは、サービスを停止したり開始したりすることなく、自己保守を行うことができます。さて、問題は「ユーザー設定」にあります。これらの設定の構成ファイルは、service-exeファイルバージョンでWindowsサービスを実行しているユーザーのユーザープロファイルの下のフォルダーに保存されます。
何らかの理由でこのフォルダが破損しています。フォルダーを削除すると、サービスは通常どおり正常に戻ります...
この問題は通常、アセンブリに参照がない場合に発生し、通常は実行時にバインディングが失敗します。
デバッグするには、Thread.Sleep(1000)
にmain()
を配置します。次の実行行にブレークポイントを置きます。
次に、プロセスを起動し、起動中にデバッガをプロセスにアタッチします。ブレークポイントに到達した後、f5を押します。不足しているアセンブリまたは参照の例外をスローします。
これがこのエラーを解決することを願っています。
Exeファイルを実行してみてください。私は同じ問題を抱えていましたが、exeファイルをダブルクリックして直接実行すると、ターゲットマシンにインストールされていないフレームワークでサービスプロジェクトがリリースされたため、.Netフレームワークバージョンに関するメッセージが表示されました。
私はこの問題を抱えていました。修正に約1日かかりました。私にとっての問題は、コードが「メインコンテンツ」をスキップし、効果的に数行実行してから終了したことでした。そして、これがエラーを引き起こしました。 ServiceController(sc.Run())で実行しようとするとすぐにWindowsサービスをインストールするC#コンソールアプリケーションであり、このエラーが発生します。
メインコンテンツに移動するようにコードを修正すると、目的のコードが実行されます。
ServiceBase.Run(new ServiceHost());
その後、表示されなくなりました。
多くの人々がすでに言っているように、エラーは何でもありえます、そして、人々が提供する解決策はそれを解決するかもしれないし、しないかもしれません。彼らがそれを解決しない場合(デバッグの代わりにリリース、生成にgeneratePublisherEvidence = falseを追加するなど)、問題はあなた自身のコードにある可能性があります。
Sc.Run()を使用せずにコードを実行してみてください(つまり、sc.Run()が実行するコードを実行します)。
サービスのデバッグビルドをインストールし、デバッガをサービスにアタッチして、何が起こっているのかを確認します。
ここでmdbのコメントをエコーしたいと思います。この道を行かないでください。あなたのサービスはUIを持たないはずです...「ユーザーとの対話なし」はサービスの定義機能のようなものです。
サービスを構成する必要がある場合は、起動時にサービスが読み取る同じ構成を編集する別のアプリケーションを作成します。しかし、それを明確なツールにしてください。サービスを開始したいときは、サービスを開始します。構成する場合は、構成ツールを実行します。
さて、サービスのリアルタイム監視が必要な場合、それは少し厄介です(そして確かに私がサービスで望んでいたことです)。今、あなたはプロセス間通信と他の頭痛の種を使用しなければならないことについて話している。
最悪なのは、ユーザーとの対話が必要な場合、サービスはユーザーと対話しないため、ここで実際に切断されます。
あなたの靴で私は戻って尋ねますなぜこれがサービスである必要があるのか?そしてなぜユーザーとの対話が必要なのか?
これらの2つの要件はかなり互換性がなく、アラームが発生するはずです。
127.0.0.1 crl.Microsoft.comを「ホスト」ファイルに追加すると、問題が解決しました。
私の問題は、Windowsサービスの設定で言及されたターゲットフレームワークによるものでした
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
windowsサービスをインストールしようとしたサーバーは、この.Netバージョンではサポートされていませんでした。
Whichを変更すると、問題を解決できました。
私も同様の問題に直面し、アセンブリの読み込みに問題があることがわかりました。サービスを開始しようとすると、すぐにこのエラーを受け取りました。
問題をすばやくデバッグするには、ProcDump http://technet.Microsoft.com/en-us/sysinternals/dd9969 を使用してコマンドプロンプトでサービス実行可能ファイルを実行してみてください。正確なエラーに関する十分なヒントを提供します。
http://bytes.com/topic/net/answers/637227-1053-error-trying-start-my-net-windows-service かなり助けてくれました。
私の場合、ADのserアカウントに対する許可でした。正しく設定すると、完璧に機能します。
リリースビルドは機能しませんでしたが、イベントビューアーとアプリケーションログを調べたところ、イベントログを作成しようとしたときにWindowsサービスがセキュリティ例外をスローしていたことがわかりました。イベントソースを管理アクセスで手動で追加することにより、これを修正しました。
Microsoftのこのガイドに従いました。
ローカルシステムアカウントとローカルサービスの両方が機能しないため、それをネットワークサービスに設定しましたが、これは正常に機能しました。
管理者としてサービスウィンドウを開き、サービスを開始してみてください。それは私のために働いた。
テストにWindowsフォームを使用している場合、スタートアップオブジェクトがWindowsフォームではなくサービスであることを確認してください
私はこのような問題を抱えていました
私の問題はエラーによるものではありません。途中でBlockingCollection.GetConsumingEnumerable()がありました。そのため、Windowsサービスは待機していました。
私の場合、本物のエラーが原因でこの問題が発生しました。サービスコンストラクターが呼び出される前に、メンバー変数の1つの静的コンストラクターが失敗していました。
private static OracleCommand cmd;
static SchedTasks()
{
try
{
cmd = new OracleCommand("select * from change_notification");
}
catch (Exception e)
{
Log(e.Message);
// "The provider is not compatible with the version of Oracle client"
}
}
Try-catchブロックを追加すると、間違ったOracleバージョンが原因で例外が発生していることがわかりました。正しいデータベースをインストールすることで問題が解決しました。
データベーステーブルにログを記録するようにLog4Netを構成しました。テーブルが非常に大きくなったため、サービスはメッセージをログに記録しようとしてタイムアウトしていました。
私もこの問題を抱えていました。ログオンアカウントをローカルシステムアカウントに変更して機能するようにしました。私のプロジェクトでは、ローカルサービスアカウントとして実行するようにセットアップしました。そのため、デフォルトでは、ローカルサービスを使用していました。 .net 2.0とVS 2005を使用しています。したがって、.net 1.1 SP1をインストールしても役に立ちませんでした。
少なくとも、これは私には有効です。