5 Nisan 2018 Perşembe

Process Sınıfı

Giriş
Bu sınıfı kullanmak için şu satır dahil edilir.
using System.Diagnostics.Process
BeginErrorReadLine metodu
Şöyle yaparız.
proc.BeginErrorReadLine();
BeginOutputReadLine metodu
Şöyle yaparız.
proc.BeginOutputReadLine();
CancelErrorRead metodu
Şöyle yaparız.
proc.CancelErrorRead();
CancelOutputRead metodu
Şöyle yaparız.
proc.CancelOutputRead();
Close metodu
Şöyle yaparız.
Process proc = new Process();
...
proc.Start();
proc.WaitForExit();
proc.Close();
EnableRaisingEvents Alanı
Bu bayrak atanırsa Process'e ait event'ler alınabilir. Eventl'leri bağlamadan önce şöyle yaparız.
process = Process.Start("notepad.exe");
process.EnableRaisingEvents = true;
process.Exited += Program_Exited;
Exited Event'i
Şöyle yaparız.
process.Exited += Program_Exited;

void Program_Exited(object sender, System.EventArgs e)
{
  ...
}
GetCurrentProcess metodu
Şöyle kullanırız.
using (var curProcess = Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule)
{...}
GetProcessesByName metodu
Çağrı bir dizi döner.
Process[] p = Process.GetProcessesByName("...");
Dizinin uzunluğu bize aradığımız uygulamanın var olup olmadığını belirtir.
if (Process.GetProcessesByName("GameCapture").Length == 0) {...}
Örnek
Remote Desktop'taki bir uygulamayı şöyle buluruz.
Process[] p = Process.GetProcessesByName("taskmgr", "machine-name-here");
Örnek
Eğer ismini bildiğimiz bir uygulama ise şöyle kapatırız.
string filename = "mylist.xls";
var excelProcesses = Process.GetProcessesByName("excel");

foreach (var process in excelProcesses)
{
  if (process.MainWindowTitle == $"Microsoft Excel - {filename}")
  {
     process.Kill();
  }
}
Örnek
Bir uygulamananın çalışıp çalışmadığını anlamak için şöyle yaparız.
bool isRunning = false;
string processToCheck = ...;
Process[] pname = Process.GetProcessesByName(processToCheck);
if (pname.Length == 0)
{
  isProcessRunning = false;
}
else
{
  isProcessRunning = true;
}
Handle Alanı
Şöyle yaparız.
unsafe
{
  Process process = ...;
  IntPtr Handle = process.Handle;
  ...
}
Id Alanı
WMI ile kullanmak için şöyle yaparız.
string GetParentProcessName() 
{
  var myId = Process.GetCurrentProcess().Id;
  var query = string.Format("SELECT ParentProcessId FROM Win32_Process
                             WHERE ProcessId = {0}", myId);
  var search = new ManagementObjectSearcher("root\\CIMV2", query);
  var queryObj = search.Get().OfType<ManagementBaseObject>().FirstOrDefault();
  if (queryObj == null)
  {
    return null;
  }
  var parentId = (uint)queryObj["ParentProcessId"];
  var parent = Process.GetProcessById((int)parentId);
  return parent.ProcessName;
}
Diğer uygulamanın belleğine erişmek için şöyle yaparız.

const int PROCESS_WM_READ = 0x0010;

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(...);

Process process = Process.GetProcessesByName("notepad")[0]; 
IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id); 
Kill metodu
Uygulamayı öldürür. Bunun yerine taskkill de kullanılabilir.
Process.Start("CMD.exe","taskkill /FI "WindowTitle eq Microsoft Excel");
veya
Process.Start("CMD.exe","taskkill /f /im excel.exe");
MainModule Alanı
Uygulamanın binary dosyasının nerede olduğu şöyle bulunur.
Process[] localByName = Process.GetProcessesByName("notepad");

foreach (Process p in localByName)
{
    string path  =  p.MainModule.FileName.ToString();
}
Çıktı olarak şunu alırız.
C:\WINDOWS\system32\NOTEPAD.EXE

Unsafe olarak şöyle kullanılır.
unsafe
{
  Process process = ...;
  IntPtr pBaseAddress = (IntPtr)process.MainModule.BaseAddress.ToInt32();
  ...
}
MainWindowHandle Alanı
Eğer Process nesnesi console veya servis değilse bir MainWindow'u bulunur.
Process process = ...;
if (process.MainWindowHandle != IntPtr.Zero)
{...}
Win32'de bir pencereyi başlatmak için şu yapı doldurulur.
typedef struct tagWNDCLASS {
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
} WNDCLASS, *PWNDCLASS;
Yapı şöyle doldurulur.
WNDCLASS wc;
wc.style = CS_BYTEALIGNWINDOW | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = "MYCLASS";
Process başlatıldıktan hemen sonra MainWindowHandle dolu gelmeyebilir. Bazen bir müddet beklemek gerekiyor.
Stopwatch sw = new Stopwatch();
sw.Start();
int timeout = 10 * 1000;     // Timeout value (10s) 
Process p = Process.Start(...);
IntPtr Handle = p.MainWindowHandle;

while (Handle == IntPtr.Zero)
{
  System.Threading.Thread.Sleep(10);
  p.Refresh();

  if (sw.ElapsedMilliseconds > timeout)
  {
    sw.Stop();
    return;
  }
}
Beklemek için döngü içinde dönmek yerine şöyle de yapabiliriz.
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

private void button1_Click(object sender, EventArgs e)
{
  Process proc = Process.Start("calc.exe");
  proc.WaitForInputIdle();
  Thread.Sleep(500);
  SetParent(proc.MainWindowHandle, this.Handle);
}
MainWindowTitle Alanı
Şöyle yaparız.
Process proc = ...;
string title = proc.MainWindowTitle.ToLower();
if (title.Contains("...")) {...}
OutputDataReceived Event'i
Şöyle yaparız.
process.OutputDataReceived+=process_OutputDataReceived;
process.ErrorDataReceived+=process_ErrorDataReceived;
process.Exited+=process_Exited;
process.EnableRaisingEvents=true;
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();

await process.StandardInput.WriteLineAsync( @"tree d:\sqlite" );
Handler metodu şöyledir.
void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
  string data = e.Data;
}
PriorityClass Alanı
Şöyle yaparız.
Process p = Process.GetCurrentProcess();
p.PriorityClass = ProcessPriorityClass.High;
ProcessName Alanı
Şöyle yaparız.
Process proc = ...;
string name = proc.ProcessName.ToLower();if (name.Contains("...")) {...}
Refresh metodu
Sanırım MainWindowHandle gibi bazı özellikleri tekrar okumaya yarıyor.
Process p = Process.Start(...);
p.Refresh();
StandardOutput Alanı
Şöyle yaparız.
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = @"c:\windows\system32\cmd.exe";
p.StartInfo.Arguments = "/c dir c:\*.iso /s /b";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Start metodu
C# ile uygulama başlatmak için Process sınıfını kullanıyoruz.

1. Yeni bir ProcessStartInfo sınıfı oluşturup Process.Start() ile başlatabiliriz.
ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\MyApplication.exe");
Process.Start(startInfo);
ProcessStartInfo sınıfının bir sürü özelliği var.

2. Dosya İsmi
Bu durumda belirtilen dosya için varsayılan uygulama kullanılıyor.
Örnek
Şöyle yaparız.
Process.Start("http://google.com");
Örnek
Şöyle yaparız.
public static void OpenBrowser(string url)
{
  try
  {
    Process.Start(url);
  }
  catch
  {
    // hack because of this: https://github.com/dotnet/corefx/issues/10361
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
      url = url.Replace("&", "^&");
      Process.Start(new ProcessStartInfo("cmd", $"/c start {url}")
        { CreateNoWindow = true });
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
      Process.Start("xdg-open", url);
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
    {
      Process.Start("open", url);
    }
    else
    {
      throw;
    }
  }
}
3. Uygulama İsmi ve Dosya
Process.Start metodu - Uygulama İsmi yazısına taşıdım.

WaitForExit metodu
Şöyle yaparız.
var startInfo = new ProcessStartInfo { CreateNoWindow = true, 
UseShellExecute = false, FileName = "tnsping", Arguments = "localhost:1521" };
var process = Process.Start(startInfo);
process.WaitForExit();
WaitForInputIdle metodu
Uygulamanın tamamen yüklenip yüklenmediğini belirtir. Şöyle yaparız.
process.WaitForInputIdle();

1 yorum: