Don't display wait cursor when console app is launching - c#

I've developed a small console application that essentially pings a url, records the result, restarts the phone if required and then schedules itself to run again.
The client is complaining about the "washing machine" icon being displayed (albeit for less than a second) every time the application launches.
I'm hiding the wait cursor in the first line of my main method but is there any way of preventing the wait cursor from displaying at all?
static void Main()
{
//Hide cursor
IntPtr hOldCursor = SetCursor(IntPtr.Zero);
//Ensure EventLog table is ready
PrepareDatabase();
tapi = new Tapi();
tapi.TAPI_Open();
//Ping specified URL and restart phone if required.
PingRestart();
tapi.TAPI_Close();
//Set the application to run again after the ping interval has passed
SystemTime systemTime = new SystemTime(DateTime.Now.AddMilliseconds(RegistryAccess.PingInterval));
CeRunAppAtTime(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase, ref systemTime);
}

There is no way to disable the wait cursor, as it appears before the application runs so the application can't block it.
The only way is to code it in C or Assembly, as those languages start up very fast in comparison to .NET executables. But still, an AntiVirus program could block it for a while before it executes.

Related

C# Find and handle child processes of a process

i need help finding the child processes (they are 2) of a process and handle them in order to set each of them foreground when needed.
The main process is Java Platform SE binary whose indicative name is javaw.
Using this code:
Process[] arrProcesses = Process.GetProcessesByName("javaw");
I can get the main process, so with:
IntPtr ipHwnd = arrProcesses[0].MainWindowHandle;
SetForegroundWindow(ipHwnd);
I can set it foreground.
My problem is that the handled process is the "last used" process...
Explaning better: on application bar of Windows I have 2 application(A, B) using java, if i click on A, when i use the code above, the application A gets foreground, insted, if i click on application B, with that code the B gets foreground.
What i want to do is decide which of two set foreground.
Anyone can help me?

process.mainwindowhandle always returning zero

I am trying to start another program from my code and set it to be the size of the screen. No matter what I try, I can't seem to get the correct handle of the window, so SetWindowPos() fails. This is on a Raspberry Pi, and the window I am trying to resize is LXTerminal running a Python script.
Code:
Process p = Process.Start ("bash", b.command);
p.WaitForInputIdle (100);
Process[] procs = Process.GetProcessesByName ("/usr/bin/lxterminal");
p.Refresh ();
IntPtr handle = procs [0].MainWindowHandle;
Console.WriteLine (handle);
SetWindowPos (handle, 0, 0, 0, 1920, 1080, 0x0040);
This always prints '0' for the handle, and "SetWindowPos (nil) (nil) to [0,0x1920,1080] 64" after the SetWindowPos has been run.
b.command is equal to -c "lxterminal -e 'python3 ../../../../GameV1.py'" (but only in this case.) This code for lxterminal is an example and the program may launch other processes.
You are waiting for input idle in a maximum amount of time of 0.1s. I sincerely doubt that the process is going to both start AND have it's main message loop created in such short manner.
I suggest you use the parameterless overload instead, so that you'll wait until the process's message loop has entered an idle state - which is when its window should've been created:
p.WaitForInputIdle()
Quoting the documentation:
A process is said to be in an idle state when it is waiting for messages inside of a message loop. This state is useful, for example, when your application needs to wait for a starting process to finish creating its main window before the application communicates with that window.

C# WPF Machine-Dependent Concurrency Issues

I have a multi-threaded C# WPF application that is a plug-in to a larger software (Princeton Instruments LightField, for those who are interested).
My plug-in invokes a synchronous method on a thread separate from the GUI. This method is from a camera API and captures an n-second exposure from the camera and returns the frame that was captured.
The situation looks something like this:
private static volatile bool _STOP = true;
// Runs when the "Run" button is clicked
private void Run_Click(object sender, RoutedEventArgs e)
{
object time = InputTime.Text; // a non-negative integer provided by the user
_STOP = false;
Thread run_thread = new Thread(Running);
run_thread.Start(time);
}
// Runs when the "Stop" button is clicked
private void Stop_Click(object sender, RoutedEventArgs e)
{
_STOP = true;
}
// Separate Thread from GUI
private void Running(object t)
{
int time = Convert.ToInt32(t);
FrameObject f;
while(!_STOP)
{
// synchronously capture a t-second exposure
f = CameraAPI.CaptureImage(t);
// display the exposure on a viewer controlled by the parent thread
Application.Current.Dispatcher.BeginInvoke(new Action(Viewer.Display(f));
}
}
This code (or, rather, it's more complex sibling) works perfectly fine on the computer I developed it on (Computer A). I click Run and the entire application remains responsive while the code is running.
When I try to run it on the computer where it will be hosted regularly (Computer B), however, the following behavior appears:
When clicking the Run button, the GUI becomes unresponsive for n
seconds (n being the time sent to the CameraAPI.CaptureImage(n);
method). This occurs for any positive integer n and continues as the
while loop executes this method each loop cycle (i.e. the application freezes for n seconds, there is a brief unfrozen moment while the Display method is called, and then the application freezes again for n seconds).
If I call Thread.Sleep(n); in place of
CameraAPI.CaptureImage(n);, the application does not freeze.
It is not just my plug-in that freezes - it is the entire application.
I have built, rebuilt, deleted and recopied my code from Computer A to Computer B, and the error persists.
Computer A (where I built this) is identical (as far as I've found)
to the computer having the issues (Computer B). The processors, OS,
drives, RAM, application versions, etc. are all the same. Computer A
specifically exists so that applications can be developed for
Computer B.
Removing the Application.Current.Dispatcher.BeginInvoke(new Action(Viewer.Display(f)); line does not stop the GUI freezing. This is not the problem method.
The application uses the same number of threads (43) on each computer. When the plug-in is running, the number of threads increments by the same amount (1-4 depending on where in the program we are) on each computer.
So, on two seemingly identical systems, the same code has different results. On System A, it works as intended (no GUI freezing), and on System B, the GUI of the entire application -- not just of the plug-in that I am writing -- freezes each time a synchronous method is called.
This error behavior exceeds my understanding of computers, so now I'm here. Any ideas as to what is causing this difference in behavior?
We reinstalled the parent application and everything works fine. Still have no idea why this happened, but closing the question since the problem is resolved. A true case of "turn it off and back on again."

C# monitor external process state

I am making a launcher app in C# on windows. However the process isn't directly started by my C# application but it uses a url to start it e.g "steam://rungameid/xxxxxxx"
I need it to monitor a process by name (say XYZ.exe) in the following fashion:
Receive an event when XYZ.exe starts
Receive an event when XYZ.exe exits
I just want to minimise and restore the my C# application's form when the application is running and not running respectively
thanks
Make a timer (with your preferred timer method) and poll every 'n' milliseconds (find what's best for you... I'd say for minimizing/restoring from a game, 500 milliseconds could be a good start, but experiment), then you can use something like:
bool processRunning = false;
void timerTickMethod()
{
var procIsRunning = Process.GetProcessesByName("xyz.exe").Any();
if(procIsRunning && !processRunning)
ProcessIsStartedEvent(); // or directly minimize your app
else if(!procIsRuning && processRunning)
ProcessIsEndedEvent(); // or directly restore your app
processRunning = procIsRunning;
}
If you want to make sure it's your xyz.exe that is running, you can pass in the full path to GetProcessesByName (so that if there's other xyz.exe in your system, it won't confuse your app)
Update
I was writing from memory, so maybe GetProcessesByName only work for friendly names (with no exe, or path).
If that's the case (I haven't tried), and you need the full path you could do it like:
var procIsRunning = Process.GetProcesses().Any(x => x.MainModule.Filename == #"c:\your\full\path.exe");

timer in console application

I am creating a device application using .NET compact framework 2.0. There is a system.threading.timer in my application which executes some code. It works fine. My problem is when I am running the app by double clicking on the exe in the bin folder, the timer starts and execute all it works but it never stops. It runs in the background even after closing the app by clicking the X-button or from the file menu close button. I don't understand how and where I stop or dispose of the timer so that it doesn't run after closing the app. May be something like a form_closing event in window form application. I had searched a lot in Google but did't find any proper answer.
The application is use to generate digital output for a device
here is some code of timer event:
public static void Main()
{
// Some code related to the device like open device etc
// Then the timer
System.Threading.Timer stt =
new System.Threading.Timer(new TimerCallback(TimerProc), null, 1, 5000);
Thread.CurrentThread.Join();
}
static void TimerProc(Object stateInfo)
{
// It is my local method which will execute in time interval,
// uses to write value to the device
writeDigital(1, 0);
GC.Collect();
}
It is working fine when I run the code in debug mode, timer stops when I stop the program. But not working when I run the exe.
You could create and dispose it in Main() and pass it to any methods that require it?
private static void Main()
{
using (var timer = new System.Threading.Timer(TimerProc))
{
// Rest of code here...
}
}
More importantly, this line of code:
Thread.CurrentThread.Join();
will never return, because you are asking the current thread to wait for the current thread to terminate. Think about that for a moment... ;)
So your solution is probably to just remove that line of code.
All about GC.Collect();
Your stt object is used once and after that is pointed out to being removed and its memory reclaimed.
If you don't belive call stt.ToString(); at the end of main function, it will extend the stt live till the end of main function.
Solution(s)?
You can define the stt object as a static - it guarantees that it will be alive till the end of live of you program
recommended solution is to use GC.KeepAlive(stt); which you can call at the end of main function which will keep the stt away from destroying process.

Categories

Resources