c# if statement for macro - c#

i am trying to create a macro with jitbit macro recorder, what i need is if statement for shortcuts, like "ctrl+y", but software doesnt have if statement for shourtcuts. But there is Run "C# code" feature. I am trying to create a code for this. but failed so far.Can anyone help me?
Note: code must contain a class named Program with the static method Main.
Here is example code from the macro recorder;
public class Program
{
public static void Main()
{
System.Windows.Forms.MessageBox.Show("test");
}
}

Maybe this is what you are searching for:
class Program
{
static void Main(string[] args)
{
ConsoleKeyInfo keyinfo;
do
{
keyinfo = Console.ReadKey(true);
if (keyinfo.Modifiers == ConsoleModifiers.Control)
{
if (keyinfo.Key == ConsoleKey.Y)
{
// Do something
}
else if (keyinfo.Key == ConsoleKey.Z)
{
// Do something else
}
}
}
while (keyinfo.Key != ConsoleKey.X); // Ends the program if you press X
}
}

Related

C# Console.ReadLine creates new line with every keypress

I've encountered this weird issue that might be connected to my IDE or C# overrall.
Whenever I am inputting something in the console that is being read my Console.ReadLine(), it is being duplicated and shown below until I press return. I want to input a whole String for example, but what I see is reading char by char which kind of messes up debugging and presence of my program. I am attaching the code below along with the screenshot of the issue.
using System;
using System.Text.RegularExpressions;
namespace Zadanie_1
{
class Program
{
static void ShowMenu()
{
Console.WriteLine("Witaj w grze Siszarp!");
Console.WriteLine("[1] Zacznij nową grę");
Console.WriteLine("[X] Zamknij program");
}
static void PickOption(ConsoleKeyInfo keyPressed)
{
switch (keyPressed.KeyChar)
{
case '1':
Console.Clear();
Option1Picked();
break;
case 'X':
Environment.Exit(0);
break;
}
}
static bool IsCharacterNameValid(String characterName)
{
if (characterName.Length < 2)
{
Console.WriteLine("Niepoprawna nazwa!");
return false;
}
if (!Regex.IsMatch(characterName, #"^[a-zA-Z]+$"))
{
Console.WriteLine("Niepoprawna nazwa!");
return false;
}
return true;
}
static void EnterCharacterName()
{
String characterName;
do
{
Console.Write("Podaj nazwę bohatera:");
characterName = Console.ReadLine();
} while (!IsCharacterNameValid(characterName));
}
static void Option1Picked()
{
EnterCharacterName();
}
static void Main(string[] args)
{
ShowMenu();
ConsoleKeyInfo keyPressed = Console.ReadKey();
PickOption(keyPressed);
}
}
}

Do functions execute loops when called?

I'm trying to write a program that consists of some items (only 2 of them for now). It doesn't show any errors in the console, but when I try to call the Main function more than once, it doesn't execute the loops inside. Here's the code by the way.
public static class Program
{
public static string input = Convert.ToString(Console.ReadLine());
public static int health = 100;
public static int energy = 100;
public static void Main()
{
Console.WriteLine("This is a game used for testing items");
Console.WriteLine("Would you like to use items or get them? (Typing in status shows the value of your health and energy)");
if (Program.input == "get")
{
Items.GetItems();
}
if (Program.input == "use")
{
ItemUser();
}
if (Program.input == "status")
{
StatusChecker();
}
}
public static void StatusChecker()
{
Console.WriteLine("Your health is " + Program.health);
Console.WriteLine("Your energy is " + Program.energy);
}
public static void ItemUser()
{
Console.WriteLine("What do you want to use?");
string useChecker = Convert.ToString(Console.ReadLine());
if (useChecker == "healthPotion")
{
health += 100;
Items.healthPotion--;
}
if (useChecker == "energyDrink")
{
energy += 100;
Items.energyDrink--;
}
}
}
public static class Items
{
public static int healthPotion = 0;
public static int energyDrink = 0;
public static void GetItems()
{
Console.WriteLine();
string itemChecker = Convert.ToString(Console.ReadLine());
if ( itemChecker == "health potion")
{
healthPotion++;
Program.Main();
}
if (itemChecker == "energy drink")
{
energyDrink++;
Program.Main();
}
}
So I wanted the program to get the values after updating them, but it just stops after I call Main method more than once. Can anyone help me?
(I'm not that great at coding so I couldn't make really efficient code)
You don't have any loops inside your Main method and every time you run the application you start from scratch and each of your variables contain initial values. If I get right what you're trying to achieve, I would suggest you to write the Main method like this to have loop which will ask a user for a command until the user enters "quit":
static void Main(string[] args)
{
Console.WriteLine("This is a game used for testing items");
while (true)
{
Console.WriteLine("Would you like to use items or get them? (Typing in status shows the value of your health and energy)");
string userAnswer = Console.ReadLine();
if (userAnswer == "quit") break;
if (userAnswer == "get")
{
Items.GetItems();
}
if (userAnswer == "use")
{
ItemUser();
}
if (userAnswer == "status")
{
StatusChecker();
}
}
}
I noticed also that when you call ItemUser method you update static variables of your Items class, but in the StatusChecker method you write to the console variables of your Program class. They are actually different, so I think in your StatusChecker method you may want do the following:
public static void StatusChecker()
{
Console.WriteLine("Your health is " + Items.health);
Console.WriteLine("Your energy is " + Items.energy);
}
You are assigning a variable here:
public static string input = Convert.ToString(Console.ReadLine());
So the next time you call your "Main" method it will use the value you typed in the first time your app executed. If you want it to ask each time you'll need to do something like this:
public static void Main()
{
input = Convert.ToString(Console.ReadLine());
...
}
Another thing is that it can exit after the first call if you type in i.e. "status".
Issue number 3 is that this is not the "nice" way to write a program. The Main method is supposed to be executed when your app starts as it is the entry point (more on that here).

How to pass/check for specified arguments?

I'm currently writing a C# console application and would like to give the user the ability to chose what feature to be executed. For example, when I start MyApp.exe -help the help should show, or when I start MyApp.exe -shutdown the computer should shutdown. How do I pass/check that?
My current code doesn't seem to work:
static void Main(string[] args)
{
if (args.Equals("-help"))
{
Console.WriteLine("Some help here...");
}
}
static void Main(string[] args)
{
ProcesArguments(args);
}
static void ProcesArguments(string[] parameters)
{
foreach (var parameter in parameters)
{
switch (parameter.ToLower())
{
case "-help":
DisplayHelp();
break;
case "-reboot":
RebootComputer();
break;
}
}
}
static void DisplayHelp()
{
Console.WriteLine($"Syntax: {System.AppDomain.CurrentDomain.FriendlyName} <Parameter>");
// ...
}
static void RebootComputer()
{
// ...
}
Args is an array, so you have to reference the argument by its index. So args[0] corresponds to the first argument passed in. In addition, check the array length first to ensure an argument was even provided before you try to access it.
static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "-help")
{
Console.WriteLine("Some help here...");
}
}
args is an array so you need to look for -help occurrence in it. You can achieve it using String.Contains() method.
static void Main(string[] args)
{
if (args.Contains("-help"))
{
Console.WriteLine("Some help here...");
}
}

Disallow console to print any keys and take only arrows as input

I have the following code in a Console Application C#. The problem is if I give any input from keyboard other than Arrows, it prints those characters onto the console. Is there a way to prevent characters other than arrows to be printed on the Console. Also is there a way to enhance the following program.
class Program
{
static ConsoleKeyInfo keyinfo;
// public ConsoleKeyInfo keyinfo;
static void Main(string[] args)
{
do
{
keyinfo = Console.ReadKey();
say();
}
while(keyinfo.Key == ConsoleKey.DownArrow
|| keyinfo.Key == ConsoleKey.UpArrow
|| keyinfo.Key == ConsoleKey.LeftArrow
|| keyinfo.Key == ConsoleKey.RightArrow);
}
public static void say()
{
if(keyinfo.Key == ConsoleKey.DownArrow)
{
Console.WriteLine("Down");
}
else if(keyinfo.Key == ConsoleKey.UpArrow)
{
Console.WriteLine("Up");
}
else if(keyinfo.Key == ConsoleKey.RightArrow)
{
Console.WriteLine("Right");
}
else if(keyinfo.Key == ConsoleKey.LeftArrow)
{
Console.WriteLine("Left");
}
else
{
Console.ReadKey(false);
}
}
}
You have to filter the output to the standart output stream.
The console uses a text writer to output the data coming from the standard input, and this text writer is invoked BEFORE the console gives you the key by Console.ReadKey(), therefore, you cannot cancel the outputting of the characters pressed. BUT!
You can set a custom text writer by Console.SetOut();
The code below sets a text writer which will filter everything. Only the Write(char) method is overridden and it is sufficient as far as I can see, if not, you can implement others.
When you need to actually write to the console, swap the text writer to a default one having standart output stream as the base stream, and voila:
class ConsoleFilteredOutput : TextWriter
{
public override void Write(char value)
{
}
public override Encoding Encoding
{
get { return Encoding.Unicode; }
}
}
static TextWriter standardOutputWriter = Console.Out;
static ConsoleFilteredOutput filteredOutputWriter = new ConsoleFilteredOutput();
static void WriteUnfiltered(string text)
{
Console.SetOut(standardOutputWriter);
Console.WriteLine(text);
Console.SetOut(filteredOutputWriter);
}
static void Main(string[] args)
{
Console.SetOut(filteredOutputWriter);
do
{
ConsoleKeyInfo keyinfo = Console.ReadKey();
switch (keyinfo.Key)
{
case ConsoleKey.DownArrow:
case ConsoleKey.LeftArrow:
case ConsoleKey.UpArrow:
case ConsoleKey.RightArrow:
WriteUnfiltered(keyinfo.Key.ToString());
break;
}
}
while (true);
}
}
`

Implementing a pausable thread class

Simple as this! This is my attempt at one, which requires that functions to be threaded with it use a Pause() function through itself in pausable sections.
using System;
using System.Threading;
class BlackThread {
private bool paused;
private Thread innerThr;
// ---
public bool IsAlive {
get {
return innerThr.IsAlive;
}
}
// ===
public void SetAndGo (ThreadStart start) {
paused = false;
innerThr = new Thread(start);
innerThr.Start();
WaitForIt();
}
// ---
public void Pause() {
paused = true;
while (paused);
}
public void Unpause() {
paused = false;
}
public void WaitForIt() {
while(!paused && IsAlive);
}
public void Continue() {
Unpause();
WaitForIt();
}
}
class MainClass {
static void pausableFunction (BlackThread self) {
Console.WriteLine("* Waiting...");
self.Pause();
Console.WriteLine("* Doing stuff.");
self.Pause();
Console.WriteLine("* Finished!");
}
static void Main() {
BlackThread noir = new BlackThread();
noir.SetAndGo(() => pausableFunction(noir));
while (noir.IsAlive) {
Console.Write("> ");
Console.ReadKey();
noir.Continue();
}
}
}
Sadly, it's not one that can be paused at any time, but a thread for functions that require to wait for outside processing to be able to continue. Like an action by a game mob that requires its frame to be drawn by the draw loop before it can continue, and the mob's A.I.'s is processed in the game's main loop.
I guess it'd make it some kind of pseudo-thread? Anyway.
It would allow the mob to process this action bit by bit every loop, instead of cascading checkings in its A.I. like...
if mob is doing action {
if mob has already done this previous part of the action {
do the following part
}
}
...it'd rather be like this, in a thread:
do the first step of the action
Wait for it to be rendered...
do the following step of the action
Wait for it to be rendered...
do the last step of the action
(Action ends here, no need to wait for anything anymore)
Now, my implementation has a bug which I cannot figure out how to fix. When it's supposed to unpause the BlackThread, it remains paused in the function (in this case, pausableFunction()) that uses it. I guess it's because of how the instance is passed?
If it's what I'm guessing - that is, something (and I'd guess it's bool paused) is passed by value instead of reference - how could I fix it?
I'm really used to the pointers of C and C++, so sometimes I get a bit tangled when dealing in C# with the communication of an object's values between scopes.
This here is a version of the code the works, a prototype to say:
using System;
using System.Threading;
class Program {
static bool paused;
static void Pause() {
paused = true;
while (paused);
}
static void Unpause() {
paused = false;
}
static void WaitForIt(Thread waited) {
while(!paused && waited.IsAlive);
}
static void Continue (Thread ToStop) {
Unpause();
WaitForIt(ToStop);
}
static void SetAndGo (out Thread thread, ThreadStart Start) {
thread = new Thread(Start);
thread.Start();
WaitForIt(thread);
}
// ---
static void thr (string chant) {
// Console.WriteLine("Waiting...");
// Pause();
// Console.WriteLine("{0}", chant);
// Pause();
// Console.WriteLine("Well, I'm finished!");
Console.WriteLine("I'm finished!");
}
static void Main() {
// Thread tt = new Thread(() => thr());
// tt.Start();
// WaitForIt(tt);
Thread tt;
SetAndGo(out tt, (() => thr("I'm doing stuff.")));
while (tt.IsAlive) {
Console.Write("> ");
Console.ReadKey();
Continue(tt);
}
}
}
I'm only not using it because I'd rather have everything in charge of a specific class for the matter, something that would also enhance readability.
Alright, I've accomplished what I was trying already, so I'll leave my code here for future reference!
This is the BlackThread class in the end:
using System;
using System.Threading;
class BlackThread {
//* ===== *//
private AutoResetEvent pauser = new AutoResetEvent(false);
private AutoResetEvent waiter = new AutoResetEvent(false);
private Thread innerThr;
// ----- //
public bool IsActing {
get {
if (innerThr != null) return innerThr.IsAlive;
else return false;
}
}
//* ===== *//
public void KickStart_(ThreadStart start) {
innerThr = new Thread(start);
innerThr.Start();
WaitForIt();
}
// ----- //
// FOR THE THREADED FUNCTION
public void Wait() {
waiter.Set();
pauser.WaitOne();
}
public void End() {
waiter.Set();
}
// ----- //
// FOR BLACKTHREAD MANAGING
private void WaitForIt() {
waiter.WaitOne();
}
public void Continue() {
if (IsActing) {
pauser.Set();
WaitForIt();
}
}
//* ===== *//
}
And here, an example of its use:
class MainClass {
static void pausableFunction() {
Console.WriteLine("* Waiting...");
Event.Wait();
Console.WriteLine("* Doing stuff.");
Thread.Sleep(1000);
Event.Wait();
Console.WriteLine("* Finished!");
Event.End();
}
static void anotherFunction(int foo) {
Console.WriteLine("* Wanna know the value of a number?");
Event.Wait();
Console.WriteLine("* I'll tell you. It's {0}!", foo);
Event.End();
}
static void simpleFunction() {
Console.WriteLine("* I'm done already!");
}
static BlackThread Event = new BlackThread();
static Random Rand = new Random();
static void Main() {
int r;
do {
if (!Event.IsActing) {
Console.WriteLine();
r = Rand.Next(3);
if (r == 0) {
Event.KickStart_(() => pausableFunction());
}
else if (r == 1) {
simpleFunction();
}
else {
Event.KickStart_(() => anotherFunction(Rand.Next(20) + 1));
}
}
else {
Event.Continue();
}
Console.Write("> ");
Console.ReadKey();
} while(true);
}
}
What I've opted to use in the end were two AutoResetEvent handlers. One is managed in the function of the thread that requires pausing, and that pauses the main loop, the waiter ARE, and another, the pauser ARE, managed in the main loop, and that pauses the thread with the function with support for BlackThread; that is, has acess to a BlackThread instance.
In this case I've used a static BlackThread object, but it can also be passed as a parameter to the function.
And yes, it's named after the Buddhist hell!

Categories