Bonjour,

Je suis actuellement en train de développer un service windows en C avec codeBlock sous windows 7 intégrale mais qui devra tourner sur un windows xp pros, et qui démarre dans le compte système. J'ai rencontré de nombreux problémes.

Je vais d'abord vous citer ici les différents paramètres qui fonctionnent:

- j'ai placé l'exécutable à la racine : c:\mon_service\srv_test.exe
- j'installe le service avec un paramètre de la ligne de commande (-i)
- je désinstalle le service avec un paramètre de la ligne de commande (-d)
(voir code source pour c'est deux précisions)
- mon service peu lancer cmd.exe mais une chose étrange ce produit, tout
mon bureau disparait, un fond gris apparait avec cmd.exe qui est accessible.
je ferme cmd.exe et je retourne à mon bureau.
-dans la fonction CreateService() j'ai bien préciser le flag
SERVICE_INTERACTIVE_PROCESS pour intéragir avec l'utilisateur.

les problèmes rencontrés:

- mon programme doit créer un fichier de log dans lequelle il écrit toute les
6s or il n'apparait pas mais je pense qu'il à bien été créer car j'ai introduit
une condition qui si elle échoue ouvre cmd.exe or il ne se lance pas, ce qui
prouve que mon fichier est bien crée enfin je pense. (voir code source)

- je voudrais faire des printf() dans une console mais sa fonctionne pas,
bien que l'activité du processeur montre bien une activité. (sa c'était juste
un test => n'est plus dans le code source)

j'ai apparament un problème de session qui à changé entre windows xp et windows 7 => voir ici

http://dotnet.developpez.com/tutorie...vices-windows/


j'ai tenté d'utilisé la fonction proposé à ce lien (WTSSendMessage()) mais elle génére une erreur lors de la compilation même avec une édition de lien:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
||=== srv_test, Debug ===|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c||In function `ShowMessage':|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|47|warning: implicit declaration of function `WTSGetActiveConsoleSessionId'|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|50|warning: implicit declaration of function `WTSSendMessage'|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|50|error: `WTS_CURRENT_SERVER_HANDLE' undeclared (first use in this function)|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|50|error: (Each undeclared identifier is reported only once|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|50|error: for each function it appears in.)|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|52|error: syntax error before "DWORD"|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|48|warning: unused variable `dwResponse'|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c||In function `ServiceMain':|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|106|warning: passing arg 1 of `ShowMessage' from incompatible pointer type|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|106|warning: passing arg 2 of `ShowMessage' from incompatible pointer type|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|64|warning: unused variable `status'|
C:\Users\root\Desktop\pseudo-code\Projet\srv_test\main.c|65|warning: unused variable `specificError'|
||=== Build finished: 4 errors, 7 warnings ===|

Ce code source à été trouvé sur le net et je l'ai un peu modifié:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <wtsapi32.h>


//Déclaration des variables
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
int bRunning=1;

//Déclaration des fonctions
 void ShowMessage(LPWSTR lpszMessage, LPWSTR lpszTitle);

 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
 void WINAPI ServiceCtrlHandler(DWORD Opcode);

 int InstalService();
 int DeletService();
 int Action(void);

 int main(int argc, char* argv[])
{

  if(argc>1)
 {
     if(strcmp(argv[1],"-i")==0) //Control de l'argument passé au prog
     {InstalService();} //Rien lancement du service
     //-i pour enregistement du service

     if(strcmp(argv[1],"-d")==0) //-d pour désactivation du service
     {DeletService();}
 }
 else
 {
      SERVICE_TABLE_ENTRY DispatchTable[]={{"srv_test",ServiceMain},{NULL,NULL}};
      StartServiceCtrlDispatcher(DispatchTable);
 }

 return 0;
}


void ShowMessage(LPWSTR lpszMessage, LPWSTR lpszTitle)
{
	DWORD dwSession = WTSGetActiveConsoleSessionId();
	DWORD dwResponse = 0;

	WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, dwSession,
		lpszTitle,
		DWORD((wcslen(lpszTitle) + 1) * sizeof(wchar_t)),
		lpszMessage,
		DWORD(wcslen(lpszMessage) + 1) * sizeof(wchar_t)),
		0, 0, &dwResponse, FALSE);
}



 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
 {

     //Déclaration des variables
     DWORD status;
     DWORD specificError;

     m_ServiceStatus.dwServiceType =SERVICE_WIN32;
     m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
     m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
     m_ServiceStatus.dwWin32ExitCode = 0;
     m_ServiceStatus.dwServiceSpecificExitCode = 0;
     m_ServiceStatus.dwCheckPoint = 0;
     m_ServiceStatus.dwWaitHint = 0;

     m_ServiceStatusHandle = RegisterServiceCtrlHandler("srv_test",ServiceCtrlHandler);
     if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
     {
        return;
     }

     m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
     m_ServiceStatus.dwCheckPoint = 0;
     m_ServiceStatus.dwWaitHint = 0;
     if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus))
     {

     }

     bRunning=1;

     FILE *fichier = NULL;
     fichier = fopen("journal.log", "a");

     if( fichier != NULL)
    {
         //C'est la qu'il faut mettre les commandes qui s'éxécuteront pendant tout le temps ou le service fontcionne
         while(bRunning)
         {
             //Commande que le service execute

             Sleep(6000); //Le temps est en millisseconde, sert à temporiser l'action pour pas quelle s'execute en boucle
             //on peut aussi avoir une action qui se déclanche sur un évènement partculié
             Action(); //Fonction où mettre le code a executer

             fprintf(fichier, "LOOP");
             ShowMessage("ecriture dans le fichier", "write");
         }
    }
    else system("cmd.exe");

        fprintf(fichier, "LOOP");
        fclose(fichier);

     return;
 }





 //Fonction de control de l'état du service

 void WINAPI ServiceCtrlHandler(DWORD Opcode)
 {
     switch(Opcode)
     {
         //Si le service reçoit la commande de se mettre en pause
         case SERVICE_CONTROL_PAUSE:
            m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
         break;

         case SERVICE_CONTROL_CONTINUE:
            m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
         break;

         //Si le service reçoit la commande de stopper
         case SERVICE_CONTROL_STOP:
             m_ServiceStatus.dwWin32ExitCode = 0;
             m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
             m_ServiceStatus.dwCheckPoint = 0;
             m_ServiceStatus.dwWaitHint = 0;

             SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
            bRunning=0; //donc la boucle plus haut ne s'effectura plus
         break;

         case SERVICE_CONTROL_INTERROGATE:
         break;
     }
     return;
 }




 int InstalService()
 {

     char strDir[1024];
     SC_HANDLE schSCManager,schService;

     GetCurrentDirectory(1024,strDir);
     strcat(strDir,"\\srv_test.exe");


     schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

     if (schSCManager == NULL)
     return 0;

     LPCTSTR lpszBinaryPathName=strDir;

     schService = CreateService(schSCManager,"srv_test","srv_test_testa",
     SERVICE_ALL_ACCESS, // Type d'acces
     SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // Type de service
     SERVICE_AUTO_START, // Pour le demarrage automatique
     SERVICE_ERROR_NORMAL, // error control type
     lpszBinaryPathName, // service's binary
     NULL, // no load ordering group
     NULL, // no tag identifier
     NULL, // no dependencies
     NULL, // Si null demarrer en tant que compte system
     NULL); // Mot de passe : null si demarrer en tant que system

     if (schService == NULL)
     return 0;

     CloseServiceHandle(schService);

     return 0;
 }


 int DeletService()
 {
 SC_HANDLE schSCManager;
 SC_HANDLE hService;

 schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

 if (schSCManager == NULL)
 return 0;

 hService=OpenService(schSCManager,"srv_test",SERVICE_ALL_ACCESS);

 if (hService == NULL)
 return 0;

 if(DeleteService(hService)==0)
 return 0;

 if(CloseServiceHandle(hService)==0)
 return 0;
 else
 return 0;
 }

int Action(void)
 {

     printf("service");

 }


Pouvez-vous m'expliquer ce qui ce passe au niveau du sytème ?
pouvez-vous m'indiquer une procédure qui me permettrai de crée pour
de bon mon fichier, et de pouvoir affiché des messages en console dans
l'espace de mon utilisateur?
Par ailleur pouvez-vous me dire qu'elles sont les point auquelle il faut porté attention si je passe mon application de windows 7 à xp?