Я пытаюсь написать приложение, которое будет порождать дочерний процесс под другим родительским процессом, а также мне нужно получить его выходные данные.
В основном это будет в проводнике .exe того же пользовательского контекста, что не должно вызывать каких-либо проблем с безопасностью Windows. Я пытаюсь заставить это работать для Windows 7 и более поздних версий, а также пытаюсь заставить это работать от имени обычного пользователя, а не администратора.
У меня возникла проблема: что не похоже, что он порождает дочерний элемент под новым родителем. Если я создаю его в процессе работы приложения, оно работает нормально, не знаю, что я делаю не так.
Я просмотрел текст, и, похоже, это не помогает.< /p>
var results = LaunchProcess.CreateProcess("cmd.exe", "/c " + command, "explorer");
Но когда я наблюдаю за процессами с помощью Process Explorer, я не вижу, чтобы он создавал новый процесс. Есть ли у кого-нибудь совет, как мне заставить это работать?
Я пытаюсь написать приложение, которое будет порождать дочерний процесс под другим родительским процессом, а также мне нужно получить его выходные данные. В основном это будет в проводнике .exe того же пользовательского контекста, что не должно вызывать каких-либо проблем с безопасностью Windows. Я пытаюсь заставить это работать для Windows 7 и более поздних версий, а также пытаюсь заставить это работать от имени обычного пользователя, а не администратора. У меня возникла проблема: что не похоже, что он порождает дочерний элемент под новым родителем. Если я создаю его в процессе работы приложения, оно работает нормально, не знаю, что я делаю не так. Я просмотрел текст, и, похоже, это не помогает.< /p> [code]using System.Runtime.InteropServices; using System; using NLog; using System.Diagnostics; using System.Threading; using System.Security.Permissions; using System.Security.AccessControl; using System.IO; using NPOI.SS.Formula.Functions; using Microsoft.Win32.SafeHandles;
[StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int nLength; public IntPtr lpSecurityDescriptor; [MarshalAs(UnmanagedType.Bool)] public bool bInheritHandle; }
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct STARTUPINFOEX { public STARTUPINFO StartupInfo; public IntPtr lpAttributeList; }
[StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; public int dwX; public int dwY; public int dwXSize; public int dwYSize; public int dwXCountChars; public int dwYCountChars; public int dwFillAttribute; public int dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; }
[StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; }
[StructLayout(LayoutKind.Sequential)] public struct SIZE_T { public UIntPtr _value; }
namespace LaunchProcess { public static class LaunchProcess { private static readonly Logger Log = LogManager.GetCurrentClassLogger();
const uint MAXIMUM_ALLOWED = 0x02000000; const int ProcessParentPid = 0x00000002; public const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000; public const int STARTF_USESTDHANDLES = 0x00000100; public const int STARTF_USESHOWWINDOW = 0x00000001; public const ushort SW_HIDE = 0x0000; public const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; public const uint CREATE_NO_WINDOW = 0x08000000; public const uint CreateSuspended = 0x00000004;
public static string CreateProcess(string processName, string command, string parentProcess = null) { Log.Trace($"Spawning {processName} with command {command}");
const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
// Create pipe for output capture IntPtr hReadPipe = IntPtr.Zero, hWritePipe = IntPtr.Zero; SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES(); securityAttributes.nLength = Marshal.SizeOf(securityAttributes); securityAttributes.bInheritHandle = true; CreatePipe(out hReadPipe, out hWritePipe, ref securityAttributes, 0); SafeFileHandle safeReadPipe = new SafeFileHandle(hReadPipe, ownsHandle: false); SetHandleInformation(hReadPipe, 1, 0); // Prevent inheritance of the read pipe
var pInfo = new PROCESS_INFORMATION(); var sInfoEx = new STARTUPINFOEX(); sInfoEx.StartupInfo.cb = Marshal.SizeOf(sInfoEx); sInfoEx.StartupInfo.hStdOutput = hWritePipe; sInfoEx.StartupInfo.dwFlags |= 0x00000100; // Set the STARTF_USESTDHANDLES flag IntPtr lpValue = IntPtr.Zero;
bool processCreated = false; // Flag to indicate if the process was created successfully string commandLine = $"{processName} {command}"; var lpApplicationName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
try { if (string.IsNullOrEmpty(parentProcess)) { Log.Trace($"Creating process with command: {commandLine}");
// Create the process //processCreated = CreateProcess(null, commandLine, ref pSec, ref tSec, false, EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, null, ref sInfoEx, out pInfo); processCreated = CreateProcess(null, commandLine, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref sInfoEx, out pInfo);
} else { int PPID = GetParentProcessId(parentProcess);
if (PPID != -1) { var lpSize = IntPtr.Zero; var success = InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
if (success || lpSize == IntPtr.Zero) { //Log.Error($"Failed to open parent process handle. Error: {Marshal.GetLastWin32Error()}"); return ""; }
var parentHandle = Process.GetProcessById(PPID).Handle; // This value should persist until the attribute list is destroyed using the DeleteProcThreadAttributeList function lpValue = Marshal.AllocHGlobal(IntPtr.Size); Marshal.WriteIntPtr(lpValue, parentHandle);
var pSec = new SECURITY_ATTRIBUTES(); var tSec = new SECURITY_ATTRIBUTES(); pSec.nLength = Marshal.SizeOf(pSec); tSec.nLength = Marshal.SizeOf(tSec); //var lpApplicationName = Path.Combine(Environment.SystemDirectory, "notepad.exe"); processCreated = CreateProcess(lpApplicationName, null, ref pSec, ref tSec, false, EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, null, ref sInfoEx, out pInfo); } }
// Check if process was created successfully if (!processCreated) { Log.Error($"CreateProcess failed. Error: {Marshal.GetLastWin32Error()}"); return ""; }
Log.Trace($"Created process with PID: {pInfo.dwProcessId}");
Process proc = Process.GetProcessById(pInfo.dwProcessId); proc.WaitForExit();
// Read process output using a StreamReader string output = "";
using (var outputStream = new FileStream(safeReadPipe, FileAccess.Read, 4096, false)) using (var reader = new StreamReader(outputStream)) { char[] buffer = new char[4096]; int read;
while ((read = reader.Read(buffer, 0, buffer.Length)) > 0) { output += new string(buffer, 0, read); } }
return output; // Return the captured output } finally { // Free the attribute list if (sInfoEx.lpAttributeList != IntPtr.Zero) { DeleteProcThreadAttributeList(sInfoEx.lpAttributeList); Marshal.FreeHGlobal(sInfoEx.lpAttributeList); } Marshal.FreeHGlobal(lpValue);
// Close process and thread handles if (pInfo.hProcess != IntPtr.Zero) { CloseHandle(pInfo.hProcess); }
if (pInfo.hThread != IntPtr.Zero) { CloseHandle(pInfo.hThread); }
if (hReadPipe != IntPtr.Zero) { CloseHandle(hReadPipe); }
if (hWritePipe != IntPtr.Zero) { CloseHandle(hWritePipe); } } }
private static int GetParentProcessId(string processName) { // Find the process by the specified name Process[] processes = Process.GetProcessesByName(processName);
if (processes.Length > 0) { Log.Trace($"Found {processName}.exe pid: {processes[0].Id}"); return processes[0].Id; } else { int currentProcessId = Process.GetCurrentProcess().Id; Log.Trace($"Failed to find {processName}.exe"); Log.Trace($"Using current process pid: {currentProcessId}"); return currentProcessId; } } } } [/code] И вот как я это называю: [code]var results = LaunchProcess.CreateProcess("cmd.exe", "/c " + command, "explorer"); [/code] Но когда я наблюдаю за процессами с помощью Process Explorer, я не вижу, чтобы он создавал новый процесс. Есть ли у кого-нибудь совет, как мне заставить это работать?
Я пытаюсь написать приложение, которое будет порождать дочерний процесс под другим родительским процессом, а также получать его выходные данные. В основном это будет файл explorer.exe того же пользовательского контекста, что не должно вызывать...
Если в php я могу создать что-то вроде родительского класса -> childCluss -> sbuChildClass в наследовании? Или у ребенка может быть только один родитель?
что-то вроде:
class base {
function connection();
}
class child extend base {
function...
Я хочу создать дочерний объект в конструкторе, чтобы иметь прямой доступ к дочернему классу в родительском классе без необходимости создания дочернего объекта отдельно.
Это всего лишь способ лучше структурировать код для меня.
Но я запускаю проблему...