3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(.Net)別ユーザでプロセスを起動する

C++Windows API を使って別のユーザでアプリケーションを書く方法は、(C++)別ユーザでプロセスを起動するで書きました。

今回は .Net でそれを実現する方法です。

基本的には、ProcessStartInfo. Domain , ProcessStartInfo.UserName , ProcessStartInfo.Password プロパティを指定して、Process.Start すればいいだけのようですね。

ただし、 ProcessStartInfo.Password は SecureString オブジェクトを指定しないといけないのが曲者です。

SecureString に文字列をセットするには、SecureString.AppendChar(char型) で一文字ずつセットしないといけないようです。

で、今回コンソールアプケーションを作成し、引数に指定されたユーザ名とパスワードで別アプリケーション(今回はバッチファイル)を起動するというコードを書く必要がありました。

下記のような感じすればいいみたいです。(C#)

static void Main(string[] args)

{

//コマンドライン引数に下記のように情報が入ることとする。

//1:ユーザ名 2:パスワード 3:実行ファイル名 4:ドメイン名 ちなみに0には必ず自身のexeのパスが入るらしい

//コマンドライン引数配列取得

string[] cmds;

cmds = System.Environment.GetCommandLineArgs();

 

//プロセスオブジェクト生成

Process proc = new Process();

// 起動するアプリケーションを設定する

proc.StartInfo.FileName = cmds[3];

// 起動するアプリケーションに対するコマンドライン引数を設定する

proc.StartInfo.Arguments = "args";

// ウィンドウを作成しないかどうかを設定する (初期値 false)trueにするとウィンドウ表示なしとなる

proc.StartInfo.CreateNoWindow = false;

// シェルを使用するかどうか設定する (初期値 true)falseにするとコンソールウィンドウが表示なしとなる

proc.StartInfo.UseShellExecute = true;

// 起動できなかった時にエラーダイアログを表示するかどうかを設定する (初期値 false)

proc.StartInfo.ErrorDialog = false;

 

//プロセス実行時のドメイン名(ローカルユーザの場合はnullを指定)

proc.StartInfo.Domain = cmds[4];

//プロセス実行時のユーザ名

proc.StartInfo.UserName = cmds[1];

//パスワード(ProcessStartInfo.PasswordはSecureStringで指定しないといけない)

SecureString password = new SecureString();

foreach (char c in cmds[2].ToCharArray())

{

//SecureStringの文字追加

password.AppendChar(c);

}

//プロセス実行時のユーザのパスワード指定

proc.StartInfo.Password = password;

 

// 起動時のウィンドウの状態を設定する

proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal; //通常

// 起動する

proc.Start();

//起動したプロセスが終わるまで待つ。(60秒待つ)

proc.WaitForExit(60000);

 

//終了コード取得

int iExitCode = proc.ExitCode;

Console.WriteLine(iExitCode.ToString());

//終了コードをOSに返して終了

Environment.Exit(iExitCode);

}

上記で、ProcessStartInfoクラスに情報をセットする方法でしたが、それとは別に Process.Start のスタティックメソッドでプロセスを簡単に起動したい場合は、Process.Start(実行ファイル名,ユーザ名,パスワード,ドメイン名) としてもいいようです。

参考:

@IT:別のユーザーでほかのアプリケーションを実行するには?

@IT:コマンド・プロンプトを表示せずにコンソール・アプリケーションを実行するには?ProcessStartInfo.CreateNoWindow、ProcessStartInfo.UseShellExecuteプロパティがキックしたプロセスの表示にどう影響するかが参考になります。

C# - 細かい条件を指定してプログラムを起動する