- PR -

C#のWindowsサービスからのProcessによるEXE起動について

1
投稿者投稿内容
山さん
会議室デビュー日: 2006/08/18
投稿数: 10
投稿日時: 2006-08-18 16:32
どなたか教えてください。

C#のWindowsサービスから、Processを使い、アカウント、パスワード指定にてEXEを起動しようとしているのですが、「アクセスが拒否されました。」との例外が発生し、うまくいきません。ローカルのAdministratorを指定してもダメでした。
ちなみに、アカウント、パスワードなしで起動すると裏で実行されます。

以下、サンプルコードです。

// 該当プログラムを起動
Process proc = new Process();
proc.StartInfo.FileName = programInfomation.Program;
proc.StartInfo.Arguments = programInfomation.Arguments;
if (programInfomation.UserId != "" && programInfomation.Password != "")
{
proc.StartInfo.UserName = programInfomation.UserId;
SecureString secStr = new SecureString();
foreach (char ch in programInfomation.Password.ToCharArray())
secStr.AppendChar(ch);
proc.StartInfo.Password = secStr;
if (programInfomation.Domain != "")
proc.StartInfo.Domain = programInfomation.Domain;
}
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.LoadUserProfile = true;
proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
proc.StartInfo.CreateNoWindow = false;
proc.Start();

別途、セキュリティ設定なんかが必要なのでしょうか?
以上、よろしくお願いします。
Yam
大ベテラン
会議室デビュー日: 2003/09/13
投稿数: 179
お住まい・勤務地: だんじり祭りの地
投稿日時: 2006-08-18 18:00
引用:

山さんさんの書き込み (2006-08-18 16:32) より:
ちなみに、アカウント、パスワードなしで起動すると裏で実行されます。


アカウント・パスワード有りでもサービスから起動する場合はこうなるのでは?
山さん
会議室デビュー日: 2006/08/18
投稿数: 10
投稿日時: 2006-08-18 18:13
引用:

Yamさんの書き込み (2006-08-18 18:00) より:
アカウント・パスワード有りでもサービスから起動する場合はこうなるのでは?



要は、Windowsの標準のタスクスケジューラーと同じようなことをしたいのです。
標準のタスクスケジューラーでは、Windowsサービスはローカルシステムで動作しており、タスクを設定する時に、動作させるアカウント、パスワードを設定します。
標準のタスクスケジューラーがうまくいくのだから、なにか方法があるものと思われます。
いかがでしょうか?
Yam
大ベテラン
会議室デビュー日: 2003/09/13
投稿数: 179
お住まい・勤務地: だんじり祭りの地
投稿日時: 2006-08-18 19:26
引用:

山さんさんの書き込み (2006-08-18 18:13) より:
標準のタスクスケジューラーがうまくいくのだから、なにか方法があるものと思われます。


タスクスケジューラは太古より続く存在ですので
.NET FrameworkのProcessとは分けて考えたほうが良いと思います。
タスクスケジューラに登録してしまうのはどうでしょう?
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-08-19 04:02
引用:

標準のタスクスケジューラーがうまくいくのだから、なにか方法があるものと思われます。
いかがでしょうか?



あるでしょうね。

少なくとも標準のタスクスケジューラが、.NET の Process クラスなんか使ってないことは間違いありません。

CreateProcessWithLogonW() API 使ってるんだと思いますよ。
山さん
会議室デビュー日: 2006/08/18
投稿数: 10
投稿日時: 2006-08-19 11:35
引用:

渋木宏明(ひどり)さんの書き込み (2006-08-19 04:02) より:

CreateProcessWithLogonW() API 使ってるんだと思いますよ。




.NETのProcessでは、できないのでしょうか?
.NET環境でのWindowsサービスにおいても、アクセス拒否を回避する方法があるように思うのですが...
どうして、Windowsサービスと同じアカウント、パスワードで「アクセスが拒否」されるかがわかれば対処する方法も分かるように思います。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-08-19 13:57
引用:

山さんさんの書き込み (2006-08-19 11:35) より:
.NETのProcessでは、できないのでしょうか?


Processだけでは出来ないでしょうね。

他にOpenDesktop APIなども関わってきていると思いますよ。これに該当するAPIが.NET Frameworkに用意されているのかは、知らないけど。
山さん
会議室デビュー日: 2006/08/18
投稿数: 10
投稿日時: 2006-08-31 16:14
引用:

甕星さんの書き込み (2006-08-19 13:57) より:
他にOpenDesktop APIなども関わってきていると思いますよ。



自己解決しましたので、概要を記録させていただきます。

Windowsサービスにおいて、標準のタスクスケジューラと同様の動作を実現する方法を見つけました。

簡単に申しますと、C#のマネージコードより必要なWin32 API(アンマネージコード)を呼び出すことで
標準のタスクスケジューラと同様の動きを実現できました。

ちなみに、その流れは、次のようになります。

1.LogonUser(Win32)で、指定ユーザーでログオン(ログオントークンを取得)
2.WindowsIdentityのImpersonateで、ユーザーを偽装
3.OpenWindowStation(Win32)で、対話ウインドウステーションのハンドルの取得(winsta0)
4.GetProcessWindowStation(Win32)で、現ウインドウステーションのハンドル取得
5.SetProcessWindowStation(Win32)で、デスクトップウインドウを対話ウインドウステーションに設定
6.OpenDesktop(Win32)で、デスクトップのハンドルの取得(default)
7.該当ユーザーのログオンSIDの取得(複雑なので内容は省略)
8.対話ウインドウステーションに該当ユーザーを追加(複雑なので内容は省略)
9."default"デスクトップに該当ユーザーを追加(複雑なので内容は省略)
10.ログオンSIDのバッファの開放
11.対話ウインドウステーションとデスクトップのハンドルをクローズ(CloseWindowStation、CloseDesktop)
12.CreateProcessAsUser(Win32)で、該当プログラムを起動(lpDesktop = @"winsta0\default")
13.SetProcessWindowStation(Win32)で、ウインドウステーションの戻し
14.Undo()で、偽装ユーザーから元のユーザー権限に戻し
15.トークンや各ハンドルのクローズ(CloseHandle)

なお、CreateProcessAsUserの説明に以下の内容がありましたので、Q165194を参考にさせていただ
き、C#に焼き直しました。

〜〜〜〜 解説文の一部 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
 ・・・
新しいプロセスでユーザーとの対話を可能にするには、STARTUPINFO 構造体のメンバ lpDesktop に
既定の対話型ウィンドウステーションとデスクトップの名前 "winsta0\default" を指定する必要があります。
さらに、CreateProcessAsUser 関数を呼び出す前に、既定の対話型ウィンドウステーションと既定のデス
クトップの両方の随意アクセス制御リスト (DACL) を変更しなければなりません。ウィンドウステーションと
デスクトップの DACL で、パラメータ hToken によって表されるユーザーまたはログオンセッションへのア
クセスを認めます。
 ・・・
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

Windowsサービスからのユーザーインタフェースを伴うWindowsアプリケーションの起動は推奨されない
ということは、充分、理解いたしましたが、当方の都合上、今回は、上記の方法にて対応したいと思います。
1

スキルアップ/キャリアアップ(JOB@IT)