/// <summary> /// System.Diagnostics.Process.BeginOutputReadLine の一文字毎版。 /// BeginOutputReadLine だと、行末に来るか、プログラムが終了するまで、次のデータが送られてこない。 /// 其処で、行末が来なくても読み取った側から文字列を通知する様に改造した。 /// </summary> public static mwg.IO.AsyncStringReader BeginOutputReadString(this Diag::Process process) { ProcessReflector proc = new ProcessReflector(process); switch (proc.outputStreamReadMode) { case SyncReadMode.MODE_UNDEF: proc.outputStreamReadMode = SyncReadMode.MODE_ASYNC; break; case SyncReadMode.MODE_SYNC: throw new System.InvalidOperationException("CantMixSyncAsyncOperation"); } if (proc.pendingOutputRead) { throw new System.InvalidOperationException("PendingAsyncOperation"); } proc.pendingOutputRead = true; System.IO.StreamReader standardOutput = proc.standardOutput; if (standardOutput == null) { throw new System.InvalidOperationException("CantGetStandardOut"); } mwg.IO.AsyncStringReader reader = new mwg.IO.AsyncStringReader( standardOutput.BaseStream, proc.OutputReadNotifyUser, standardOutput.CurrentEncoding ); reader.BeginRead(); return(reader); }
/// <summary> /// 指定したプロセスの指定した場所から、指定した長さのバイナリデータを読み取ります。 /// </summary> /// <param name="proc">プロセスを指定します。</param> /// <param name="addr">指定したプロセスのメモリ空間に於ける、読み込み元のアドレスを指定します。</param> /// <param name="data">読み取った値を返します。</param> /// <param name="size">読み取るデータの大きさをバイト単位で指定します。</param> /// <returns>読み取りが成功した場合に true を返します。それ以外の場合には false を返します。</returns> public static bool Read(Diag::Process proc, System.IntPtr addr, out byte[] data, int size) { data = new byte[size]; fixed(byte *pData = data) return(DReadMemoryArray(proc.Handle, addr, (void *)pData, size)); }
// ポインタ // ・Box 化不能 // ・型パラメータに指定出来ない (ポインタ配列は出来るのに…) // ・匿名メソッドの引数に出来ない /* そもそもポインタは Box 化出来ない… (System.IntPtr に変換して自動的にやってくれても良いのに) * [afh.Tester.TestMethod] * public unsafe static void testPointerBoxing(Log log){ * byte* alpha=(byte*)0x400000; * object o=alpha; * log.WriteLine("{0}",o is void*); * } * //*/ public unsafe static void chkEnumModules(Log log) { // Notepad.exe を取得 Diag::Process[] procs = Diag::Process.GetProcessesByName("notepad"); if (procs.Length == 0) { log.WriteLine("現在 notepad.exe は動いていません。"); return; } Diag::Process proc = procs[0]; for (int i = 1; i < procs.Length; i++) { procs[i].Close(); } log.WriteLine("プロセス notepad.exe を捕まえました"); log.WriteVar("Id", proc.Id.ToString("X8")); log.WriteVar("Handle", proc.Handle.ToString("X8")); // Modules log.WriteLine("Diag::Process.Modules より"); log.Lock(); log.AddIndent(); try{ foreach (Diag::ProcessModule mod in proc.Modules) { log.WriteVar("Module-Name", mod.ModuleName); log.WriteVar("Base-Address", mod.BaseAddress.ToString("X8")); log.WriteVar("Module-Size", mod.ModuleMemorySize.ToString("X8")); } }finally{ log.RemoveIndent(); log.Unlock(); } // Modules2 log.WriteLine("<DbgHelp>::EnumerateLoadedModules より"); log.Lock(); log.AddIndent(); try{ #pragma warning disable 618 DbgHelp.EnumerateLoadedModules(proc.Handle, delegate(string name, System.IntPtr modbase, uint modsize, System.IntPtr userData){ log.WriteVar("Module-Name", name); log.WriteVar("Base-Address", modbase.ToString("X8")); log.WriteVar("Module-Size", modsize.ToString("X8")); return(true); }, System.IntPtr.Zero); #pragma warning restore 618 }finally{ log.RemoveIndent(); log.Unlock(); } }
public static mwg.IO.AsyncStringReader BeginErrorReadString(this Diag::Process proc) { const int MODE_UNDEF = 0; //const int MODE_SYNC=1; const int MODE_ASYNC = 2; int errorStreamReadMode = (int)fProcess_errorStreamReadMode.GetValue(proc); if (errorStreamReadMode == MODE_UNDEF) { fProcess_errorStreamReadMode.SetValue(proc, MODE_ASYNC); } else if (errorStreamReadMode != MODE_ASYNC) { throw new System.InvalidOperationException("CantMixSyncAsyncOperation"); } if ((bool)fProcess_pendingErrorRead.GetValue(proc)) { throw new System.InvalidOperationException("PendingAsyncOperation"); } fProcess_pendingErrorRead.SetValue(proc, true); mwg.IO.AsyncStringReader reader; { System.IO.StreamReader standardError = (System.IO.StreamReader)fProcess_standardError.GetValue(proc); if (standardError == null) { throw new System.InvalidOperationException("CantGetStandardError"); } System.IO.Stream stream = standardError.BaseStream; System.Action <string> callback = (System.Action <string>)System.Delegate.CreateDelegate( typeof(System.Action <string>), proc, "ErrorReadNotifyUser"); reader = new mwg.IO.AsyncStringReader(stream, (System.Action <string>)callback, standardError.CurrentEncoding); } reader.BeginRead(); return(reader); }
static void test1() { Diag::Process bashProcess = new Diag::Process(); bashProcess.StartInfo.FileName = "C:\\usr\\cygwin\\bin\\bash.exe"; bashProcess.StartInfo.Arguments = "--login -i "; //?--login bashProcess.StartInfo.WorkingDirectory = "C:\\usr\\cygwin"; //bashProcess.StartInfo.EnvironmentVariables["CYGWIN"] = "tty"; bashProcess.StartInfo.RedirectStandardError = true; bashProcess.StartInfo.RedirectStandardInput = true; bashProcess.StartInfo.RedirectStandardOutput = true; bashProcess.StartInfo.CreateNoWindow = true; bashProcess.StartInfo.UseShellExecute = false; bashProcess.StartInfo.ErrorDialog = false; bashProcess.Start(); bashProcess.OutputDataReceived += (Diag::DataReceivedEventHandler)test1HandleStdout; bashProcess.ErrorDataReceived += (Diag::DataReceivedEventHandler)test1HandleStderr; //bashProcess.BeginErrorReadLine(); //bashProcess.BeginOutputReadLine(); bashProcess.BeginOutputReadString(); bashProcess.BeginErrorReadString(); System.ConsoleKeyInfo ki; while (!bashProcess.HasExited && (ki = System.Console.ReadKey(true)).Key != System.ConsoleKey.Escape) { bashProcess.StandardInput.Write(((char)ki.KeyChar).ToString()); } //int ch; //while(!bashProcess.HasExited&&(ch=System.Console.Read())>=0){ // bashProcess.StandardInput.Write(((char)ch).ToString()); //} }
public ProcessReflector(Diag::Process proc) { this.proc = proc; }
/// <summary> /// 指定したプロセスの指定した場所から 64bit 値を読み取ります。 /// </summary> /// <param name="proc">プロセスを指定します。</param> /// <param name="addr">指定したプロセスのメモリ空間に於ける、読み込み元のアドレスを指定します。</param> /// <param name="value">読み取った値を返します。</param> /// <returns>読み取りが成功した場合に true を返します。それ以外の場合には false を返します。</returns> public static bool Read(Diag::Process proc, System.IntPtr addr, out long value) { return(DReadMemory64(proc.Handle, addr, out value, 8)); }
/// <summary> /// 指定したプロセス内の全スレッドを再開します。 /// </summary> /// <param name="proc">再開の対象となるプロセスを指定します。</param> /// <returns>スレッドの再開が成功した場合に true を返します。それ以外の場合に false を返します。</returns> public static bool RestartProcessThreads(Diag::Process proc) { return(RestartProcessThreads(proc.ProcessName + ".exe")); }
// WriteMemoryS // DWriteMemoryS // GetHandle // ExePro /// <summary> /// 指定したプロセス内の全スレッドを停止します。 /// </summary> /// <param name="proc">停止の対象となるプロセスを指定します。</param> /// <returns>スレッドの停止が成功した場合に true を返します。それ以外の場合に false を返します。</returns> public static bool StopProcessThreads(Diag::Process proc) { return(StopProcessThreads(proc.ProcessName + ".exe")); }
/// <summary> /// 指定したプロセスの指定した場所に、十六進文字列で指定したバイナリデータを書き込みます。 /// </summary> /// <param name="proc">プロセスを指定します。</param> /// <param name="addr">値の書き込み先のアドレスを指定します。</param> /// <param name="hexValue"> /// 書き込むデータを十六進数で記述した文字列を指定します。 /// 変更を行わないバイトは "**" と指定することが可能です。 /// 例: "12**5678"→ 1byte 目に 0x12 と書かれ、3byte 目に 0x56、4byte 目に 0x78 と書かれます。 /// </param> /// <returns>書き込みが成功した場合に true を返します。それ以外の場合には false を返します。</returns> public static bool WriteHexStr(Diag::Process proc, System.IntPtr addr, string hexValue) { return(DWriteMemoryS(proc.Handle, addr, hexValue)); }
/// <summary> /// 指定したプロセスの指定した場所に バイナリデータを書き込みます。 /// </summary> /// <param name="proc">プロセスを指定します。</param> /// <param name="addr">値の書き込み先のアドレスを指定します。</param> /// <param name="data">書き込むデータを指定します。</param> /// <returns>書き込みが成功した場合に true を返します。それ以外の場合には false を返します。</returns> public static bool Write(Diag::Process proc, System.IntPtr addr, params byte[] data) { fixed(byte *pData = data) return(DWriteMemoryArray(proc.Handle, addr, (void *)pData, data.Length)); }
/// <summary> /// 指定したプロセスの指定した場所に 64bit 値を書き込みます。 /// </summary> /// <param name="proc">プロセスを指定します。</param> /// <param name="addr">値の書き込み先のアドレスを指定します。</param> /// <param name="value">書き込む値を指定します。</param> /// <returns>書き込みが成功した場合に true を返します。それ以外の場合には false を返します。</returns> public static bool Write(Diag::Process proc, System.IntPtr addr, long value) { return(DWriteMemory64(proc.Handle, addr, value, 8)); }