Bonjour tout le monde,
Je cherche a écrire un mini débogueur d'application .Net.
Pour ceux qui ne le savent pas, globalement, ca se passe via une API qui offre des objets permettant l'interaction avec le CLR (ICLRMetaHost, ICLRRuntimeInfo, ICorDebug, etc..., tous héritant de IUnknown).
Et justement, l'objet ICorDebug offre une méthode "CreateProcess" permettant de lancer un exécutable sous l'égide du débogueur.
Mon problème c'est que tout ca n'est pas super bien documenté (il manque certaines valeurs d'énumération par exemple, ou des codes erreurs) et j'ai justement une erreur qui ne semble pas être documentée.

Voila un bout de code pour être plus clair :
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
wchar_t exefile[]; // Contient le chemin absolut vers l'exécutable .Net à déboguer
ICLRMetaHost*		_MetaHost = 0;
ICLRDebugging*		_Debugging = 0;
ICorDebug*			_CorDebug = 0;
ICorDebugProcess*	_CorProcess = 0;
 
// Obtient un CLMetaHost
HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (void**)&_MetaHost); // OK
if(hr) throw std::exception("Echec de l'obtention de l'interface de meta-données.");
 
// Obtient un CLRDebugging
hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging, (void**)&_Debugging); // OK
if(hr) throw std::exception("Echec de l'obtention de l'interface de débogage.");
 
wchar_t CLRVersion[MAX_PATH]; // MAX_PATH pour prendre large, rien de lié aux chemins
DWORD bufLength = MAX_PATH;
_MetaHost->GetVersionFromFile(exefile, CLRVersion, &bufLength); // Ok, CLRVersion = "v4.0.30319", l'exécutable a déboguer est bien en .Net 4,
//j'ai testé avec un exe en .Net 2 et la fonction retourne bien "v2.[...]"
 
// Obtient le runtime associé
ICLRRuntimeInfo* _RuntimeInfo = 0;
HRESULT hr = _MetaHost->GetRuntime(CLRVersion, IID_ICLRRuntimeInfo, (void**)&_RuntimeInfo); // OK
if(hr) throw std::exception("Echec de l'obtention de l'interface ICLRRuntimeInfo.");
 
// Obtient l'interface de débogage pour le runtime spécifié
hr = _RuntimeInfo->GetInterface(CLSID_CLRDebuggingLegacy, IID_ICorDebug, (void**)&_CorDebug); // OK
 
// Maintenant que l'interface de débogage est obtenue, le ICLRRuntimeInfo n'est plus requis
_RuntimeInfo->Release(); // J'ai tenté en commentant cette ligne, sans changement.
 
STARTUPINFO startupinfo;
PROCESS_INFORMATION processinfo;
memset(&startupinfo, 0, sizeof(STARTUPINFO));
startupinfo.cb = sizeof(STARTUPINFO);
memset(&processinfo, 0, sizeof(PROCESS_INFORMATION));
 
// J'ai tenté toutes les combinaisons entre ApplicationName et CommandLine, aucun changement
HRESULT hr = _CorDebug->CreateProcess
	(
		0, // ApplicationName
		exefile, //CommandLine
		0, //ProcessAttributes
		0, // ThreadAttribute
		FALSE, // InheritHandles
		CREATE_NEW_CONSOLE,
		0, // Environment
		0, // CurrentDirectory
		&startupinfo,
		&processinfo,
		DEBUG_NO_SPECIAL_OPTIONS,
		&_CorProcess
	); // une HRException est lancée au sein de cette fonction
 
if(hr) // E_FAIL
{
	DWORD err = GetLastError(); // err = 0 ?!?!?!
	return STOPPED;
}
Si j'active l'arrêt sur toutes les exceptions (même catchées) je vois qu'il y a une HRException lancée sur la méthode CreateProcess, mais je n'ai pas plus d'info (genre un message d'erreur, comme ca se passe en interne de la fonction je ne sais pas comment je peux inspecter l'exception en question pour faire un .what() dessus ou un truc du genre).

Cependant, cette exeption semble être catchée puisque si je met un try/catch autour je ne passe pas dans le catch.
le résultat de la fonction est E_FAIL, effectivement _CorProcess est toujours NULL.
Mais le GetLastError() returne 0 (ERROR_SUCCESS), autrement dit, il n'y a pas d'erreur

Pour couronner le tout, si je conserve exactement les mêmes paramètres pour appeler la fonction CreateProcess (la vrai de base issue de windows.h), ca passe sans aucun problème.

Une idée de où ca pourrait venir ?

Merci du coup de main