Windows EXE can work as a service or application. How can I determine if it works as a service or not?

I'm looking for a Win32 API call to return the runtime context of my process. I want to be able to programmatically test whether I am running as a service or running as a standard application process.

A few ideas come to mind ... Since I always have the DAD.exe service, which sometimes runs SON.exe as its child, and in the context of the service --- and sometimes SON.exe is launched not by DAD, but by the user.

SON.EXE will run the whoami () API to find out in what context it works.

Now DAD can create a var environment - and then SON can check this var - and if it finds out that it knows that it is the son of DAD and thus works as a service ..... But this is weak ..

Another idea is to look at my SID or token and see if I can make this determination .... Again, this looks best harder against one API check ...

+6
source share
5 answers

A simple low-tech solution for this is to register your service to run with command line arguments that identify it as a service.

+1
source

Another option is to use a tool library of tools . Using it, you take a snapshot of all currently running processes, and then you can go through all the processes using Process32First and Process32Next . They return a structure ( PROCESSENTRY32 ) that looks like this:

typedef struct tagPROCESSENTRY32 { DWORD dwSize; DWORD cntUsage; DWORD th32ProcessID; ULONG_PTR th32DefaultHeapID; DWORD th32ModuleID; DWORD cntThreads; DWORD th32ParentProcessID; LONG pcPriClassBase; DWORD dwFlags; TCHAR szExeFile[MAX_PATH]; } PROCESSENTRY32, *PPROCESSENTRY32; 

when you go through all the processes, as soon as you find one whose th32ProcessID matches the one for SON.exe (see GetCurrentProcessId or GetProcessId ). If the identifier th32ParentProcessID of this structure matches the type DAD.exe, then you know that you were started from DAD.exe.

Edit: Answering your comment, I think you can go even further and then see who is the parent of DAD.exe, if it is service.exe, then you are a service.

+1
source

Reading the documentation, I think you could determine if you are in an interactive session or service through:

and then WSF_VISIBLE should tell you.

If you want to distinguish between a logon session and an inactive (Fast User Switching), I think you could use GetThreadDesktop and GetUserObjectInformation(UOI_IO) .


The best and easiest way to tell from inside a service is to set a flag when calling ServiceMain . But you are testing a child process, so see above.

+1
source

I found the following:

 bool WinUtil::IsServiceUser(HANDLE hToken, bool *is_service) { if (is_service == NULL) { return false; } TOKEN_STATISTICS ts; DWORD dwSize = 0; // Use token logon LUID instead of user SID, for brevity and safety if (!::GetTokenInformation(hToken, TokenStatistics, (LPVOID)&ts, sizeof(ts), &dwSize)) { return false; } // Compare LUID const LUID SystemLuid = SYSTEM_LUID; const LUID LocalServiceLuid = LOCALSERVICE_LUID; const LUID NetworkServiceLuid = NETWORKSERVICE_LUID; if (EqualLuid(SystemLuid, ts.AuthenticationId) || EqualLuid(LocalServiceLuid, ts.AuthenticationId) || EqualLuid(NetworkServiceLuid, ts.AuthenticationId)) { *is_service = true; return true; } // Not a service account *is_service = false; return true; } bool WinUtil::IsServiceProcess(bool *is_service) { if (is_service == NULL) { return false; } if (Util::IsVistaOrLater()) { // Session 0 is dedicated to services DWORD dwSessionId = 0; if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &dwSessionId) || (dwSessionId == 0)) { *is_service = true; return true; } } // Get process token HANDLE hProcessToken = NULL; if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hProcessToken)) { return false; } ScopedHandle process_token(hProcessToken); // Process token is one for a service account. if (!IsServiceUser(process_token.get(), is_service)) { return false; } return true; } 
+1
source

I think you're looking for Topshelf http://topshelf-project.com/ , it does the hard work and makes it easy to run as a console or install as a service, Debugging Topshelf application hosting in VS2010

0
source

Source: https://habr.com/ru/post/898319/


All Articles