2011-04-28 4 views
2

레거시 32 비트보고 응용 프로그램을 실행해야하는 64 비트 시스템에 ASP .NET 웹 응용 프로그램이 있습니다. 내가 UseShellExecute = false으로 프로그램을 실행하면64 비트 컴퓨터에서 쉘 실행을 사용하지 않고 C#에서 32 비트 프로세스를 시작하는 방법은 무엇입니까?

, 프로그램은 종료 코드로 종료 : 나는 다른 사용자로 프로세스를 실행해야하기 때문에

-1073741502

내가 쉘 실행을 사용할 수 없습니다. 그러나 Shell Execute가 true 일 때 프로세스가 잘 실행됩니다 (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(); 
+0

이 작업은 32 비트 프로세스라는 것을 강조하고 있습니다. 64 비트 프로세스에서 제대로 작동하기 때문입니까? – Gabe

+1

64 비트 응용 프로그램에서 프로세스를 시작한다고해서 하위 응용 프로그램이 64 비트인지는 결정되지 않습니다. 하위 응용 프로그램은 별도의 프로세스이며 32/64 비트 니스는 다른 모든 프로그램이 결정되는 것과 같은 방식으로 결정됩니다. 64 또는 32로 명시 적으로 컴파일되지 않은 .Net 앱은 OS에 기본으로 제공됩니다. 64 비트 OS는이를 64 비트로 실행하지만 32 비트 OS는 32 비트로 실행됩니다. –

+1

ASP.NET이 LocalSystem 계정으로 실행 중이면'CreateProcessWithLogonW' (장면을 나타내는 데 사용되는 함수 호출)가 실패합니다. http://msdn.microsoft.com/en-us/library/ms682431(VS.85) .aspx – Gabe

답변

3

당신이 윈도우 네이티브 "LogonUser"방법, UseShellExecute = true 포함하여 코드를 포위하는 경우? 몇 가지 프로젝트에서 성공적으로 이것을 사용하여 과 비슷한을 수행했습니다.

[DllImport("advapi32.dll", CharSet = CharSet.Auto)] 
public static extern bool LogonUser(String lpszUserName, String lpszDomain, 
    String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken 

신선한 클릭 미디어는이에 대한 기사를했고, 샘플로 가장 클래스를 썼다 : - : 그것을 사용

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); 
} 

>

하지만 완전성에 대한 http://www.freshclickmedia.com/blog/2008/11/programmatic-impersonation-in-c/는, 여기의 내 버전입니다 귀하의 사례는 다음과 같습니다 :

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(); 
} 
+0

OP에는 'UseShellExecute = false'가 필요합니다. – Gabe

+0

@Gabe : 프로세스가 가장의 결과로 다른 사용자로 시작된 경우 아닙니다. –

+0

그 해결 방법은 훌륭했습니다. – Ryan