2011-03-15 69 views
32

C#을 사용하여 Windows 서비스에서 EXE 프로그램을 어떻게 실행합니까? 나는이 서비스를 실행하면 응용 프로그램이 시작되지C#을 사용하여 Windows 서비스에서 EXE 프로그램을 실행하려면 어떻게해야합니까?

System.Diagnostics.Process.Start(@"E:\PROJECT XL\INI SQLLOADER\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2\bin\Debug\ConsoleApplication2.exe"); 

:

내 코드입니다.
내 코드에 어떤 문제가 있습니까?

+1

지금까지 내가 말할 수있는, 당신은 예외를 얻고있다 작성된 코드와 아무 문제가 없다? –

+0

이 프로그램을 실행할 때 어떤 일이 발생했는지 알려주십시오. – NT88

답변

0

다른 위치로 .exe를 복사한다고 생각합니다. 이것은 내가 생각하는 문제일지도 모른다. exe 파일을 복사하면 종속 파일을 복사하지 않습니다. 모든 .NET EXE는 그렇지

에 액세스 할 수 있도록

그래서, 무엇 당신이 할 수있는, 새로운 위치로 EXE 파일을 복사하지 마십시오, GAC에 모든 종속 DLL을 넣어. 그냥 환경 변수를 만들고 C#에서 exe를 호출하십시오. 경로는 환경 변수에 정의되어 있으므로 exe는 C# 프로그램에서 액세스 할 수 있습니다.

업데이트 : 내 C# .NET을 나는 C# .NET 코드에서 .exe 파일을 실행하려고 한 3.5 프로젝트에 같은 문제의 어떤 종류를했고, 그 EXE가 다른 프로젝트에 지나지 않았다 이전

exe (내 기능에 대한 지원 DLL 몇 개를 추가 한 곳) 및 exe 응용 프로그램에서 사용하고있는 DLL 메서드. 마지막으로이 솔루션을 동일한 솔루션에 대한 별도의 프로젝트로 만들어이 프로젝트를 내 배포 프로젝트에 추가했습니다. 이 시나리오에 따르면 나는 대답했다. 그가 원하는 것이 아니라면, 나는 매우 유감 스럽다.

+1

EXE가 다른 위치로 복사되고 있다는 느낌을주는 이유는 무엇입니까? –

46

최소한 Windows Vista 이상에서는이 작동하지 않습니다. 주요 문제는 표준 Windows 응용 프로그램이 아닌 Windows 서비스 내에서이 작업을 실행하려고한다는 것입니다. 표시 한 코드는 Windows Forms, WPF 또는 콘솔 응용 프로그램에서 완벽하게 작동하지만 Windows 서비스에서는 전혀 작동하지 않습니다.

Windows 서비스는 특정 사용자의 컨텍스트에서 실행 중이기 때문에 추가 응용 프로그램을 시작할 수 없습니다. 일반 Windows 응용 프로그램과 달리 services are now run in an isolated session은 사용자 나 데스크톱과 상호 작용할 수 없습니다. 따라서 응용 프로그램을 실행할 장소가 없습니다.

자세한 내용은 다음 관련 질문에 대한 답변에서 사용할 수 있습니다 :

문제에 대한 가장 좋은 해결책, 당신은 아마 말 그대로 이제는 서비스 대신 표준 Windows 응용 프로그램을 만드는 것입니다. 이들은 특정 사용자가 실행하도록 설계되었으며 해당 사용자의 데스크탑과 연관됩니다. 이렇게하면 이미 보여준 코드를 사용하여 필요할 때마다 추가 응용 프로그램을 실행할 수 있습니다.

또 다른 가능한 해결책은 콘솔 응용 프로그램이 어떤 종류의 인터페이스 나 출력을 요구하지 않는다고 가정하면 프로세스를 창을 만들지 않도록 지시하는 것입니다. 이렇게하면 더 이상 콘솔 창을 만들지 않기 때문에 Windows에서 프로세스 생성을 차단하지 않습니다. 관련 질문은 this answer에서 찾을 수 있습니다.

+3

EXE의 이름을 기반으로 콘솔 응용 프로그램을 시작하려고 시도하고 있으므로이 프로그램과 상호 작용할 것으로 예상하지 않으므로 서비스에서 실행하는 데 아무런 문제가 없습니다. – Gabe

+0

@Gabe : 콘솔 응용 프로그램은 여전히 ​​인터페이스를 표시합니다. 데스크탑이 없다면 그 인터페이스를 어디에 표시해야합니까? –

+0

답장을 보내 주셔서 감사합니다.하지만 박쥐 파일을 호출해도 문제가되지 않습니다. – xoops

1

Windows XP에서 Windows 서비스의 .exe를 잘 실행할 수 있습니다. 나는 과거에 나 자신을 해냈다.

Windows 서비스 속성에서 "데스크톱과 상호 작용하도록 허용"옵션을 선택했는지 확인해야합니다. 완료되지 않으면 실행되지 않습니다.

Windows 7 또는 Vista에서 추가 보안 권한이 필요하므로 오류가 발생할 수 있으므로이 확인란을 직접 또는 간접적으로 수행 할 수 있는지 확인해야합니다. XP의 경우, 내가 직접 한 것처럼 확실합니다.

+0

그것은 exe가 열릴 때마다 승리 7에 자극한다. –

-9

System.Diagnostics.Process.Start ("Exe Name");

+0

그것의 작동하지 않습니다 .. –

2

먼저 우리는 시스템 계정으로 실행되는 Windows 서비스를 만들 것입니다. 이 서비스는 현재 활성화 된 사용자 세션 내에서 대화 형 프로세스를 생성 할 책임이 있습니다. 이 새로 생성 된 프로세스는 UI를 표시하고 전체 관리자 권한으로 실행됩니다. 첫 번째 사용자가 컴퓨터에 로그온하면이 서비스는 으로 시작되어 Session0에서 실행됩니다. 그러나 이 서비스가 시작되는 프로세스는 현재 로그온 한 사용자의 바탕 화면에서 실행됩니다. 이 서비스는 LoaderService로 참조합니다.

다음으로 winlogon.exe 프로세스는 사용자 로그인 및 로그 아웃 절차를 관리합니다. 컴퓨터에 로그온하는 모든 사용자는 고유 한 세션 ID와 해당 세션과 연결된 winlogon.exe 프로세스를 갖게됩니다. 이제 위에서 을 언급했으며 LoaderService는 시스템 계정으로 실행됩니다. 또한 컴퓨터의 각 winlogon.exe 프로세스가 시스템 계정 에서 실행됨을 확인했습니다. 시스템 계정은 LoaderService와 winlogon.exe 프로세스의 소유자이기 때문에 LoaderService 은 winlogon.exe 프로세스의 액세스 토큰 (및 세션 ID)을 복사 한 다음 Win32 API 함수 CreateProcessAsUser를 호출하여 CreateProcessAsUser를 호출하여 로그온 한 사용자의 현재 활성 세션으로의 프로세스. 복사 된 winlogon.exe 프로세스의 액세스 토큰 내에있는 세션 ID가 0보다 커서 해당 토큰을 사용하여 대화식 프로세스를 시작할 수 있습니다.

보십시오. Subverting Vista UAC in Both 32 and 64 bit Architectures

3

나는이 기사를 시도했다. Code Project, 그것은 나를 위해 잘 작동하고있다. 나는 코드도 사용했다. 기사 스크린 샷과 함께 설명에 우수합니다.

나는 당신이 당신의 컴퓨터를 부팅하고 로그온하려고 한이 시나리오

에 필요한 설명을 추가하고있다. 로그온하면 시스템이 고유 한 세션 ID를 할당합니다. Windows Vista에서는 컴퓨터에 처음 로그온하는 사용자에게 OS에 의해 세션 ID 1이 할당됩니다. 로그온 할 다음 사용자에게 세션 ID 2가 할당됩니다. 작업 관리자의 사용자 탭에서 로그온 한 각 사용자에게 할당 된 세션 ID를 볼 수 있습니다. enter image description here

그러나 Windows 서비스는 세션 ID가 0입니다.이 세션은 다른 세션과 분리되어 있습니다.궁극적으로 Windows 서비스가 사용자 세션에서 실행되는 응용 프로그램을 1 또는 2와 같이 호출하는 것을 방지합니다.

Windows 서비스에서 응용 프로그램을 호출하려면 표시된대로 현재 로그인 한 사용자 역할을하는 컨트롤을 Windows 서비스에서 복사해야합니다 아래 스크린 샷. enter image description here

중요 코드

// obtain the process id of the winlogon process that 
// is running within the currently active session 
Process[] processes = Process.GetProcessesByName("winlogon"); 
foreach (Process p in processes) 
{ 
    if ((uint)p.SessionId == dwSessionId) 
    { 
     winlogonPid = (uint)p.Id; 
    } 
} 

// obtain a handle to the winlogon process 
hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid); 

// obtain a handle to the access token of the winlogon process 
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken)) 
{ 
    CloseHandle(hProcess); 
    return false; 
} 

// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser 
// I would prefer to not have to use a security attribute variable and to just 
// simply pass null and inherit (by default) the security attributes 
// of the existing token. However, in C# structures are value types and therefore 
// cannot be assigned the null value. 
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 
sa.Length = Marshal.SizeOf(sa); 

// copy the access token of the winlogon process; 
// the newly created token will be a primary token 
if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, 
    (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, 
    (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup)) 
    { 
     CloseHandle(hProcess); 
     CloseHandle(hPToken); 
     return false; 
    } 

STARTUPINFO si = new STARTUPINFO(); 
si.cb = (int)Marshal.SizeOf(si); 

// interactive window station parameter; basically this indicates 
// that the process created can display a GUI on the desktop 
si.lpDesktop = @"winsta0\default"; 

// flags that specify the priority and creation method of the process 
int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; 

// create a new process in the current User's logon session 
bool result = CreateProcessAsUser(hUserTokenDup, // client's access token 
          null,    // file to execute 
          applicationName, // command line 
          ref sa,   // pointer to process SECURITY_ATTRIBUTES 
          ref sa,   // pointer to thread SECURITY_ATTRIBUTES 
          false,   // handles are not inheritable 
          dwCreationFlags, // creation flags 
          IntPtr.Zero,  // pointer to new environment block 
          null,    // name of current directory 
          ref si,   // pointer to STARTUPINFO structure 
          out procInfo  // receives information about new process 
          ); 
+0

나를 위해 완벽하게 일했습니다. Windows 서비스를 통해 스캔을 요청하는 동안 스캐너에서 오류를 표시 할 수있었습니다. 고맙습니다 –

+0

경우 솔루션 +1합니다. – Vijayaraghavan

+0

이미 답변을 +1했습니다 –

관련 문제