CreatePipe и необходимые разрешения в C # - PullRequest
1 голос
/ 17 июля 2010

Я пытаюсь добавить решатель Sokoban (написанный на C ++) к моей программе на C # (в моей программе есть класс, который обрабатывает сортировку интерфейса C ++). Моя программа загружает библиотеку solver.dll, которая загружает solver.exe. Solver.dll и Solver.exe обмениваются данными по каналам.

Проблема в том, что когда я запускаю свою программу в Visual Studio (отладка), DLL загружается нормально, а функции плагина работают отлично. Но когда я открываю свою программу вне Visual Studio (простой двойной щелчок по MyProgram.exe) и когда я пытаюсь запустить функцию решения, появляется сообщение об ошибке: «Got Invalid Pipe» и «Failed to create pipe». появляются.

Я в растерянности, в чем может быть проблема, но я думаю, что есть проблема с некоторыми разрешениями.

Вот две части кода от автора плагина:

В файле 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);

На стороне 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;
 }

В чем может быть проблема? Есть ли какие-либо разрешения, связанные с загруженной DLL (для каналов)?

Спасибо!

1 Ответ

2 голосов
/ 17 июля 2010

Тьфу, это плохо.Это может работать только в том случае, если MyProgram.exe - приложение в консольном режиме.Требуется для работы перенаправления ввода / вывода.Возможно, он работает в отладчике из-за процесса размещения Visual Studio.

P / Invoking AllocConsole в вашей программе решит проблемуПолагаю, вам не особенно важно это окно консоли, вам придется переписать этот интерфейс.Использование именованных каналов решило бы это.Реально, не имеет смысла запускать решатель как отдельный процесс.Взгляните на C ++ / CLI, чтобы опередить.

...