2013-07-05 2 views
0

IIS, Windows Server 2008 R2에서 WCf 서비스를 호스팅하고 있으며 네트워크 서비스 ID가있는 AppPool .NET 4.0을 사용합니다.WCF 서비스 Process. 다른 사용자로 가장하는 네트워크 서비스 계정에서 시작

My Wcf Service에는 Process.Start를 사용하여 EXE 명령을 호출하는 메서드가 있습니다.

도메인 사용자 계정 인 EXE 실행 명령에 대한 자격 증명으로 다른 사용자를 사용해야합니다.

나는 그것을 시도한다. 그러나 그것은 나를 위해 일하지 않는다 : 그것은 EXE 명령을 실행하지 않는 것 같다.

갱신 : 프로세스가 종료하지만, 내가 할

코드를 실행할 수 없습니다와 같은 오류 :

종료 코드 -1073741502

및 eventvwr을 다음 appplication가 없습니다

  Process Information: 
      Process ID:   0xc50 
      Process Name:  C:\DeployTools\DeployTools.Commands.Ejecutar.exe 
      Exit Status:   0xc0000142 

올바르게 시작하려면 (0xC0000142). 확인을 클릭하십시오 응용 프로그램을 닫습니다

어떤 제안이 있습니까?

코드 :

 StreamReader sr = null; 
     StreamReader serr = null; 

     try 
     { 
      var psi = new ProcessStartInfo(MY_COMMAND_EXE); 
      psi.WorkingDirectory = Path.GetDirectoryName(MY_COMMAND_EXE); 
      psi.Arguments = arguments; 
      psi.Domain = DOMAIN; 
      psi.UserName = USER_IN_DOMAIN; 
      psi.Password = SecureStringHelper.ToSecureString(pwd); 

      psi.LoadUserProfile = true; 
      psi.UseShellExecute = false; 

      psi.ErrorDialog = false; 
      psi.RedirectStandardOutput = true; 
      psi.RedirectStandardInput = true; 
      psi.RedirectStandardError = true; 
      psi.CreateNoWindow = true; 
      psi.WindowStyle = ProcessWindowStyle.Minimized; 

      using (Process pr = Process.Start(psi)) 
      { 
       sr = pr.StandardOutput; 
       serr = pr.StandardError; 

       if (!pr.HasExited) 
       { 
        pr.WaitForExit(300000); 
       } 
       output = pr.StandardOutput.ReadToEnd(); 
       errors = pr.StandardError.ReadToEnd(); 
       exitCode = pr.ExitCode; 

       return output; 
      } 
     } 
     catch (Exception exc) 
     { 
      return "EXCEPCIÓN: " + exc.Message; 
     } 
     finally 
     { 
      if (sr != null) 
      { 
       sr.Close(); 
       sr.Dispose(); 
       sr = null; 
      } 

      if (serr != null) 
      { 
       serr.Close(); 
       serr.Dispose(); 
       serr = null; 
      } 
     } 
+0

가 확인할 수 요 ur 이벤트 로그 크기입니다. 종료 코드 '1502'의 마지막 4 자리는 이벤트 로그/오류 로그 파일이 가득 찬 것을 의미합니다. 이것이 문제인 경우 - http://www.howtogeek.com/howto/windows/fixing-the-event-log-is-full-error-on-windows-xp/ –

+0

로 해결할 수 있습니다. 문제. 이벤트 로그를 확인합니다. 비어 있습니다. 각 테스트 전에 로그를 지우십시오. – Kiquenet

+0

어셈블리 'AsproLock'은 강력한 이름을 갖고 있습니까? 어셈블리 생성 실패 - 참조 어셈블리 'AsproLock'에 강력한 이름이 없음 \t https://github.com/cloudfoundry-incubator/if_warden/tree/master/lib/AsproLock – Kiquenet

답변

2

본인은 실행중인 자원에 액세스 할 수 있도록 사용자 계정을 허용하기 위해 AsproLock.dll 참조 및 관련 코드를 추가했다.

  //The following security adjustments are necessary to give the new 
      //process sufficient permission to run in the service's window station 
      //and desktop. This uses classes from the AsproLock library also from 
      //Asprosys. 
      IntPtr hWinSta = NativeMethods.GetProcessWindowStation(); 
      WindowStationSecurity ws = new WindowStationSecurity(hWinSta, 
       System.Security.AccessControl.AccessControlSections.Access); 
      ws.AddAccessRule(new WindowStationAccessRule(userPassDto.Usuario, 
       WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow)); 
      ws.AcceptChanges(); 

      IntPtr hDesk = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()); 
      DesktopSecurity ds = new DesktopSecurity(hDesk, 
       System.Security.AccessControl.AccessControlSections.Access); 
      ds.AddAccessRule(new DesktopAccessRule(userPassDto.Usuario, 
       DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow)); 
      ds.AcceptChanges(); 

[DllImport("user32.dll", SetLastError = true)] 
public static extern IntPtr GetProcessWindowStation(); 

[DllImport("user32.dll", SetLastError = true)] 
public static extern IntPtr GetThreadDesktop(int dwThreadId); 

[DllImport("kernel32.dll", SetLastError = true)] 
public static extern int GetCurrentThreadId(); 

얼마나 위험한지와이 공통의 필요가 아니라 그것은 또한 드문되지 않습니다 Asprosys에 의해

을 새로운 자격 증명으로 프로세스를 시작의 함정, 그래서 내가 더 나은이 게시했다고 생각 가장 된 자격 증명을 사용하는 프로세스 시작 문제 해결 단계별 가이드 이것은 .Net Process 클래스의 Start 메소드를 사용하지만, 기본 API 호출 인 CreateProcessWithLogonW 및 CreateProcessWithTokenW에도 적용됩니다.

액세스가 거부되었습니다. - 첫 번째 시도와 액세스가 거부되었습니다. 예외가 발생했습니다. 이것은 가장 일반적인 초기 문제이며 서비스가 LOCAL SYSTEM 계정으로 실행되고 있기 때문에 발생합니다. 이상하게도 SYSTEM 계정은 컴퓨터에서 가장 강력한 계정이지만, 할 수없는 몇 가지 사항 중 하나는 Process.Start 호출의 기본 API 인 CreateProcessWithLogonW를 사용하여 프로세스를 시작하는 것입니다. 따라서 서비스 계정을 로컬 서비스로 변경하면 어쨌든 더 적합한 계정 일 것입니다.

액세스가 거부되었습니다. - 아,이 문제가 해결 된 것 같습니다. 죄송합니다. 실행하려는 응용 프로그램에 대한 사용 권한을 다시 확인하십시오. 시스템은 서비스 계정이 아닌 프로세스가 실행될 사용자 계정으로 응용 프로그램 파일에 액세스하려고합니다.

잘못된 디렉토리 오류 - 무엇? 모든 경로가 정확합니다. 모든 디렉토리의 철자가 정확하며 잘못된 문자는 없습니다. 이것은 엄청나게 짜증나는 오류이며 매우 일관성이 없습니다.일반적으로 프로세스를 실행할 때 WorkingDirectory 속성을 설정하는 것을 신경 쓰지 않고 부모 프로세스의 기본값을 그대로 사용합니다. 새로운 자격 증명으로 프로세스를 시작할 때 그렇게 할 수 없다면 WorkingDirectory에 대한 경로를 명시 적으로 설정해야합니다. 그렇지 않으면 "디렉토리 이름이 유효하지 않습니다."라는 메시지가 나타납니다. Win32Exception입니다.

실패 : 오류가 있습니까? - Process.Start는 새로운 프로세스를위한 환경 블록 생성을 매우 잘 처리합니다. 따라서 기본 API를 사용하는 경우에만 문제가됩니다. CreateProcess * API 중 하나를 호출 할 때 lpEnvironment 매개 변수를 NULL로두고 시스템이 부모 프로세스에서 블록을 복사하는 기본값을 사용하도록하는 것이 정상입니다. 그러나 새 자격 증명을 사용하여 시작하는 경우 수동으로 또는 CreateEnvironmentBlock을 사용하여 명시 적으로 환경 블록을 만들어야합니다. 더 나쁜 이유는 CreateProcess * 호출은 실패하지만 GetLastError는 ERROR_SUCCESS를 반환하고 환경 블록을 만드는 동안 오류가 발생하더라도 오류는 발생하지 않지만 프로세스가 전혀 실행되지 않을 수 있습니다.

응용 프로그램을 제대로 초기화하지 못했습니다. - 예외가 없으면 모든 문제가 해결되고 프로세스가 시작되었습니다. 죄송합니다. 프로세스가 어디에 있습니까? 이벤트 로그를 확인하십시오 (또는 응용 프로그램 오류 팝업이 수신되었을 수 있음). 응용 프로그램 오류에 대한 항목이 있어야 프로세스가 오류가있는 응용 프로그램이고 user32.dll 또는 kernel32.dll이 오류 모듈이며 예외는 0xC0000142입니다. 약간의 변형이있을 수 있지만 기본적으로 응용 프로그램을 초기화 할 수 없다고합니다. 그 이유는 초기화시 모든 응용 프로그램 코드를 실행하기 전에 모든 프로세스가 Window Station에 연결되고 모든 스레드가 데스크톱에 연결되어 있지만 실행중인 사용자에게는 Window Station 및 Desktop에 대한 액세스 권한이 없습니다 프로세스가 시작되고 초기화 할 수 없습니다. 프로세스가 시작되는 사용자에게 AllAccess 권한을 부여하려면 Window Station 및 Desktop의 보안 설명자가 조정되어야합니다. 이것은 .Net에서 직접 수행 할 수있는 악마이기 때문에 여기에서 보안 래퍼 클래스를 유용하게 사용할 수 있습니다.

더 이상 오류가 없습니다. - 오류가 없으므로 이제는 원활하게 실행되고 있어야합니다. 사용자가 누구인지에 따라 필요한 작업 (예 : 관리자가 일부 경우 올바른 권한을 이미 보유하고있는 경우) 또는 시작하는 세션의 종류에 따라 약간의 차이가있을 수 있습니다. 그러나 이러한 단계를 따르면 평생 동안 부드럽고 쉽게 (물론 어쩌면 당신의 평생).

참고 :

The Perils and Pitfalls of Launching a Process Under New Credentials

Aspro Lock - Access Control

Code Samples

Creating New Process Under Alternate Credentials (createprocessasuser)

processstart-hangs