同じプロセスでWindowsフォームを使用するWindowsサービス
-
03-07-2019 - |
質問
ソケット接続などを制御するWindowsサービスとして実行されるc#アプリケーションがあります。 また、このサービスを制御および構成するための別のWindowsフォームアプリケーションがあります(開始、停止、構成パラメーターを使用してフォームを表示)。
.netリモーティングを使用してIPCを実行していますが、これで問題ありませんでしたが、実際のトラフィックやその他のレポートを表示したいので、リモーティングはパフォーマンス要件を満たしません。したがって、両方のアプリケーションを1つにまとめたいと思います。
問題は次のとおりです。
Windowsサービスからフォームを開始したとき、何も起こりませんでした。グーグルで検索して、サービスを右クリックし、ログオンに移動して、「デスクトップとの対話をサービスに許可する」をチェックする必要があることがわかりました。オプション。ユーザーにそれを要求したくないので、インストール時にユーザーのregeditでこのオプションを設定するために、いくつかのコードを再度グーグルで取得しました。問題は、このオプションを設定しても機能しないことです。サービスのログオンオプション(チェックされている)を開き、チェックを外して再度チェックする必要があります。
それで、それを解決する方法は?同じプロセスでsystrayコントロールを備えたWindowsサービスを使用して、ログインしているすべてのユーザーが利用できる最善の方法はどのようになりますか?
更新:これまでのコメントをありがとう、みんな。 IPCを使用する方が良いことに同意します。Windowsサービスとユーザーインターフェイスを混在させることは悪いことです。それでも、その方法を知りたい。
解決
選択したテクノロジーを使用して通信する2つの別個のプロセス。 UIを使用したサービスは、悪い考えです。この道を下らないでください-後悔します。
単純なソケット接続を介したサービス通信で非常に良い結果が得られました。サービスプロトコルを文書化し、可能な限りシンプルに保つと、思ったより簡単になります。
他のヒント
実際には、サービスと管理UIを組み合わせないでください。
Gregに同意します。おそらく、別のIPCメカニズムを調べることができます。おそらく、ソケットと独自のプロトコルを使用します。または、サービスコントロールアプリがローカルマシン上のサービスのみを制御できる場合は、名前付きパイプを使用できます(さらに高速)。
これは、サービスとフォームを混在させる方法です
http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx
thisからこれを行う方法を見つけました。記事([メソッド]テーブルの[変更]リンクをクリックします)。
string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
object[] parameters = new object[11];
parameters[5] = true; // Enable desktop interaction
service.InvokeMethod("Change", parameters);
}
いくつかのステップで解決策があります。これが計画です
-
windowsフォームを使用してサービスプロジェクトを作成するのではなく、windowsサービスプロジェクト、windowsフォームプロジェクト、セットアッププロジェクトを含むVisual Studioソリューションを作成します。
-
アイデアは、Windowsサービスが常に実行に使用するパラメーターを保存するデータベース、ファイル、またはデータの保存に慣れているものを用意することです。したがって、WindowsサービスとWindowsフォームアプリケーションは、そこからデータを変更および取得できる必要があります。
-
Windowsアプリケーションのメインフォームに、プロパティタブで、NotifyIconをフォームにドラッグアンドドロップし、.icoイメージを参照して選択します(Visual Studioで作成できますが、それは別のトピックです) Googleにアクセスするか、私に連絡してください)アプリケーションを実行し、メインフォームがアクティブまたは表示されているときにシステムトレイに表示されることを試して、アプリケーションを実行します。
-
これらの両方をソリューションのセットアッププロジェクトの出力として追加します。プロジェクトをセットアッププロジェクトに追加するには、同じソリューション内にある必要があります。ソリューションエクスプローラーでセットアッププロジェクトを右クリックし、[追加]を選択してプロジェクト出力を選択し、WindowsサービスとWindowsフォーム出力を追加すると、セットアッププロジェクトの下のソリューションエクスプローラーに表示されます。
-
Windowsサービスの追加はこれよりもさらに進んでいますが、それはGoogle itのもう1つのトピックです
-
Windowsアプリケーションのショートカットを作成し、それをスタートアップフォルダに追加することも、別のトピックgoogleまたは私に連絡してください。
注閉じるボタンが表示されず、フォームがMe.visible = falseになり、システムトレイ内のアイコンをダブルクリックすることが、me.visible = true.thatを設定する唯一の方法です。方法は、コンピューターが起動するたびに、Windowsフォームアプリケーションも起動され、表示がすぐにfalseに設定されますが、アイコンイメージの通知アイコンがあるため、システムトレイに表示され、ダブルクリックするとフォームが表示され、編集できますサービス用に保存している設定では、セットアッププロジェクトでサービスを設定するときに設定したため、サービスも自動的に開始されます。 私のメールはiamjavademon@gmail.comです。スクリーンショットを使用してより良いイラストを作成し、完全に説明してください
これは非常に単純です-アプリケーションイベントを実行するために1つのスレッドを作成する必要があります。 このように(CLRを使用したC ++のソースコードですが、C#で作成できます):
ref class RunWindow{
public:
static void MakeWindow(Object^ data)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew TMainForm());
};
};
メインでスレッドを作成
int main(array<System::String ^> ^args)
{
bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");
if (bService)
{
System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
thread->Start();
ServiceBase::Run(gcnew simpleWinService());
Application::Exit();
}
else
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew TMainForm());
}
return 0;
}
インタラクティブサービスの主な問題は次のとおりです。
-
セキュリティ-他のプロセスがメッセージポンプを介してメッセージを送信し、SYSTEM / LOCALプロセスにアクセスできるようになります。
-
不完全-対話型サービスではシェルメッセージが表示されないため、通知領域アイコンと対話できません。
定期的にTCPおよびUDP接続を使用して、サービスから他のexe、および場合によってはMSMQに情報を渡します。