Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Service not created correctly under windows 11 but any older version.

Service not created correctly under windows 11 but any older version.

Scheduled Pinned Locked Moved C / C++ / MFC
sysadminhelpquestionannouncement
10 Posts 2 Posters 55 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Rick R 2023
    wrote on last edited by
    #1

    I'm using the following function for years and used it under any Version of Windows since XP. It creates a systemtask with the start type set to "auto", just like it is expected to do. But under windows 11, the start type of the installed service always defaults to "manual" when being created. Any help solving this is very much appreciated. Am using VS2022 using toolset 1.41_XP (for reasons) (already added some extra check for win 11... but still the start type defaults to manual in the newly created task)

    static int manage_service(int action) {
    SC_HANDLE hSCM = NULL, hService = NULL;
    SERVICE_DESCRIPTION descr = { server_name };
    char path[PATH_MAX + 20]; // Path to executable plus magic argument
    int success = 1;

    GetModuleFileName(NULL, path, sizeof(path));
    strncat(path, " ", sizeof(path));
    strncat(path, service\_magic\_argument, sizeof(path));
    
    if (IsRunAsAdministrator()) {
    	if ((hSCM = OpenSCManager(NULL, NULL, action == ID\_INSTALL\_SERVICE ?
    		GENERIC\_WRITE : GENERIC\_READ)) == NULL) {
    		success = 0;
    		show\_error();
    	}
    	else if (action == ID\_INSTALL\_SERVICE) {
    		hService = CreateService(hSCM, service\_name, service\_name,
    			SERVICE\_ALL\_ACCESS, SERVICE\_WIN32\_OWN\_PROCESS,
    			SERVICE\_AUTO\_START, SERVICE\_ERROR\_NORMAL,
    			path, NULL, NULL, NULL, NULL, NULL);
    		if (hService) {
    			ChangeServiceConfig(hService, SERVICE\_NO\_CHANGE, SERVICE\_AUTO\_START,
    				SERVICE\_NO\_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    			ChangeServiceConfig2(hService, SERVICE\_CONFIG\_DESCRIPTION, &descr);
    
    			// Check Windows version
    			OSVERSIONINFOEX osvi;
    			ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
    			osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    			osvi.dwMajorVersion = 11; // Windows 11
    
    			if (GetVersionEx((OSVERSIONINFO\*)&osvi)) {
    				// Set start type to AUTO\_START for Windows 11
    				ChangeServiceConfig(hService, SERVICE\_NO\_CHANGE, SERVICE\_AUTO\_START,
    					SERVICE\_NO\_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    			}
    		}
    		else {
    			show\_error();
    		}
    	}
    	else if (action == ID\_REMOVE\_SERVICE) {
    		if ((hService = OpenService(hSCM, service\_name, DELETE)) == NULL ||
    			!DeleteService(hService)) {
    			show\_error();
    		}
    	}
    	else if ((hService = OpenService(hSCM, service\_name,
    		SERVICE\_QUERY\_STATUS)) == NULL) {
    		success = 0;
    	}
    
    	CloseServiceHandle(hService);
    	CloseServiceHandle(hSCM);
    }
    else {
    	if (action == ID\_INSTALL\_SERVICE) {
    		RunServiceAsAdmin('I', path, service\_name);
    	}
    	else if (action == ID\_REMOVE\_
    
    L 1 Reply Last reply
    0
    • R Rick R 2023

      I'm using the following function for years and used it under any Version of Windows since XP. It creates a systemtask with the start type set to "auto", just like it is expected to do. But under windows 11, the start type of the installed service always defaults to "manual" when being created. Any help solving this is very much appreciated. Am using VS2022 using toolset 1.41_XP (for reasons) (already added some extra check for win 11... but still the start type defaults to manual in the newly created task)

      static int manage_service(int action) {
      SC_HANDLE hSCM = NULL, hService = NULL;
      SERVICE_DESCRIPTION descr = { server_name };
      char path[PATH_MAX + 20]; // Path to executable plus magic argument
      int success = 1;

      GetModuleFileName(NULL, path, sizeof(path));
      strncat(path, " ", sizeof(path));
      strncat(path, service\_magic\_argument, sizeof(path));
      
      if (IsRunAsAdministrator()) {
      	if ((hSCM = OpenSCManager(NULL, NULL, action == ID\_INSTALL\_SERVICE ?
      		GENERIC\_WRITE : GENERIC\_READ)) == NULL) {
      		success = 0;
      		show\_error();
      	}
      	else if (action == ID\_INSTALL\_SERVICE) {
      		hService = CreateService(hSCM, service\_name, service\_name,
      			SERVICE\_ALL\_ACCESS, SERVICE\_WIN32\_OWN\_PROCESS,
      			SERVICE\_AUTO\_START, SERVICE\_ERROR\_NORMAL,
      			path, NULL, NULL, NULL, NULL, NULL);
      		if (hService) {
      			ChangeServiceConfig(hService, SERVICE\_NO\_CHANGE, SERVICE\_AUTO\_START,
      				SERVICE\_NO\_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
      			ChangeServiceConfig2(hService, SERVICE\_CONFIG\_DESCRIPTION, &descr);
      
      			// Check Windows version
      			OSVERSIONINFOEX osvi;
      			ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
      			osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
      			osvi.dwMajorVersion = 11; // Windows 11
      
      			if (GetVersionEx((OSVERSIONINFO\*)&osvi)) {
      				// Set start type to AUTO\_START for Windows 11
      				ChangeServiceConfig(hService, SERVICE\_NO\_CHANGE, SERVICE\_AUTO\_START,
      					SERVICE\_NO\_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
      			}
      		}
      		else {
      			show\_error();
      		}
      	}
      	else if (action == ID\_REMOVE\_SERVICE) {
      		if ((hService = OpenService(hSCM, service\_name, DELETE)) == NULL ||
      			!DeleteService(hService)) {
      			show\_error();
      		}
      	}
      	else if ((hService = OpenService(hSCM, service\_name,
      		SERVICE\_QUERY\_STATUS)) == NULL) {
      		success = 0;
      	}
      
      	CloseServiceHandle(hService);
      	CloseServiceHandle(hSCM);
      }
      else {
      	if (action == ID\_INSTALL\_SERVICE) {
      		RunServiceAsAdmin('I', path, service\_name);
      	}
      	else if (action == ID\_REMOVE\_
      
      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      Hmmm, Your code looks good to me. Although it would be nice if you captured the return values of ChangeServiceConfig. I would recommend debugging this by checking the Event logs. Look for event ID 7040 in the "Service Control Manager" log source. You might need to enable auditing. Also, try temporarily adding a Windows Defender exclusion on the service file path if your executable is unsigned/untrusted. I'm wondering if Defender is blocking the change.

      R 1 Reply Last reply
      0
      • L Lost User

        Hmmm, Your code looks good to me. Although it would be nice if you captured the return values of ChangeServiceConfig. I would recommend debugging this by checking the Event logs. Look for event ID 7040 in the "Service Control Manager" log source. You might need to enable auditing. Also, try temporarily adding a Windows Defender exclusion on the service file path if your executable is unsigned/untrusted. I'm wondering if Defender is blocking the change.

        R Offline
        R Offline
        Rick R 2023
        wrote on last edited by
        #3

        Just found out somethhing more.... As soon as I invoke the service creation function from within the program, I do get the normal service controll manager asking for elevated rights in order to create the service, what is exactly what happen. But then the service gets created with start type set to "manual". If I do start the program manually "as Administrator" and then invoke the service creation function, the service gets created correctly with start type "auto". So there probably might be a problem with my elevation of rights!?... will check this. Strange though, that it works fin under any Windows version since XP... just not windows 11... Here is the code to start with elevated rights:

        BOOL IsRunAsAdministrator()
        {
        BOOL isRunAsAdmin = FALSE;
        DWORD dwError = ERROR_SUCCESS;
        PSID pAdministratorsGroup = NULL;

        // Allocate and initialize a SID of the administrators group.
        SID\_IDENTIFIER\_AUTHORITY NtAuthority = SECURITY\_NT\_AUTHORITY;
        if (!AllocateAndInitializeSid(
            &NtAuthority, 
            2, 
            SECURITY\_BUILTIN\_DOMAIN\_RID, 
            DOMAIN\_ALIAS\_RID\_ADMINS, 
            0, 0, 0, 0, 0, 0, 
            &pAdministratorsGroup))
        {
            goto Cleanup;
        }
        
        // Determine whether the SID of administrators group is enabled in 
        // the primary access token of the process.
        if (!CheckTokenMembership(NULL, pAdministratorsGroup, &isRunAsAdmin))
        {
            goto Cleanup;
        }
        

        Cleanup:
        // Centralized cleanup for all allocated resources.
        if (pAdministratorsGroup)
        {
        FreeSid(pAdministratorsGroup);
        pAdministratorsGroup = NULL;
        }

        return isRunAsAdmin;
        

        }

        void RunServiceAsAdmin(char ch, const char *program, const char* name)
        {
        // Launch itself as admin
        char param[255];
        SHELLEXECUTEINFO sei = { sizeof(sei) };

        memset(param, 0 , sizeof(param));
        sei.lpVerb = "runas";
        sei.lpFile = "sc.exe";
        sei.hwnd = NULL;
        sei.nShow = SW\_NORMAL;
        
        if(ch == 'I')
        {
        	sprintf(param, "create \\"%s\\" binPath= \\"%s\\" DisplayName=\\"%s\\"", name, program, name);
        }
        else
        {
        	sprintf(param, "delete \\"%s\\"", name);
        }
        
        sei.lpParameters = param;
        
        if (!ShellExecuteEx(&sei))
        {
        	show\_error();
        }
        

        }

        L 1 Reply Last reply
        0
        • R Rick R 2023

          Just found out somethhing more.... As soon as I invoke the service creation function from within the program, I do get the normal service controll manager asking for elevated rights in order to create the service, what is exactly what happen. But then the service gets created with start type set to "manual". If I do start the program manually "as Administrator" and then invoke the service creation function, the service gets created correctly with start type "auto". So there probably might be a problem with my elevation of rights!?... will check this. Strange though, that it works fin under any Windows version since XP... just not windows 11... Here is the code to start with elevated rights:

          BOOL IsRunAsAdministrator()
          {
          BOOL isRunAsAdmin = FALSE;
          DWORD dwError = ERROR_SUCCESS;
          PSID pAdministratorsGroup = NULL;

          // Allocate and initialize a SID of the administrators group.
          SID\_IDENTIFIER\_AUTHORITY NtAuthority = SECURITY\_NT\_AUTHORITY;
          if (!AllocateAndInitializeSid(
              &NtAuthority, 
              2, 
              SECURITY\_BUILTIN\_DOMAIN\_RID, 
              DOMAIN\_ALIAS\_RID\_ADMINS, 
              0, 0, 0, 0, 0, 0, 
              &pAdministratorsGroup))
          {
              goto Cleanup;
          }
          
          // Determine whether the SID of administrators group is enabled in 
          // the primary access token of the process.
          if (!CheckTokenMembership(NULL, pAdministratorsGroup, &isRunAsAdmin))
          {
              goto Cleanup;
          }
          

          Cleanup:
          // Centralized cleanup for all allocated resources.
          if (pAdministratorsGroup)
          {
          FreeSid(pAdministratorsGroup);
          pAdministratorsGroup = NULL;
          }

          return isRunAsAdmin;
          

          }

          void RunServiceAsAdmin(char ch, const char *program, const char* name)
          {
          // Launch itself as admin
          char param[255];
          SHELLEXECUTEINFO sei = { sizeof(sei) };

          memset(param, 0 , sizeof(param));
          sei.lpVerb = "runas";
          sei.lpFile = "sc.exe";
          sei.hwnd = NULL;
          sei.nShow = SW\_NORMAL;
          
          if(ch == 'I')
          {
          	sprintf(param, "create \\"%s\\" binPath= \\"%s\\" DisplayName=\\"%s\\"", name, program, name);
          }
          else
          {
          	sprintf(param, "delete \\"%s\\"", name);
          }
          
          sei.lpParameters = param;
          
          if (!ShellExecuteEx(&sei))
          {
          	show\_error();
          }
          

          }

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Well, You appear to have a function that is checking if you are running as Administrator. Could you show me the content of that function?

          R 1 Reply Last reply
          0
          • L Lost User

            Well, You appear to have a function that is checking if you are running as Administrator. Could you show me the content of that function?

            R Offline
            R Offline
            Rick R 2023
            wrote on last edited by
            #5

            Here is some more complete code:

            BOOL IsRunAsAdministrator()
            {
            BOOL isRunAsAdmin = FALSE;
            DWORD dwError = ERROR_SUCCESS;
            PSID pAdministratorsGroup = NULL;

            // Allocate and initialize a SID of the administrators group.
            SID\_IDENTIFIER\_AUTHORITY NtAuthority = SECURITY\_NT\_AUTHORITY;
            if (!AllocateAndInitializeSid(
                &NtAuthority, 
                2, 
                SECURITY\_BUILTIN\_DOMAIN\_RID, 
                DOMAIN\_ALIAS\_RID\_ADMINS, 
                0, 0, 0, 0, 0, 0, 
                &pAdministratorsGroup))
            {
                goto Cleanup;
            }
            
            // Determine whether the SID of administrators group is enabled in 
            // the primary access token of the process.
            if (!CheckTokenMembership(NULL, pAdministratorsGroup, &isRunAsAdmin))
            {
                goto Cleanup;
            }
            

            Cleanup:
            // Centralized cleanup for all allocated resources.
            if (pAdministratorsGroup)
            {
            FreeSid(pAdministratorsGroup);
            pAdministratorsGroup = NULL;
            }

            return isRunAsAdmin;
            

            }

            void RunServiceAsAdmin(char ch, const char *program, const char* name)
            {
            // Launch itself as admin
            char param[255];
            SHELLEXECUTEINFO sei = { sizeof(sei) };

            memset(param, 0 , sizeof(param));
            sei.lpVerb = "runas";
            sei.lpFile = "sc.exe";
            sei.hwnd = NULL;
            sei.nShow = SW\_NORMAL;
            
            if(ch == 'I')
            {
            	sprintf(param, "create \\"%s\\" binPath= \\"%s\\" DisplayName=\\"%s\\"", name, program, name);
            }
            else
            {
            	sprintf(param, "delete \\"%s\\"", name);
            }
            
            sei.lpParameters = param;
            
            if (!ShellExecuteEx(&sei))
            {
            	show\_error();
            }
            

            }

            static int manage_service(int action) {
            SC_HANDLE hSCM = NULL, hService = NULL;
            SERVICE_DESCRIPTION descr = { server_name };
            char path[PATH_MAX + 20]; // Path to executable plus magic argument
            int success = 1;

            GetModuleFileName(NULL, path, sizeof(path));
            strncat(path, " ", sizeof(path));
            strncat(path, service\_magic\_argument, sizeof(path));
            
            if (IsRunAsAdministrator()) {
            	if ((hSCM = OpenSCManager(NULL, NULL, action == ID\_INSTALL\_SERVICE ?
            		GENERIC\_WRITE : GENERIC\_READ)) == NULL) {
            		success = 0;
            		show\_error();
            	}
            	else if (action == ID\_INSTALL\_SERVICE) {
            		hService = CreateService(hSCM, service\_name, service\_name,
            			SERVICE\_ALL\_ACCESS, SERVICE\_WIN32\_OWN\_PROCESS,
            			SERVICE\_AUTO\_START, SERVICE\_ERROR\_NORMAL,
            			path, NULL, NULL, NULL, NULL, NULL);
            		if (hService) {
            			ChangeServiceConfig(hService, SERVICE\_NO\_CHANGE, SERVICE\_AUTO\_START,
            				SERVICE\_NO\_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
            			ChangeServic
            
            L 1 Reply Last reply
            0
            • R Rick R 2023

              Here is some more complete code:

              BOOL IsRunAsAdministrator()
              {
              BOOL isRunAsAdmin = FALSE;
              DWORD dwError = ERROR_SUCCESS;
              PSID pAdministratorsGroup = NULL;

              // Allocate and initialize a SID of the administrators group.
              SID\_IDENTIFIER\_AUTHORITY NtAuthority = SECURITY\_NT\_AUTHORITY;
              if (!AllocateAndInitializeSid(
                  &NtAuthority, 
                  2, 
                  SECURITY\_BUILTIN\_DOMAIN\_RID, 
                  DOMAIN\_ALIAS\_RID\_ADMINS, 
                  0, 0, 0, 0, 0, 0, 
                  &pAdministratorsGroup))
              {
                  goto Cleanup;
              }
              
              // Determine whether the SID of administrators group is enabled in 
              // the primary access token of the process.
              if (!CheckTokenMembership(NULL, pAdministratorsGroup, &isRunAsAdmin))
              {
                  goto Cleanup;
              }
              

              Cleanup:
              // Centralized cleanup for all allocated resources.
              if (pAdministratorsGroup)
              {
              FreeSid(pAdministratorsGroup);
              pAdministratorsGroup = NULL;
              }

              return isRunAsAdmin;
              

              }

              void RunServiceAsAdmin(char ch, const char *program, const char* name)
              {
              // Launch itself as admin
              char param[255];
              SHELLEXECUTEINFO sei = { sizeof(sei) };

              memset(param, 0 , sizeof(param));
              sei.lpVerb = "runas";
              sei.lpFile = "sc.exe";
              sei.hwnd = NULL;
              sei.nShow = SW\_NORMAL;
              
              if(ch == 'I')
              {
              	sprintf(param, "create \\"%s\\" binPath= \\"%s\\" DisplayName=\\"%s\\"", name, program, name);
              }
              else
              {
              	sprintf(param, "delete \\"%s\\"", name);
              }
              
              sei.lpParameters = param;
              
              if (!ShellExecuteEx(&sei))
              {
              	show\_error();
              }
              

              }

              static int manage_service(int action) {
              SC_HANDLE hSCM = NULL, hService = NULL;
              SERVICE_DESCRIPTION descr = { server_name };
              char path[PATH_MAX + 20]; // Path to executable plus magic argument
              int success = 1;

              GetModuleFileName(NULL, path, sizeof(path));
              strncat(path, " ", sizeof(path));
              strncat(path, service\_magic\_argument, sizeof(path));
              
              if (IsRunAsAdministrator()) {
              	if ((hSCM = OpenSCManager(NULL, NULL, action == ID\_INSTALL\_SERVICE ?
              		GENERIC\_WRITE : GENERIC\_READ)) == NULL) {
              		success = 0;
              		show\_error();
              	}
              	else if (action == ID\_INSTALL\_SERVICE) {
              		hService = CreateService(hSCM, service\_name, service\_name,
              			SERVICE\_ALL\_ACCESS, SERVICE\_WIN32\_OWN\_PROCESS,
              			SERVICE\_AUTO\_START, SERVICE\_ERROR\_NORMAL,
              			path, NULL, NULL, NULL, NULL, NULL);
              		if (hService) {
              			ChangeServiceConfig(hService, SERVICE\_NO\_CHANGE, SERVICE\_AUTO\_START,
              				SERVICE\_NO\_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
              			ChangeServic
              
              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              I do see a bug.

              SHELLEXECUTEINFO sei = { sizeof(sei) };

              You should zero that struct out. Then set the cbSize member. Not sure if this is causing your problem though. I'm on my TV right now so reviewing on my couch. But don't see any other issues.

              R 1 Reply Last reply
              0
              • L Lost User

                I do see a bug.

                SHELLEXECUTEINFO sei = { sizeof(sei) };

                You should zero that struct out. Then set the cbSize member. Not sure if this is causing your problem though. I'm on my TV right now so reviewing on my couch. But don't see any other issues.

                R Offline
                R Offline
                Rick R 2023
                wrote on last edited by
                #7

                Thanks for the tip! :) Am also currently looking into a way to use the ControlService utility via CreateProcess to install the service, instead of calling CreateService directly... But not sure if I can pull that off correctly...

                L 1 Reply Last reply
                0
                • R Rick R 2023

                  Thanks for the tip! :) Am also currently looking into a way to use the ControlService utility via CreateProcess to install the service, instead of calling CreateService directly... But not sure if I can pull that off correctly...

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  I just noticed in your original post:

                  Rick R. 2023 wrote:

                  Am using VS2022 using toolset 1.41_XP

                  Do you get the same behavior if you compile for Windows 11?

                  R 1 Reply Last reply
                  0
                  • L Lost User

                    I just noticed in your original post:

                    Rick R. 2023 wrote:

                    Am using VS2022 using toolset 1.41_XP

                    Do you get the same behavior if you compile for Windows 11?

                    R Offline
                    R Offline
                    Rick R 2023
                    wrote on last edited by
                    #9

                    Starting to suspect the toolset, too. Have to fix a bunch of linker problems caused by my old and pretty messy project settings, in order to test with a newer version... might take a while.

                    L 1 Reply Last reply
                    0
                    • R Rick R 2023

                      Starting to suspect the toolset, too. Have to fix a bunch of linker problems caused by my old and pretty messy project settings, in order to test with a newer version... might take a while.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Well, Alot of members check the forums everyday. Sometimes it just helps to have a few other eyes look at the issue.

                      Rick R. 2023 wrote:

                      Have to fix a bunch of linker problems

                      XP to Win11 is a big jump, I can imagine. :laugh:

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups