C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[12]: サービスからWin32アプリケーションの起動


(過去ログ 94 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■55845 / inTopicNo.1)  サービスからWin32アプリケーションの起動
  
□投稿者/ asuka (26回)-(2010/12/15(Wed) 17:23:36)

分類:[C#] 

お世話になっております。


バックアップソフトをWin32アプリケーション(EXE)で作成しております。

タスクトレイに常駐し、指定した時間になるとバックアップを開始〜終了を繰り返す単純なソフトです。

客先運用のことを視野に入れず、毎夜再起動されるのですが、Win32Appということで、

シャットダウンあるいはログオフされると終了してしまい常駐出来なくなってしまいます。



そこで、サービスプログラムとして作成しなおそうかと思ったのですが、

ふと、サービスからWin32Appを起動して動作すれば良いかな?

という安直ながらも案が浮かびました。



Win32Appからはサービスを開始させたり停止させたりする出来ることは確認済みなのですが、

サービスからWin32Appを起動し、今回の場合ですと常駐ソフトですので、常駐してバックアップを行ってくれるものなのか疑問です。
(Windowsにログインもしていない状態なので。)

このような経験をお持ちの方がおられましたらご教授頂けると幸いです。

また、このような動作を行うべきでない理由などがありましたら、あわせて教えて頂けると幸いです。


---
VS2010
C#






引用返信 編集キー/
■55851 / inTopicNo.2)  Re[1]: サービスからWin32アプリケーションの起動
□投稿者/ オショウ (566回)-(2010/12/15(Wed) 20:18:33)
> Win32Appからはサービスを開始させたり停止させたりする出来ることは確認済みなのですが、
> サービスからWin32Appを起動し、今回の場合ですと常駐ソフトですので、常駐してバックアップを行ってくれるものなのか疑問です。
> (Windowsにログインもしていない状態なので。)

  まず、理論的には可能です。
  私はすでに作って動作させてます。

  ただし、多分、大きなハードルがいくつもあるでしょう〜
  権限の偽装を含め、ログインしているユーザー環境の継承等・・・

> このような経験をお持ちの方がおられましたらご教授頂けると幸いです。
> また、このような動作を行うべきでない理由などがありましたら、あわせて教えて頂けると幸いです。

  バックアップとは、何をバックアップしているんですか?
  それによっては、サービス上でのバックアップ動作も、そう
  難しいことではないかと。

  ただし、アプリ起動にせよ、権限の問題は付きまといますの
  で、タスクスケジューラにバックアップを行うアプリを登録
  して、起動させるのが一番簡単で楽ではないでしょうか。

以上。参考まで
引用返信 編集キー/
■55869 / inTopicNo.3)  Re[2]: サービスからWin32アプリケーションの起動
□投稿者/ asuka (27回)-(2010/12/16(Thu) 15:20:25)
> オショウさま

ご教授感謝です。

>   ただし、多分、大きなハードルがいくつもあるでしょう〜
>   権限の偽装を含め、ログインしているユーザー環境の継承等・・・

もうこれだけで辞めようと決意しました。
素直にサービスプログラムに処理を移植することにします。



>>このような経験をお持ちの方がおられましたらご教授頂けると幸いです。
>>また、このような動作を行うべきでない理由などがありましたら、あわせて教えて頂けると幸いです。
>
>   バックアップとは、何をバックアップしているんですか?
>   それによっては、サービス上でのバックアップ動作も、そう
>   難しいことではないかと。

バックアップはSQLサーバのデータをMDB(ファイル)へデータ転送しています。

>   ただし、アプリ起動にせよ、権限の問題は付きまといますの
>   で、タスクスケジューラにバックアップを行うアプリを登録
>   して、起動させるのが一番簡単で楽ではないでしょうか。
>
> 以上。参考まで

なるほど、、、
伺ってよかったです。
確かにあれやこれや悩んでいた中では一番簡単かと思います。
サービスに処理を移植するか悩ましいところです、、、
ちょっと悩んでどちらにするか考えたいと思います。
ありがとうございました。

解決済み
引用返信 編集キー/
■55870 / inTopicNo.4)  Re[3]: サービスからWin32アプリケーションの起動
□投稿者/ ちゃっぴ (65回)-(2010/12/16(Thu) 15:27:42)
ちゃっぴ さんの Web サイト
Batch 専用 user を作っておけば log on の影響は受けないですね。

Windows Vista 以降では Task Scheduler での設定にもよりますが、task が起動するときに同じ user が log on しているとその log on session が利用されるので、log off のときに道ずれになるという現象です。

私も障害復旧がややこしいとか、scheduling がややこしいといった場合を除き Task Scheduler を利用すると思います。
引用返信 編集キー/
■55891 / inTopicNo.5)  Re[4]: サービスからWin32アプリケーションの起動
□投稿者/ asuka (28回)-(2010/12/17(Fri) 15:12:03)
> ちゃっぴ さま

アドバイスありがとうございます。

確か以前、XPはともかく、Vistaでタスクスケジューラを動かしていてログインに失敗した記憶があります。

そのときはadmini権限を持たせたユーザで実行するようにして対処した記憶があります。

ログオンセッションの問題もありですか・・・



ちなみに現在、勉強がてらサービスからWin32Appを起動させようとしているのですがうまく行かないです。。。

オショウさんがまだこのレスを見られていたら教えて頂きたいのですが、

OnStart内でProcess.Start("strExePath");のようにサービス内からWin32Appを非同期でコールし、

直後に throw new ApplicationException("")して終了してます。



うまくいかないというのは、Win32Appが起動しないことと、例外を投げてサービスを終了するつもりが「開始」のままになってます。

.Net2.0からOnStart内でもOnStopで終了してよいのでしたっけ?

これをやると「〜サービスは起動して停止しました。・・・」のメッセージが回避出来ずいやなのですが・・・

引用返信 編集キー/
■55895 / inTopicNo.6)  Re[5]: サービスからWin32アプリケーションの起動
□投稿者/ オショウ (567回)-(2010/12/17(Fri) 15:59:28)
> ちなみに現在、勉強がてらサービスからWin32Appを起動させようとしているのですがうまく行かないです。。。
> オショウさんがまだこのレスを見られていたら教えて頂きたいのですが、
> OnStart内でProcess.Start("strExePath");のようにサービス内からWin32Appを非同期でコールし、
> 直後に throw new ApplicationException("")して終了してます。

  GUIを持つアプリを起動しようとしていますか?
  あとレジストリやHDD上のどこかにアクセスする機能を持つアプリ
  でしょうか?因みに.NETアプリならサービスから起動させた場合
  特殊なフォルダにアクセスしますので、適切な権限を持つユーザー
  として起動させないと、起動しません。

  因みに、CreateEnvironmentBlock/CreateProcessAsUser 等のAPI
  を使う必要があります。

> うまくいかないというのは、Win32Appが起動しないことと、例外を投げてサービスを終了するつもりが「開始」のままになってます。
> .Net2.0からOnStart内でもOnStopで終了してよいのでしたっけ?

  .NET Framework内からAPIが呼び出され、API側エラーを返している
  はずですので、異常終了させたい場合、OnStart内で、エラーを
  スローするコードを書かないと止まりません。

以上。
引用返信 編集キー/
■55899 / inTopicNo.7)  Re[6]: サービスからWin32アプリケーションの起動
□投稿者/ asuka (29回)-(2010/12/17(Fri) 16:32:51)
No55895 (オショウ さん) に返信
>>ちなみに現在、勉強がてらサービスからWin32Appを起動させようとしているのですがうまく行かないです。。。
>>オショウさんがまだこのレスを見られていたら教えて頂きたいのですが、
>>OnStart内でProcess.Start("strExePath");のようにサービス内からWin32Appを非同期でコールし、
>>直後に throw new ApplicationException("")して終了してます。
>
>   GUIを持つアプリを起動しようとしていますか?
>   あとレジストリやHDD上のどこかにアクセスする機能を持つアプリ
>   でしょうか?因みに.NETアプリならサービスから起動させた場合
>   特殊なフォルダにアクセスしますので、適切な権限を持つユーザー
>   として起動させないと、起動しません。
>
>   因みに、CreateEnvironmentBlock/CreateProcessAsUser 等のAPI
>   を使う必要があります。

なるほど・・・
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=32959&forum=7

上記記事を見つけましたが、オショウさんはこのような実装をして動かしていると思ってよいでしょうか?

ちょっとしきいが高そうです・・・

年内いっぱいなのですが、時間もないので厳しいかなぁ。。。


>>うまくいかないというのは、Win32Appが起動しないことと、例外を投げてサービスを終了するつもりが「開始」のままになってます。
>>.Net2.0からOnStart内でもOnStopで終了してよいのでしたっけ?
>
>   .NET Framework内からAPIが呼び出され、API側エラーを返している
>   はずですので、異常終了させたい場合、OnStart内で、エラーを
>   スローするコードを書かないと止まりません。

んー、例えばAPIを呼びださないような、OnStart内の一発目のコードに throw new ApplicationException("終わります");

と記述しただけでもサービスが停止しないです。

ちなみに
catche(ApplicationException AppEx ){}
があってもなくても、状態は「開始」状態です。



引用返信 編集キー/
■55901 / inTopicNo.8)  Re[7]: サービスからWin32アプリケーションの起動
□投稿者/ ちゃっぴ (66回)-(2010/12/17(Fri) 16:44:33)
ちゃっぴ さんの Web サイト
2010/12/17(Fri) 17:03:44 編集(投稿者)

Task Scheduler から起動する前提なのですから、Win32 console application として作成してください。

それから、service の停止については、service にも ACL がありますのでその ACL を適切に構成する必要があります。

下記で service の ACL SDDL 形式が取得できます。以下、Windows 7 での結果

>sc sdshow ServiceName

:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCR
C;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

既定の設定では下記 account に service 停止が許可されています。

SY: NT AUTHORITY\SYSTEM
BA: BUILTIN\Administrators

上記以外で実行させようとしても ACL ではじかれます。

なお、Windows Vista 以降の OS で UAC が有効な場合、BUILTIN\Administrators group に所属している user でも task scheduler の設定で「最上位の特権で実行する」が有効になっていないと BUILTIN\Administrators group が有効になりません。


引用返信 編集キー/
■55902 / inTopicNo.9)  Re[8]: サービスからWin32アプリケーションの起動
□投稿者/ ちゃっぴ (67回)-(2010/12/17(Fri) 16:49:43)
ちゃっぴ さんの Web サイト
読み返したら。

> バックアップはSQLサーバのデータをMDB(ファイル)へデータ転送しています。

SQL Server Database Engine service 停止せずに SSIS package 作って実行で問題無いでしょうに。
他の service 停止している?

なんか、不必要に面倒な設計にしているような気がするんですが。
引用返信 編集キー/
■55903 / inTopicNo.10)  Re[9]: サービスからWin32アプリケーションの起動
□投稿者/ asuka (30回)-(2010/12/17(Fri) 17:33:17)
> ちゃっぴさま

わたしがガチャガチャ書いて分かりづらくしてしまったのは事実ですが、

現在話している内容は、

>ちなみに現在、勉強がてらサービスからWin32Appを起動させようとしているのですがうまく行かないです。。。

のつもりだったので、一端タスクスケジューラからの話とは切り離しているつもりでした。



> SQL Server Database Engine service 停止せずに SSIS package 作って実行で問題無いでしょうに。
> 他の service 停止している?
>
> なんか、不必要に面倒な設計にしているような気がするんですが。

これもこちらの諸事情があり、どうしてもC#から作成する必要があったのでそうしてます。


引用返信 編集キー/
■55905 / inTopicNo.11)  Re[9]: サービスからWin32アプリケーションの起動
□投稿者/ ちゃっぴ (68回)-(2010/12/17(Fri) 17:47:28)
ちゃっぴ さんの Web サイト
なお、task tray に常駐させるのがどうしても必須の要件ということであれば、私なら下記のようにします。

・ Service で実際の処理を行う
・ 常駐 application は要求の受領および service への要求の送信のみ

Service への要求の送信は簡単なものであれば service control command でもいいでしょうが、複雑なものであれば memory mapped file や WCF とかを利用したものを作りこむ必要がありますね。WCF で named pipe 使ってやるかな。

Service は log on user とは違った account で動作するので、Service 側で要求側の account に適切な特権があるか判定する必要もあるでしょう。

Service は NT AUTHORITY\SYSTEM で動作させずに専用の account を作成し、その account で動作させます。
権限が不足するので下記を行います。

・ SQL Server に log in を作成し、必要最小限の権限を付与
・ 扱う service と SCManager に必要最小限の権限を付与
・ MDB file に必要最小限の権限を付与
引用返信 編集キー/
■55906 / inTopicNo.12)  Re[10]: サービスからWin32アプリケーションの起動
□投稿者/ ちゃっぴ (69回)-(2010/12/17(Fri) 18:25:21)
ちゃっぴ さんの Web サイト
Service から console application を起動すること自体には何も問題ありませんよ。
Windows application (GUI) となるとものによりますが。
普通に Process.Start で行えます。

権限の問題は対話的に log on していないので、NT AUTHORITY\INTERACTIVE への許可を利用しているものは軒並みこけますのでこの対策は必要です。別の user で実行すれば解決するといったものではありません。BUILTIN\Administrators の member での実行を除く。

扱う resources の ACL を確認し、適切に resources の ACL を構成する必要があります。


引用返信 編集キー/
■55943 / inTopicNo.13)  Re[11]: サービスからWin32アプリケーションの起動
□投稿者/ asuka (31回)-(2010/12/20(Mon) 10:35:37)
> ちゃっぴさま

詳細なご説明ありがとうございます。

ちゃっぴさんに頂いたアドバイス通り、実際の処理はサービスで行うことにしました。

あれやこれや伺っていて面目ないのですが、色々と試行錯誤し、結局サービスのみでの実装としました。
申し訳ありません。m(__)m



>Service は NT AUTHORITY\SYSTEM で動作させずに専用の account を作成し、その account で動作させます。
権限が不足するので下記を行います。

ここが気になったのですが、タスクマネージャも使用せず自前のサービスを開始させる際に、

そのサービス特有のアカウントを作成して動かした経験はありますが、必ず設ける必要はありますでしょうか?

今回に関して申し上げますと、特にサービスを実行させるユーザに対する要求はなく、

サービスシステムインストーラでアカウントを作成する際、
serviceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
serviceProcessInstaller.Password=null;
serviceProcessInstaller.Username =null;

としてLocalSystemを設定し、アカウントとパスワードを指定せずに作成して現状動作しておりますが、

何か決定的な問題はありますでしょうか?

長々と申し訳ありませんが、お答え頂けるようでしたらご教授頂けると幸いです。


>Service から console application を起動すること自体には何も問題ありませんよ。
Windows application (GUI) となるとものによりますが。
普通に Process.Start で行えます。

なるほど、コンソールアプリケーションで動作確認しました。

GUIですと、先に記載した通り動作しない・・・

というより、タスクマネージャには表示されますが画面も表示されず実装した処理がされませんでした。

記載のURLの現象でしたので、こちらはまた時間をみつけて調査したいと思います。

今回はサービスのみで実装することにしましたので一度ペンディングにしたいと思います。
引用返信 編集キー/
■55989 / inTopicNo.14)  Re[12]: サービスからWin32アプリケーションの起動
□投稿者/ ちゃっぴ (70回)-(2010/12/21(Tue) 20:08:54)
ちゃっぴ さんの Web サイト
最少権限の原則に反するからです。

NT AUTHORITY\SYSTEM は system に対する全権を持っているため、その account で動作する process に脆弱性が存在すると system 全体が危険にさらされます。Security 防御を行う場合、多層での防御を行うのが非常に重要であるため、Microsoft もできる限り NT AUTHORITY\SYSTEM を利用しないことを推奨しています。

http://technet.microsoft.com/ja-jp/library/dd433763.aspx

なお、Windows Vista 以降の OS では個別の service 毎に account が自動生成されるため、外部に接続しないのであれば専用の account を作成せず Local Service で動作させた方が良いと思います。外部に接続する必要があるのであれば、専用の domain account を割り当てます。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -