2010-07-17 5 views
1

J'essaie d'ajouter un solveur Sokoban (écrit en C++) à mon programme en C# (j'ai une classe dans mon programme qui gère la gestion de l'interface C++). Mon programme charge la bibliothèque solver.dll qui charge solver.exe. Solver.dll et Solver.exe communiquent via des tuyaux. Le problème est que lorsque j'exécute mon programme dans Visual Studio (débogage) la DLL est bien chargée et les fonctions du plugin fonctionnent très bien. Mais quand j'ouvre mon programme en dehors de Visual Studio (double-cliquez simplement sur MyProgram.exe) et quand j'essaye d'exécuter la fonction de résolution le message d'erreur: "Got Invalid Pipe" et "Échec de créer le tuyau." apparaître.CreatePipe et les autorisations nécessaires en C#

Je suis tout à fait à la perte ce qui pourrait être le problème mais je suppose qu'il y a un problème avec certaines autorisations.

Voici deux parties de code de l'auteur du plugin:

Dans le fichier solver.dll:

//create pipes 
SECURITY_ATTRIBUTES attr; 
attr.nLength=sizeof(attr); 
attr.lpSecurityDescriptor=NULL; 
attr.bInheritHandle=TRUE; 
if(!CreatePipe(&hPipeOutRead,&hPipeOutWrite,&attr,0) 
     ||!CreatePipe(&hPipeInRead,&hPipeInWrite,&attr,0)) 
{ 
     ReportError("Failed to create pipe."); 
     return SOKOBAN_PLUGIN_RESULT_FAILURE; 
} 

//set std handle for deliver pipe 
HANDLE hStdInSave, hStdOutSave; 
hStdInSave=GetStdHandle(STD_INPUT_HANDLE); 
hStdOutSave=GetStdHandle(STD_OUTPUT_HANDLE); 
if(hStdInSave==INVALID_HANDLE_VALUE || hStdOutSave==INVALID_HANDLE_VALUE) 
{ 
     ReportError("Failed to get std handles."); 
     return SOKOBAN_PLUGIN_RESULT_FAILURE; 
} 
if(!SetStdHandle(STD_INPUT_HANDLE,hPipeOutRead) 
     ||!SetStdHandle(STD_OUTPUT_HANDLE,hPipeInWrite)) 
{ 
     ReportError("Failed to redirect std handles."); 
     return SOKOBAN_PLUGIN_RESULT_FAILURE; 
} 

//create BoxSearch Process 
STARTUPINFO startInfo; 
ZeroMemory(&startInfo,sizeof(startInfo)); 
startInfo.cb=sizeof(startInfo); 

PROCESS_INFORMATION processInfo; 
ZeroMemory(&processInfo,sizeof(processInfo)); 

char dllDir[MAX_PATH]; 
char exeName[MAX_PATH+100]; 
GetModuleFileName(ghinstDLL,dllDir,MAX_PATH); 
*(strrchr(dllDir,'\\')+1)=0; 
strcpy(exeName,dllDir); 
strcat(exeName,"Solver.exe"); 

char cmdLine[MAX_PATH+100]; 
strcpy(cmdLine,"\""); 
strcat(cmdLine,exeName); 
strcat(cmdLine,"\""); 
strcat(cmdLine," "); 
strcat(cmdLine,API_DLLCommandLine); 

BOOL launchSuccess=CreateProcess(exeName,cmdLine,NULL,NULL,TRUE,0,NULL,dllDir,&startInfo,&processInfo); 

A côté de Solver.exe:

//get pipes 
hPipeRead=GetStdHandle(STD_INPUT_HANDLE), 
hPipeWrite=GetStdHandle(STD_OUTPUT_HANDLE); 
if(0==hPipeRead || INVALID_HANDLE_VALUE==hPipeRead 
     ||0==hPipeWrite|| INVALID_HANDLE_VALUE==hPipeWrite) 
{ 
     FormattedMessageBox("Got invalid pipe."); 
     return; 
} 

Ce qui pourrait être le problème? Y a-t-il des permissions liées à la DLL chargée (pour les pipes)?

Merci!

Répondre

2

Yuck, c'est fugement. Cela ne peut fonctionner que si MyProgram.exe est une application en mode console. Requis pour obtenir une redirection d'entrée/sortie. Cela fonctionne probablement dans le débogueur à cause du processus d'hébergement Visual Studio. P/Appeler AllocConsole dans votre programme résoudrait le problème. Je suppose que vous ne vous souciez pas particulièrement de cette fenêtre de console, vous devrez réécrire cette interface. Utiliser des tuyaux nommés le résoudrait. De manière réaliste, cela n'a aucun sens d'exécuter le solveur en tant que processus séparé. Jetez un oeil à C++/CLI pour aller de l'avant.

+0

Merci pour votre réponse! Je ne suis pas l'auteur du plugin et je ne peux pas le changer de quelque façon que ce soit. MyProgram.exe est malheureusement l'application WPF. Y a-t-il un moyen de le réparer? http://www.pinvoke.net/default.aspx/kernel32.allocconsole - J'ai compris que AllocConsole ne peut pas être utilisé dans WPF. –

+0

(Je n'ai plus de votes pour aujourd'hui, je vais vous mettre demain dessus) –

Questions connexes