I was planning to write the specific implementation of the jobs module in this article. But when I look back, it seems that I still forget an important problem, that is, when deploying and uninstalling Windows service, I have introduced two different commands: SC and installutil. Why do we not need to create projectinstaller internally when using SC? When Using installutil, we must create projectinstaller, I checked some materials with questions and finally found some clues. Please give me some advice on the shortcomings.
I thought SC was the underlying command line, and installutil was created by calling the SC command. Unfortunately, I made a relatively low-level error and everything should come from Windows API, either SC or installutil.
Let's take a look at installutil. The msdn explanation is:
InstallProgramTool allows you to install and uninstall server resources by executing the installer components in the specified assembly ,. This tool works with classes in the system. configuration. Install namespace.
Installutil.exe uses reflection to check the specified assembly and finds that runinstallerattribute is setTrueAll installer types. Then the toolInstallerRun the install or uninstall Method on each instance of the type. Installutil.exe is installed in a transactional manner. If one assembly fails to be installed, installutil.exe rolls back the installation of all other assembly. Unmount is not transactional.
In this way, installutil should be the serviceinstaller1 and serviceprocessinstaller1 in the projectinstaller we added in Windows Service. The latter two are the installer for the final deployment and uninstallation of Windows service, so what is the relationship between serviceinstaller1 and serviceprocessinstaller1 ??
I used reflect to check the source code of the Two. My current conclusion is that serviceprocessinstaller1 mainly stores some account-related information and checks the account permissions during the install operation; however, serviceinstaller1 is used to store service-related information, such as the service name, service description, startup mode, and so on. It also creates a service during the install process;
Serviceinstaller1 does the following during install:
- Logmessage: record the install log
- Checkenvironment: Check the installation environment. Check whether the OS version of the system is consistent with that of the service environment.
- Find out whether the Sub-installer of the parent-level Installer (parent attribute) and the sub-installer of the parent-level installer has serviceprocessinstaller, and assign the found serviceprocessinstaller to the parent attribute of the serviceinstaller, copy the account information in serviceprocessinstaller.
- Prepare relevant parameters for calling windows32 API to create a service and calling createservice API to create a service
- Configure the service and log the service properly.
- Execute install () of the parent class ()
When serviceinstaller1 is not installed (the log and other unimportant steps are omitted below ):
- Run the uninstall () command of the parent class first ()
- Open service management intptr using openscmanager API
- Use openservice API to find the corresponding service
- Use deleteservice API to delete the services found
- Disable Service Management intptr
- Use the servicecontroller class to check whether the service still exists. If so, try to stop the service. (Why do I need to perform this further check and stop the deleteservice API ?? Instead of throw exception)
So far, the install and uninstall processes of serviceinstaller1 have been completed, and the core of the installutil service deployment is clear. In the uninstallperiod, installutil.exe may be used to uninstall the service. It is estimated that there are two possible causes:
1: installutil.exe is not executed by a transaction during Uninstall.
2: In the above uninstall step 6th;
But what is the reason? I am still stuck on the above two points of speculation,I don't know which one can explain it !??
SC is relatively simple. The following explanation is from msdn:
Create a service remotely and start the service from the command line. You can use the resource kit to include the SC tool (SC .exe ).
Use SC .exe to help develop Windows Services. SC .exe, which is used to call all the control application programming interfaces (APIS) functions of Windows Services.
This shows that SC directly calls the Windows API to install, uninstall, query, and perform a series of operations and control.
In this case, we can generalize the nature of SC .exeand installutil.exe on Windows service operations.
Next, I will give a rough introduction to how to call Windows API to operate the service and servicecontrol.
Servicecontrol is A. Net class used to control Windows Services, such as stop (), start (), pause (), and refresh;
You can call a Windows API to control the name, description, status, Startup type, and running account of a Windows Service, including the following APIs:
Code
[Dllimport ( " Advapi32.dll " , Charset = Charset. Unicode, setlasterror = True )]
Public Static Extern Intptr createservice (intptr databasehandle, String Servicename, String Displayname, Int Access, Int Servicetype, Int Starttype, Int Errorcontrol, String Binarypath, String Loadordergroup, intptr ptagid, String Dependencies, String Servicesstartname, String Password );
[Dllimport ( " Advapi32.dll " , Charset = Charset. Unicode, setlasterror = True )]
Public Static Extern Intptr openscmanager ( String Machinename, String Databasename, Int Access );
[Dllimport ( " Advapi32.dll " , Charset = Charset. Unicode, setlasterror = True )]
Public Static Extern Intptr openservice (intptr databasehandle, String Servicename, Int Access );
[Dllimport ( " Advapi32.dll " , Charset = Charset. Unicode, setlasterror = True )]
Public Static Extern Bool Deleteservice (intptr servicehandle );
[Reliabilitycontract (consistency. willnotcorruptstate, Cer. Success), dllimport ( " Advapi32.dll " , Charset = Charset. Unicode, setlasterror = True )]
Public Static Extern Bool Closeservicehandle (intptr handle );
[Dllimport ( " Advapi32.dll " , Charset = Charset. Unicode, setlasterror = True )]
Public Static Extern Bool Changeserviceconfig2 (intptr servicehandle, Uint Infolevel, Ref Service_description servicedesc );
In the Service API, each service instance is represented by a handle, and the SCM handle must be obtained before the Service handle is required. Therefore, all calls start through openscmanager, after a successful call to openscmanager, an SCM handle is obtained. If a service is registered, the SCM handle is used to call createservice to create a new service. If a service is deleted, the openservice method is called, obtain an existing service handle, use this handle to call deleteservice to delete the service, and finally call closeservicehandle to close the Service handle and SCM handle. Changeserviceconfig2 is mainly used to set the description of the service.
In this way, we can use APIs to implement a class that controls Windows Service behaviors (including creating, deregistering, stopping, starting, and so on ).
Of course, if we use the serviceInstaller and serviceprocessinstaller create and delete services and use servicecontrol to manage services.
The class that uses APIs to control Windows Service behaviors.CodePost it!