1

Windows サービス アプリケーションがあります。現在、すべての管理タスクは構成編集によって行われます。

ある種のコマンド ライン インターフェイスを追加したいのですが、powershell を使用して実行したいと考えています。

そして、どこから始めるべきかわかりません。この場合、アプリケーションインターフェイスを作成するにはどうすればよいですか。powershellはどのようにサービスと通信する必要がありますか? この場合、リモート機能も必要です。

(この機能には、他の管理ツールが含まれている可能性があります。GUI またはブラウザーを使用します。)

4

2 に答える 2

2

LBの短い発言を少し拡張します。特権サービスをユーザーのデスクトップと対話させることは、特権昇格のルートを開く可能性があるため、最善のアイデアではありません。たとえば、シャッター攻撃はそのように機能しました。

ユーザーとの対話を処理するためのより良い方法は、ローカルホスト(たとえば127.0.0.1:5555)に非特権リスナーを設定し、そのポートを介して送信されたメッセージを表示し、特権サービスをリスナーに接続してユーザーにメッセージを送信することです。

以下のコードスニペットは、改善の余地がたくさんありますが、そのようなリスナーがどのように見えるかについての一般的なアイデアを提供するはずです。

$addr = "127.0.0.1"
$port = 5555

[byte[]]$byte = @(0)
$enc = [System.Text.Encoding]::ASCII
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$socket = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Parse($addr), $port)
$socket.Start()
while ( $true ) {
  $client = $socket.AcceptTcpClient()
  $stream = $client.GetStream()
  [byte[]]$input = @()
  while ( ($i = $stream.Read($byte, 0, 1)) -ne 0 ) { $input += $byte }
  $client.Close()
  [System.Windows.Forms.MessageBox]::Show($enc.GetString($input), "Title")
}
于 2012-09-25T21:55:27.053 に答える
2

Windows サービスは、最初は次のようになります。

using System.ServiceProcess;
internal partial class MyService : ServiceBase
{
    static void Main()
    {
        ServiceBase[] ServicesToRun = new ServiceBase[] { new MyService() };
        ServiceBase.Run( ServicesToRun );
    }
}

私が行ったことは、Main()次のように、サービスの起動とコマンドラインの処理の両方に使用できるように変更することです。

using System;
using System.Runtime.InteropServices;
using System.ServiceProcess;
internal partial class MyService : ServiceBase
{
    const int ATTACH_PARENT_PROCESS = -1;

    [DllImport( "kernel32.dll" )]
    static extern bool AttachConsole( int dwProcessId );
    [DllImport( "kernel32.dll" )]
    static extern bool FreeConsole();

    static void Main()
    {
        if ( Environment.UserInteractive ) {
            try {
                // Redirect console output to the parent process.
                AttachConsole( ATTACH_PARENT_PROCESS );

                // Process command line arguments here...
            } catch {
                // Handle exceptions here...
            } finally {
                // Detach from the console.
                FreeConsole();
            }
        } else {
            ServiceBase[] ServicesToRun = new ServiceBase[] { new MyService() };
            ServiceBase.Run( ServicesToRun );
        }
    }
}

実行可能ファイルがビルドされたら、通常どおりオペレーティング システムに登録します (実際には、-install コマンド ライン オプションを使用して登録します)。サービスが開始されると、UserInteractiveフラグはfalseであるため、サービスは通常どおり開始されます。ただし、コマンド プロンプトからはUserInteractiveフラグがtrueであるため、コマンド ライン処理が引き継ぎます。

この時点で必要なのは、実行可能ファイルのコマンドライン インスタンスが、ある種の IPC (ソケット、パイプ、共有メモリ、WCF など) を介して実行可能ファイルのサービス インスタンスと通信することだけです。

于 2012-09-26T04:34:37.123 に答える