PsExec freezes when running from a simple C # or C ++ gui program compiled as an "application for Windows",

I am experiencing PsExec freezing when running from a simple C # or C ++ gui program compiled as a “Windows application” (not as a “console application”). Under section C) below. I pasted the code to reproduce the problem, and in section D) I pasted the C ++ code to reproduce the same problem.

When psexec freezes, windbg output after joining psexec is locally inserted in section B).

My program freezes after resetting the output inserted in section A).

The program works fine if you replace the psexec command with something local, for example. ProcessStartInfo ("cmd.exe", "/ c dir c: \ windows \ *. *");

I was wondering if anyone had experienced this and found a solution for it. Help would be greatly appreciated.

Thanks, Sharrajesh


A) My C # program output when psexec hangs

PsExec v1.98 - Run Processes Remotely Copyright (C) 2001-2010 Mark Russinovich Sysinternals - www.sysinternals.com

The volume on drive C has no label.


B) Windbg output for psexec during freeze

3 Id: 1614.15e4 Suspend: 1 Teb: 7efac000 Unfrozen ChildEBP RetAddr Args to Child

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]) WARNING: stack failure information is not available. The following frames may be incorrect. 02a3ff2c 00000000 00291e48 00000000 02a5ff80 psexec + 0x3bde


C) C # code to reproduce the problem

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) C ++ code to reproduce the problem

 #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 /sc:\\windows\\*.*"); // Not Working //TCHAR szCmdline[] = TEXT("cmd.exe /c dir /sc:\\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); } 
+6
source share
6 answers

PSExec was too random for me. I did not make efforts to recreate the problem in my own way, but I avoided my problems using PAExec, which seems to be a worthy successor in spirit: http://www.poweradmin.com/PAExec/

+5
source

I had a similar problem with eula, which could be yours:

Possible reasons:

1) psiexec.exe displays an EULA message during the first run.

2) Permissions

3) The dll function may require a user session.

To avoid these problems, try the following scripts:

1) with the argument "-septula"

2) with the argument -s "

3) with the argument -i "

4)> 2 + 3 5) 2 + 3 + 1

See: http://www.appdeploy.com/messageboards/tm.asp?m=72376&mpage=1&key=𑪸

Even if I checked EULA several times

+2
source

Also set the WorkDirectory property in startInfo, since Sysinternals utilities use file decompression at runtime, and the kernel cannot find the decompressed (real) exectutable file.

0
source

Create a common console application that runs PsExec and PsKill and all your friends. Call this ConsoleApp through your code instead of calling the NotWorkingPsExec method and it will work fine.

0
source

I have a simple solution for this,

  • C # do the process as follows:

     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 :

     psexec.bat > %1 //redirect to a text file exit 
  • psexec.bat :

     psexec.exe .......................... exit 
0
source

Synchronous reading in a stream works:

  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); 

Even here, note that ReadToEnd () should be executed before WaitForExit ().

I believe PSExec has always had such problems. When working under the Java service, we used output redirection to nul and could not get the result of the running process, but could get the output of PSExec itself.

See the discussion below:

http://forum.sysinternals.com/psexec-always-hangs-when-run-from-java_topic5013.html

http://forum.sysinternals.com/unusual-problem-with-psexecexe_topic6655.html

Edit:

Note on cleaning up PSEXESVC: delete the PSEXESVC.EXE file in C: \ Windows (or C: \ Windows \ system32 or both) after destroying the hacked PSEXESVC process. A protracted process / file causes more problems.

-1
source

Source: https://habr.com/ru/post/885851/


All Articles