Changing the affinity of a Console C# program - c#

In this page, the following code is an example for changing the affinity of the current process:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process myProcess = Process.GetCurrentProcess();
Console.WriteLine("ProcessorAffinity: {0}", myProcess.ProcessorAffinity);
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)3;
Console.WriteLine("ProcessorAffinity: {0} ", myProcess.ProcessorAffinity);
Console.ReadKey();
}
}
But the output for me is:
ProcessorAffinity: 255
ProcessorAffinity: 255
meaning that the affinity is not changed. What's the problem? And how can I change the affinity?

As #ChetanRanpariya mension in his comment, the issue is because you changeing ProcessorAffinity of one process object (returned from the second call of Process.GetCurrentProcess()) and checking it in another (returned from the first call of Process.GetCurrentProcess()). Here is corrected sample:
using (var currentProcess = Process.GetCurrentProcess())
{
Console.WriteLine($"ProcessorAffinity: {currentProcess.ProcessorAffinity}");
currentProcess.ProcessorAffinity = (System.IntPtr)3;
Console.WriteLine($"ProcessorAffinity: {currentProcess.ProcessorAffinity}");
}

Related

How do I limit the number of cores used for a process?

I want my program to open some other processes, and one of the requirements of the project is that each process opened can only be run on a single core.
I know that a specific processor can be picked with processorAffinity but is it possible to set a maximum number of cores (in my case 1)?
you have to try with ProcessThread.ProcessorAffinity
using System;
using System.Diagnostics;
namespace ProcessThreadIdealProcessor
{
class Program
{
static void Main(string[] args)
{
// Make sure there is an instance of notepad running.
Process[] notepads = Process.GetProcessesByName("notepad");
if (notepads.Length == 0)
Process.Start("notepad");
ProcessThreadCollection threads;
//Process[] notepads;
// Retrieve the Notepad processes.
notepads = Process.GetProcessesByName("Notepad");
// Get the ProcessThread collection for the first instance
threads = notepads[0].Threads;
// Set the properties on the first ProcessThread in the collection
threads[0].IdealProcessor = 0;
threads[0].ProcessorAffinity = (IntPtr)1;
}
}
}

Set string value from clipboard contents C#

I'm writing a small app that should display the number of characters in the current string from the clipboard. So for example, someone highlights a line of text and hits copy, then runs my app. I want it to display the number of characters in the string. Should be simple, but I keep getting Zero returned. There are related threads but none answer my question. Here is what I have so far (Its a console app btw.):
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BuildandRun
{
class Program
{
static void Main(string[] args)
{
string data = Clipboard.GetText();
Console.WriteLine(data);
int dataLength = data.Length;
Console.WriteLine(dataLength + " Characters.");
Console.ReadLine();
}
}
}
From MSDN:
The Clipboard class can only be used in threads set to single thread
apartment (STA) mode. To use this class, ensure that your Main method
is marked with the STAThreadAttribute attribute.
Just change your code to:
[STAThreadAttribute]
static void Main( string[] args )
The Clipboard only works for Single Threaded Apartment threads.
Therefore the answer is to add the following to Main():
[STAThread]
static void Main(string[] args)
{
...
Or workaround like this:
public string GetClipboardText()
{
string result = "";
Thread thread = new Thread(() => result = Clipboard.GetText());
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
return result;
}

Why thread is stopped when start new process, while application (c#) is still running?

Is there any problem which i have to do carefully when starting new process in multiple thread application?
I tried this in a simple project:
static void Main(string[] args)
{
Process.Start(#"D:\System\Desktop\a.txt");
MessageBox.Show("Success");
}
And it runs perfectly. But when i do it in my big project which use multiple thread, it's thread is stopped working ("a.txt" is opened but "Success" is not shown) while my application (other thread) do well.
What is the problem in this situation?
If you have a Windows.Forms application and you try to show a message-box from a thread that is not the main user-interface thread, the behavior of the message-box is undefined. Meaning, it may or may not show, be inconsistent, or some other problem.
For instance, displaying a message-box from the BackgroundWorker's DoWork event may or may not work. In one case, the message-box-result was always cancel regardless of what button was clicked.
Therefore, if you are using a message-box just for debugging purposes, use a different technique. If you have to show a message-box, call it from the main user-interface thread.
A console-application should normally not have problems displaying message-boxes. Yet, I have had cases where I would have to sleep the thread for 100ms before the message-box call.
Note, as TomTom pointed out, the main user-interface thread is the application's Windows message loop. Which reminds me, I once had to create a Form in a Console application in order to create a Windows message loop, so my application could respond to Windows messages.
This isn't the answer - I can't put all this code in a comment...
This works for me. Tell me how your code differs from this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;
namespace Test
{
class Program
{
const string OutputFile = #"E:\Output.txt";
object _lock = new object();
static void Main(string[] args)
{
Program program = new Program();
Thread thread = new Thread(program.ThreadMethod);
thread.Start(#"E:\Test.txt");
thread = new Thread(program.ThreadMethod);
thread.Start(#"E:\DoesntExist.txt");
Console.ReadKey();
}
void ThreadMethod(object filename)
{
String result = RunNormal(filename as string);
lock (_lock)
{
FileInfo fi = new FileInfo(OutputFile);
if (!fi.Exists)
{
try
{
fi.Create().Close();
}
catch (System.Security.SecurityException secEx)
{
Console.WriteLine("An exception has occured: {0}", secEx.Message);
return;
}
}
StreamWriter sw = fi.AppendText();
sw.WriteLine(result);
sw.Close();
}
}
string RunNormal(string fullfilename)
{
try
{
Process.Start(fullfilename);
return fullfilename + "|Success";
}
catch (Exception e)
{
return fullfilename + "|" + e.ToString();
}
}
}
}
The output in Output.txt is:
E:\DoesntExist.txt|System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(String fileName)
at Test.Program.RunNormal(String fullfilename) in E:\Projekti\VS2010\Test\Test\Program.cs:line 59
E:\Test.txt|Success
How much different is your code? Do you call some other methods? How do you process the results?
Make sure Process.Start works. Passing a filename is not good enough in some cases. In you sample code, you would have to set the use-shell property; otherwise, you would have to use cmd start <filename> or equivalent.
Therefore, just start NotePad.exe to make sure Process.Start works. If it does then your problem is the process command and command line.

Killing A Process in C#

So I'm just trying to explore the intricacies of C# and I wanted to make a simple program that would just kill a process. Yes I know, that is what Task Manager is for but this is supposed to be a learning experience, this is what I have so far.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace endProcess
{
class Program
{
private Process GetaProcess(string processname)
{
Process[] aProc = Process.GetProcessesByName(processname);
if (aProc.Length > 0)
return aProc[0];
else return null;
}
string selectProcess = "";
static void Main(string[] args)
{
Console.WriteLine("What process do you want to kill?");
selectProcess = Console.ReadLine();
Process myprc = Call GetAProcess(selectProcess);
myprc.Kill();
Console.ReadLine();
}
}
}
The issue comes where I made the comment. It says there should be a semicolon after GetAProcess and I have no idea why. Any help would be much appreciated.
You don't say Call GetaProcess you simply say GetaProcess
The line should look like this : Process myprc = GetaProcess(selectProcess);

How to terminate child processes when a c# console application is aborted?

I have a console application that spawns other win32 processes using WMI ManagementClass.I have a requirement when a user kills the console application through proc explorer or by pressing ctrl+c ,the application should terminate all the child processes it created.What is the best way to achive this?
Keeping in mind that you have to take in your needs into account, you can do it like the sample below.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace KillSpawnedProcesses
{
class Program
{
static List<int> _processes = new List<int>();
static void Main(string[] args)
{
Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
StartProcesses();
Console.Read(); //to hold up console
Console.Read(); //to hold up console
}
static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
KillProcesses();
}
static void StartProcesses()
{
for(int i = 0; i < 2; i++)
{
Process p = new Process();
p.StartInfo = new ProcessStartInfo();
p.StartInfo.FileName = "Notepad.exe";
p.Start();
_processes.Add(p.Id);
}
}
static void KillProcesses()
{
foreach(var p in _processes)
{
Process tempProcess = Process.GetProcessById(p);
tempProcess.Kill();
}
}
}
}
If the sub-process has a message queue (Win32 message pumping), you can post WM_CLOSE to its main window, or define your own message. Otherwise, you can design your inter-process notification by using Sockets, Pipes, or Synchronization objects like Events.
The worst way is to kill the sub-processes.

Categories