~ocsinventory-dev/ocsinventory-deploy-tool/trunk

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
//====================================================================================
// Open Computer and Software Inventory Next Generation
// Copyright (C) 2010 OCS Inventory NG Team. All rights reserved.
// Web: http://www.ocsinventory-ng.org

// This code is open source and may be copied and modified as long as the source
// code is always made freely available.
// Please refer to the General Public Licence V2 http://www.gnu.org/ or Licence.txt
//====================================================================================

// ExecCommand.h: interface for the CExecCommand class.
//
// This class is inspired from CMake (Cross-Platform Makefile Generator)
// cmWin32ProcessExecution class, but is updated to be Unicode compliant
//////////////////////////////////////////////////////////////////////

#pragma once

// Command execution function result
#define EXEC_SUCCESSFULL			0	// Excute success
#define EXEC_ERROR_START_COMMAND	1	// Failed to launch command
#define EXEC_ERROR_WAIT_COMMAND		2	// Failed to wait command termination or to get exit code
// Time to wait in ms between each check for alive process
#define EXEC_WAIT_CHECK_LATENCY		1000	

class CExecCommand
{
public:
	CExecCommand();
	~CExecCommand();

  /**
   Set process execution timeout, in milliseconds
   By default, wait is INFINITE
   */
  void setTimeout( DWORD dwTimeout = INFINITE);

  /**
   Use COMSPEC environnement variable to start process (e.g cmd.exe /C command) 
   or not (Does not allow searching in path for command => must provide full path
   for command)
   */
   void useComspec( BOOL bUse = TRUE);

  /**
   * Exec command in the directory path. Make sure that the
   * executable is either in the path or specify the full path.
   * We don't care about command ending, so stdout and stderr
   * will not be grabbed, and we will not try to get process
   * exit code
   * Return EXEC_SUCCESSFULL if all successfull
   *        EXEC_ERROR_START_COMMAND if start command error
   */
  int execNoWait(LPCTSTR lpstrCommand, LPCTSTR lpstrPath);

  /**
   * Exec command in the directory path. Make sure that the
   * executable is either in the path or specify the full path.
   * We will try to get process exit code (use getExitCode() to retreive it).
   * If bCapture is TRUE, stdout and stderr will be grabbed (use getOutput() 
   * to retreive it)
   * We will wait until command end (but if command starts other
   * processes/threads, we will not be able to wait for those ending)
   * Return EXEC_SUCCESSFULL if all successfull
   *        EXEC_ERROR_START_COMMAND if start command error
   *        EXEC_ERROR_WAIT_COMMAND if wait or get exit code/ouput error,
   */
  int execWait( LPCTSTR lpstrCommand, LPCTSTR lpstrPath, BOOL bCapture = TRUE);

  /**
   * Exec command in the directory path. Make sure that the
   * executable is either in the path or specify the full path.
   * Wait for command AND ALL others threads/processes it may launch to finish.
   * In this case, we try get exit code, but NOT stdout and stderr
   * Return EXEC_SUCCESSFULL if all successfull
   *        EXEC_ERROR_START_COMMAND if start command error
   *        EXEC_ERROR_WAIT_COMMAND if wait error,
   */
  int execWaitForAllChilds( LPCTSTR lpstrCommand, LPCTSTR lpstrPath);

  /**
   * Get the output of the command (mixed stdout and stderr)
   * In case of error, contains error description
   */
  LPCSTR getOutput();

  /**
   * Get the return value of the process. If the process is still
   * running, the return value is -1.
   */
  int getExitValue();


protected:
  /**
   * Initialize the process execution datastructure. Do not call while
   * running the process.
   */
  void initialize();
  /**
   * Start the process in the directory path. Make sure that the
   * executable is either in the path or specify the full path.
   * Use already opened handles to redirecting stdin/stdout/stderr
   * if capture used
   * Return 0 if error or PID of created process
   */
  DWORD realCreateProcess(LPCTSTR lpstrCommand, LPCTSTR lpstrPath, BOOL bCapture = FALSE);
  /**
   * Prepare handle to capture stdin, stdout and stderr, start the process and
   * and prepare for waiting end of process to get exit code
   */
  BOOL startProcessCapture(LPCTSTR lpstrCommand, LPCTSTR lpstrPath);
  /**
   * Wait for process to finish and get exit code 
   * Ends grabbing stdout and stderr if asked
   */
  BOOL wait( BOOL bCapture = FALSE);
  /**
   * Close all used handles of needed
   */
  BOOL closeHandles();

  /**
   * Search in memory all processes listed in pProcesses array
   * or any new child process of an already listed process
   * Also remove for array non existing process
   */
  BOOL parseRunningProcesses( CObArray *pProcessList);
  BOOL isProcessListed( CObArray *pProcessList, DWORD dwProcessID);
  BOOL freeProcessList( CObArray *pProcessList);

protected:
  HANDLE m_hProcessHandle;
  HANDLE m_hChildStdinRd;
  HANDLE m_hChildStdinWr;
  HANDLE m_hChildStdoutRd;
  HANDLE m_hChildStdoutWr;
  HANDLE m_hChildStdinWrDup;
  HANDLE m_hChildStdoutRdDup;
  DWORD  m_dwTimeout;
  BOOL	 m_bComspec;
  
  int m_nExitValue;
  int m_fdStdOut;

  CStringA m_csOutput;
};