64ビットマシンでシェル実行を使用せずにC#で32ビットプロセスを開始するにはどうすればよいですか?
-
25-10-2019 - |
質問
レガシー32ビットレポートアプリケーションを実行する必要がある64ビットマシンにASP .NET Webアプリケーションがあります。
プログラムを実行したとき UseShellExecute = false
, 、プログラムは出口コードで終了します:
-1073741502
別のユーザーとしてプロセスを実行する必要があるため、シェルエグゼトルを使用できません。しかし、シェルの実行が真実である場合、プロセスは正常に実行されます(ただし、ASP .NETが実行しているユーザーを変更する必要があります)。
使用せずにC#を使用してこの32ビットプログラムを開始するにはどうすればよいですか?
これが私が今持っているコードです:
var pxs = new ProcessStartInfo
{
Arguments = arguments,
CreateNoWindow = true,
Domain = ConfigurationManager.AppSettings["reportUserDomain"],
UserName = ConfigurationManager.AppSettings["reportUserName"],
Password = GetSecureString(ConfigurationManager.AppSettings["reportUserPassword"]),
LoadUserProfile = true,
FileName = ConfigurationManager.AppSettings["reportRuntime"],
UseShellExecute = false
};
var px = new Process
{
StartInfo = pxs
};
px.Start();
px.WaitForExit();
解決
を含むコードを囲んだ場合はどうなりますか UseShellExecute = true
, 、Windowsネイティブの「LogOnuser」メソッドを使用しますか?私はこれをいくつかのプロジェクトで正常に使用して何かをしました 似ている.
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool LogonUser(String lpszUserName, String lpszDomain,
String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken
フレッシュクリックメディアはこれに関する記事を作成し、サンプルになりすましクラスを書きました: - > http://www.freshclickmedia.com/blog/2008/11/programmatic-impersonation-in-ch/
しかし、完全性のために、私のバージョンは次のとおりです。
public class Impersonator : IDisposable
{
private WindowsImpersonationContext _impersonatedUser = null;
private IntPtr _userHandle;
// constructor for a local account. username and password are arguments.
public Impersonator(string username, string passwd)
{
_userHandle = new IntPtr(0);
string user = username;
string userDomain = "."; // The domain for a local user is by default "."
string password = passwd;
bool returnValue = LogonUser(user, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);
if (!returnValue)
throw new ApplicationException("Could not impersonate user");
WindowsIdentity newId = new WindowsIdentity(_userHandle);
_impersonatedUser = newId.Impersonate();
}
// constructor where username, password and domain are passed as parameters
public Impersonator(string username, string passwd, string domain)
{
_userHandle = new IntPtr(0);
string user = username;
string userDomain = domain;
string password = passwd;
bool returnValue = LogonUser(user, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);
if (!returnValue)
throw new ApplicationException("Could not impersonate user");
WindowsIdentity newId = new WindowsIdentity(_userHandle);
_impersonatedUser = newId.Impersonate();
}
public void Dispose()
{
if (_impersonatedUser != null)
{
_impersonatedUser.Undo();
CloseHandle(_userHandle);
}
}
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_SERVICE = 3;
public const int LOGON32_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
}
あなたの場合にそれを使用することは次のとおりです。
var domain = ConfigurationManager.AppSettings["reportUserDomain"];
var username = ConfigurationManager.AppSettings["reportUserName"];
var password = ConfigurationManager.AppSettings["reportUserPassword"];
using (Impersonator impersonator = new Impersonator(username, password, domain))
{
var pxs = new ProcessStartInfo
{
Arguments = arguments,
CreateNoWindow = true,
LoadUserProfile = true,
FileName = ConfigurationManager.AppSettings["reportRuntime"],
UseShellExecute = true
};
var px = new Process
{
StartInfo = pxs
};
px.Start();
px.WaitForExit();
}
所属していません StackOverflow