2009-03-10 5 views
3

J'écris une fonction d'utilitaire win32 pour notre produit qui doit appeler un programme arbitraire via le shell et enregistrer sa sortie. Nous faisons cela en redirigeant la sortie standard du processus enfant dans un tuyau:Win32: Détermine si le handle stdout est char ou wchar stream

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

    CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0); 

    // Redirect the first process stdout to our write pipe 
    // so that we can read its output from the read pipe. 
    startUpInfo.dwFlags = STARTF_USESTDHANDLES; 
    startUpInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 
    startUpInfo.hStdOutput = hWritePipe; 
    startUpInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); 

    CreateProcessA(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo[i], &procInfo); 

Il existe une grande variété de programmes qui peuvent être appelés ainsi, dont beaucoup ne sont pas sous notre contrôle. Actuellement, nous voyons un problème où la sortie de nombreux programmes semble être tronquée après le premier caractère --- généralement un signe certain qu'une chaîne WCHAR est utilisée par erreur comme CHAR.

Comment puis-je savoir si le processus fils écrit dans son canal stdout en tant que CHAR ou WCHAR?

Répondre

3

En fin de compte, il n'y a pas de façon 100% fiable de le faire. Les poignées d'entrée/sortie d'un processus ne sont pas spécifiques à l'encodage. Ils fonctionnent simplement sur un flux d'octets. Il est tout à fait possible pour un processus d'écrire ASCII pendant un certain temps et de passer à Unicode plus tard.

Malheureusement, il n'est pas possible de dire à partir d'un flux d'octets avec une précision de 100% quel est le codage sous-jacent. La seule façon de déterminer cela est d'avoir un protocole de tremblement de la main où le processus vous indique quel encodage il utilisera. Probablement pas une option dans ce cas.

Liens sur le sujet

1

Je pense que vous devez négocier cela lorsque vous vous connectez. Vous pouvez utiliser PeekNamedPipe() et deviner en fonction de si elle ressemble à un caractère Unicode ...

Questions connexes