2010-01-18 4 views
22

.NET 서비스에서 다른 사용자로 .NET 응용 프로그램을 시작하려고합니다. 아이디어는 Windows에서 샌드 박스 호스팅 응용 프로그램을 만드는 것입니다. 이 서비스에서, 나는 프로그램 적으로 윈도우에서 사용자를 생성하고, 그 사용자에 대한 폴더를 생성하고, 서버에서 호스트 .exe를 그 폴더로 다운로드한다. 그럼 System.Diagnostics.Process를 사용하여 호스트 .exe를 실행합니다. 여기에 프로세스의 StartInfo은 다음과 같습니다.NET 서비스에서 .NET 사용자를 다른 사용자로 시작할 때 사용 권한 문제가 있습니까?

_process = new Process 
{ 
    StartInfo = 
    { 
     Arguments = " -debug", 
     FileName = instanceDirectory + "host.exe", 
     WorkingDirectory = instanceDirectory, 
     UseShellExecute = false, 
     RedirectStandardError = true, 
     RedirectStandardOutput = true, 
     RedirectStandardInput = true, 
     UserName = Helpers.GetUserNameForInstance(_hostid), 
     Password = _hostpass, 
     Domain = "" 
    }, 
    EnableRaisingEvents = true 
}; 

내가 서비스로 서비스를 실행하면 프로세스가 -1073741502 오류 코드와 함께 즉시 충돌합니다. 그러나 Windows 서비스에 지정된 동일한 사용자로 서비스를 실행하지만 콘솔에서 대화식으로 실행하면 모든 것이 올바르게 작동합니다. 이는 서비스를 SERVICE로 실행하고 콘솔에서 직접 실행하지 않을 때만 발생합니다.

도움이 될 것입니다. 이제이 오랫동안 두통이었다 이것은 최후의 수단 :(

서비스 자격 증명을 일으킬 수 있습니다 서버 사이의 이중 홉이 떨어 얻을
+0

콘솔 응용 프로그램에서 실행되는 동일한 코드를 테스트 했습니까? –

+2

예, 모든 것이 잘 작동하여 독립 실행 형 모드로 실행됩니다. 서비스로만 실행되는 문제가 있습니다. –

+1

안녕하세요, 귀하가 말한 것처럼 서비스가 아닐 때 실행되기 때문에 권한 문제와 같은 것 같습니다. 이 링크는 도움이 될 수 있습니다. http://asprosys.blogspot.com/2009/03/perils-and-pitfalls-of-launching.html – keyboardP

답변

1

0xc0000142 (-1073741502)는 STATUS_DLL_INIT_FAILED된다. 동적 링크 라이브러리 [이름]의

초기화 실패

프로세스가 비정상적으로 종료되는

.

TenaciousImpy 웹 사이트에서 지적한 것처럼, 계정에 윈도우 스테이션과 데스크톱에 대한 권한을 부여해야합니다. 그러나 대화식 프로그램 인 경우에는 프로세스 토큰의 세션 ID도 설정해야합니다.

14

그것은 사용자 이름과 암호와 서비스 모드로 new Process()를 사용하는 것 같다 "계산하지 않는다":

견적을 MSDN에서 :

당신은에 지정된 매개 변수 를 변경할 수 있습니다 프로세스에서 Start 메서드를 호출 할 때까지 StartInfo 속성을 위로 설정하십시오. 프로세스를 시작한 후 StartInfo 값을 변경해도 관련된 프로세스 인 에 영향을주지 않거나 다시 시작하지 않습니다. 당신이 ProcessStartInfo를 함께 시작 (ProcessStartInfo를) 메소드를 호출하면 .. ::. 사용자 이름과 ProcessStartInfo를 .. ::. 비밀번호 속성을 설정, 관리되지 않는 CreateProcessWithLogonW 기능 새의 프로세스를 시작이라는 입니다 CreateNoWindow 속성 값이 true이거나 WindowStyle 속성 값이 Hidden 인 경우에도 마찬가지입니다.

또한 CreateProcessWithLogonW 문서 찾고 :

lpStartupInfo [IN]

STARTUPINFO 구조의 포인터.응용 프로그램은 지정한 사용자 계정에 권한을 추가해야합니다. WinSta0 \ Default에 대해서도 지정된 창 스테이션 및 데스크톱에 계정을 추가해야합니다.

lpDesktop 구성원이 NULL이거나 빈 문자열 인 경우 새 프로세스 은 데스크톱을 상속하고 부모 프로세스의 스테이션을 상속합니다. 응용 프로그램은 지정된 사용자 계정 에 대한 액세스 권한을 상속 된 창 스테이션 및 데스크톱에 추가해야합니다.

.NET StartupInfo에는 lpDesktop이 없지만 SERVICE 사용자에게는 문제가 발생할 수있는 바탕 화면이 없습니다.

길고도 짧은 이야기, true는 레지스트리에서 사용자의 정보를로드 할 LoadUserProfile로 설정 을 시도하거나

추가로 조사하려면 확인해야 어쩌면 당신은 등, 작업 디렉토리를 설정해야합니다 당신의 FileMon을 사용하여 어떤 파일에 액세스했는지 기록 할 수 있습니다.

5

아래와 같이 새로 생성 된 사용자의 가장 된 컨텍스트에서 프로세스를 만들려고합니다.

[DllImport("advapi32.DLL", SetLastError = true)] 
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
public extern static bool CloseHandle(IntPtr handle); 

[DllImport("advapi32.DLL")] 
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); 

static void Main() 
{    
    IntPtr admin_token = new IntPtr(); 
    WindowsIdentity wid_admin = null; 
    WindowsImpersonationContext wic = null; 

    LogonUser("username", "domain", "password", 9, 3, out admin_token); 
    wid_admin = new WindowsIdentity(admin_token); 
    wic = wid_admin.Impersonate(); 

    _process = new Process 
    { 
     StartInfo = 
     { 
      Arguments = " -debug", 
      FileName = instanceDirectory + "host.exe", 
      WorkingDirectory = instanceDirectory, 
      UseShellExecute = false, 
      RedirectStandardError = true, 
      RedirectStandardOutput = true, 
      RedirectStandardInput = true, 
      UserName = Helpers.GetUserNameForInstance(_hostid), 
      Password = _hostpass, 
      Domain = "" 
     }, 
     EnableRaisingEvents = true 
    }; 

    if (wic != null) wic.Undo(); 
    CloseHandle(admin_token); 
} 
+0

나는 그것을 시도했지만 도움이되지 않았다. Gyuri가 인용 한 것을 다시 언급하자면 사용자가 서비스가 속한 윈도우 스테이션 및 데스크톱을 사용할 수있는 권한을 부여 받아야하는 것처럼 보입니다. – jamessan

관련 문제