PsExec se bloquea mientras se ejecuta desde un programa gui c#o c++ muy simple compilado como "aplicación de Windows"
redirect hang (6)
Estoy experimentando un bloqueo de PsExec mientras se ejecuta desde un programa gui c # o c ++ muy simple compilado como "aplicación de Windows" (no como "aplicación de consola"). Debajo de la sección C) a continuación he pegado el código para reproducir el problema y en la sección D) He pegado el código c ++ para reproducir el mismo problema.
Cuando el psexec se cuelga, la salida del viento después de ser unida a psexec localmente se pega debajo de la sección B).
Mi programa se bloquea después de descargar la salida pegada en la sección A).
El programa funciona bien si reemplaza el comando psexec con cualquier elemento local p. Ej. ProcessStartInfo ("cmd.exe", "/ c dir c: / windows / *. *");
Me preguntaba si alguien lo experimentó y encontró la solución para ello. La ayuda será muy apreciada.
Gracias, Sharrajesh
A) Mi salida del programa c # cuando se cuelga psexec
PsExec v1.98 - Ejecuta procesos de forma remota Copyright (C) 2001-2010 Mark Russinovich Sysinternals - www.sysinternals.com
El volumen en la unidad C no tiene etiqueta.
B) Salida de Windbg para psexec mientras se cuelga
3 Id: 1614.15e4 Suspender: 1 Teb: 7efac000 Sin congelar ChildEBP RetAddr Args al niño
02a3fe68 75a6d0c5 00000180 00000000 00000000 ntdll! NtReadFile + 0x15 (FPO: [9,0,0]) 02a3fecc 75cb18aa 00000180 02a3ff44 00010000 KERNELBASE! ReadFile + 0x118 (FPO: [SEH]) 02a3ff14 00403bde 00000180 02a3ff44 00010000 kernel32! ReadFileImplementation + 0xf0 (FPO : [SEH]) ADVERTENCIA: la información de desenrollado de la pila no está disponible. Seguir algunas estructuras puede ser malo. 02a3ff2c 00000000 00291e48 00000000 02a5ff80 psexec + 0x3bde
C) El código c # para reproducir el problema
using System;
using System.Windows.Forms;
using System.Diagnostics;
namespace WindowsFormsApplication1 {
static class Program {
static void DataReceiveHandler(object sender, DataReceivedEventArgs e) {
Debug.WriteLine(e.Data);
}
public static void NotWorkingPsExec() {
ProcessStartInfo startInfo = new ProcessStartInfo("psexec.exe",
"////raj-2k3-32 cmd.exe /c dir c://windows//*.*");
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
Process proc = new Process();
proc.StartInfo = startInfo;
proc.ErrorDataReceived += new DataReceivedEventHandler(DataReceiveHandler);
proc.OutputDataReceived += new DataReceivedEventHandler(DataReceiveHandler);
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
Debug.WriteLine("Exit code = {0}", proc.ExitCode);
}
public static void WorkingPsExec() {
ProcessStartInfo startInfo = new ProcessStartInfo("psexec.exe",
"////raj-2k3-32 cmd.exe /c dir c://windows//*.*");
startInfo.UseShellExecute = false;
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
proc.WaitForExit();
Debug.WriteLine("Exit code = {0}", proc.ExitCode);
}
static void Main() {
NotWorkingPsExec();
//WorkingPsExec(); //If uncommented will work
}
}
}
D) El código de C ++ para reproducir el problema
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
HANDLE g_hStdoutRd = NULL;
HANDLE g_hStdoutWr = NULL;
void StartCommand(TCHAR *szCmdline);
void ReadOutput();
void ErrorExit(PTSTR);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&g_hStdoutRd, &g_hStdoutWr, &saAttr, 0))
ErrorExit(TEXT("Stdout SetHandleInformation"));
if (!SetHandleInformation(g_hStdoutRd, HANDLE_FLAG_INHERIT, 0))
ErrorExit(TEXT("Stdout SetHandleInformation"));
TCHAR szCmdline[] = TEXT("psexec.exe ////raj-2k3-32 cmd.exe /c dir /s c://windows//*.*"); // Not Working
//TCHAR szCmdline[] = TEXT("cmd.exe /c dir /s c://windows//*.*"); // Working
StartCommand(szCmdline);
ReadOutput();
return 0;
}
void StartCommand(TCHAR *szCmdline) {
PROCESS_INFORMATION piProcInfo = {0};
STARTUPINFO siStartInfo = {0};
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hStdoutWr;
siStartInfo.hStdOutput = g_hStdoutWr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
BOOL bSuccess = CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);
if (!bSuccess)
ErrorExit(TEXT("CreateProcess"));
else {
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
}
void ReadOutput() {
if (!CloseHandle(g_hStdoutWr))
ErrorExit(TEXT("StdOutWr CloseHandle"));
for (;; ) {
CHAR chBuf[4096] = {0};
DWORD dwRead;
BOOLEAN bSuccess = ReadFile(g_hStdoutRd, chBuf, ARRAYSIZE(chBuf), &dwRead, NULL);
if (!bSuccess || dwRead == 0)
break;
OutputDebugStringA(chBuf);
}
}
void ErrorExit(PTSTR lpszFunction) {
OutputDebugString(lpszFunction);
ExitProcess(1);
}
Establezca también la propiedad WorkingDirectory en startInfo, ya que las utilidades Sysinternals usan el desempaquetado de archivos en tiempo de ejecución y el kernel no puede encontrar el archivo ejecutable desempaquetado (real).
La lectura sincrónica en la transmisión funciona:
ProcessStartInfo startInfo = new ProcessStartInfo("psexec.exe", @"//localhost cmd.exe /c dir c:/windows/*.*");
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
//startInfo.RedirectStandardError = true;
//startInfo.RedirectStandardInput = true;
Process proc = new Process();
proc.StartInfo = startInfo;
//proc.ErrorDataReceived += new DataReceivedEventHandler(DataReceiveHandler);
//proc.OutputDataReceived += new DataReceivedEventHandler(DataReceiveHandler);
proc.Start();
//proc.BeginErrorReadLine();
//proc.BeginOutputReadLine();
string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
Console.WriteLine(output);
Console.WriteLine("Exit code = {0}", proc.ExitCode);
Incluso aquí, tenga en cuenta que ReadToEnd () debe hacerse antes de WaitForExit ().
Creo que PSExec siempre tuvo problemas como este. Cuando se ejecuta bajo el servicio Java, solíamos redirigir la salida a nul y no podíamos obtener el resultado del proceso en ejecución, pero podíamos obtener el resultado de PSExec.
Consulte las discusiones a continuación dadas:
http://forum.sysinternals.com/psexec-always-hangs-when-run-from-java_topic5013.html
http://forum.sysinternals.com/unusual-problem-with-psexecexe_topic6655.html
Editar:
Nota sobre la limpieza de PSEXESVC: elimine el archivo PSEXESVC.EXE en C: / Windows (o C: / Windows / system32 o ambos) después de eliminar el proceso colgado de PSEXESVC. El proceso / archivo persistente causa más problemas.
Tuve un problema similar debido a la eula, que puede ser tuya:
Posibles razones:
1) psiexec.exe muestra el mensaje EULA durante la primera ejecución.
2) Permisos
3) la función dll puede requerir la sesión del usuario.
Para evitar estos problemas, intente seguir los siguientes escenarios:
1) con el argumento "-accepteula"
2) con el argumento "-s"
3) con el argumento "-i"
4)> 2 + 3 5) 2 + 3 + 1
Ver: http://www.appdeploy.com/messageboards/tm.asp?m=72376&mpage=1&key=𑪸
Aunque había verificado el EULA varias veces
PSExec estaba colgando para mí también al azar. No me he esforzado en recrear el tema a su manera, pero he evitado mis problemas usando "PAExec", un sucesor aparentemente digno en espíritu: http://www.poweradmin.com/PAExec/
Cree una aplicación de consola genérica que ejecute PsExec
& PsKill
y todos sus amigos. Llame a esta aplicación ConsoleApp a través de su código en lugar de llamar al método NotWorkingPsExec
, y funcionará perfectamente.
Tengo una solución simple para esto,
C # ejecuta el proceso como:
Process.Start("start run.bat xx.txt"); //call it async //and then we make some code juse wait xx.txt appear and finish written .
run.bat
es:psexec.bat > %1 //redirect to a text file exit
psexec.bat
es:psexec.exe .......................... exit