아래 방법으로 서비스에서 응용 프로그램를 실행해 보았는데,
프로그램의 UI는 나타나지 않고
작업 관리자에 프로세스 실행은 확인 할 수 있었다. 제대로 동작하는지는 알 수 없ㅋ엉ㅋ ㅜㅜ
서비스에서는 콘솔, 윈도우 UI를 제공하지 않아서
이것들을 가지고 있는 프로그램은 나타나지 않는다
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(si);
si.lpDesktop = "WinSta0\\default";
CreateProcess( NULL, "c:\\1.txt", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
==========================================================================
C++빌더나 Delphi로 Service 프로그램 만드는것은 매우 쉽습니다.
그런데 이 서비스프로그램에서 일반 윈도우 어플리케이션을 실행하거나
어플리케이션과 통신을 해야 할때는 좀 까다로운 부분이 있습니다.
그 이유는
Sercive가 실행되는 desktop이 일반 어플리케이션이 실행되는 desktop이 다르기 때문입니다.
http://cafe.naver.com/bcbmaster/765
그래서 Service프로그램에서 윈도우 어플리케이션을 실행하면 정상적으로 실행이 잘안됩니다.
또한 Service에서
FindWindow, EnumWindows 등으로
desktop에 실행된 윈도우 핸들도 찾아지지 않으며
당연히 SendMessage로 메세지를 보낼수도 없습니다..(불가능한것은 아님)
[Service에서 default 데트스탑에 어플리케이션 실행하기]
그럼 Service프로그램에서 logon한 user화면에 어플리케이션을 실행하려면 어떻게 해야 할까요?
간단합니다.
CreateProcess로 프로그램을 실행하면서
9번째 파라메터로 넘기는 STARTUPINFO 구제체에서 lpDesktop에 해당 desktop을 설정해주면 됩니다.
[델파이 예제]
| procedure TService1.ServiceCreate(Sender: TObject); var si: STARTUPINFO; pi : PROCESS_INFORMATION; bResult : Boolean; begin
ZeroMemory( @si, sizeof(si) ); si.cb := sizeof(si); si.lpDesktop:=PChar('WinSta0\default'); // 이부분이 핵심
bResult := CreateProcess( nil, // No module name (use command line). 'C:\Zzang\[기술예제]\DelphiToHTML\DelphiToHTML.exe', // Command line. nil, // Process handle not inheritable. nil, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. 0, // No creation flags. nil, // Use parent's environment block. nil, // Use parent's starting directory. si, // Pointer to STARTUPINFO structure. pi ); // Pointer to PROCESS_INFORMATION structure. )
end; | |
만약 로그인 화면에 어플리케이션을 실행하려면
STARTUPINFO 구조체의 lpDesktop에 "WinSta0\Winlogon" 으로 설정해주면됩니다.
[서비스 프로그램에서 FindWindow , SendMessage를 사용하려면]
일반 윈도우 프로그램과 SendMessage등 상호 작용이 가능한 Service프로그램을
Interactive Service라고 합니다..
다시말해 Service프로그램을 Interactive Service로 설정해놓으면 일반 윈도우 어플리케이션과 상호작용이 가능합니다.
그럼 Service프로그램을 어떻게 Interactive Service로 설정할까요?
서비스 - 속성 - 로그온 에서 "서비스와 테스트톱 상호 작용 허용"을 체크해 놓으면 된다.
참조 http://www.simpleisbest.net/archive/2005/10/18/260.aspx
그런데 일반 사용자가 Service 속성을 열어서 직접 수정할수는 없으니
Service프로그램을 Windows에 install할때 설정해서 install 해야 한다.
보통 서버스를 install 하려면 command 모드에서 서비스실행파일네임.exe /install 하면 설치되고
서비스실행파일네임.exe /uninstall 하면 uninstall 된다.
그런데 Interactive Service로 install하려면
CreateService로 서비스 프로그램을 인스톨해야 합니다.
참조 http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=7998&ref=7998
그런데 위 그림을 보면 "로컬 시스템 계정"이라는 것 밑에 " Interactive Service"관련 항목이 있다.
즉 " Interactive Service"는 로컬 시스템 계정에서만 동작한다는 것이다.
administrator가 아니면 user의 desktop의 윈도우와 상호작용이 불가능하다는 얘기...
앗참
Interactive Service에서 윈도우 어플리케이션을 실행하면 기본적으로
"WinSta0\default" 데스크톱에서 실행됩니다.
STARTUPINFO 의 lpDesktop을 설정하지 않아도 된다는....
참고로..
XP나 Vista 같은경우 로그아웃 하지 않고 여러명의 User로 로그인한 상태가 되는경우도 있습니다.
이경우 원하는 데스트탑에 프로그램이 뜨지 않고 엉뚱한(다른계정의 desktop)에 프로그램이 뜰수도 있습니다.
이 문제는 좀더 머리아픕니다.
그럼..
출처 http://www.delmadang.com/community/bbs_view.asp?bbsNo=17&bbsCat=41&indx=409951&page=393