C# Application exit - c#

I want to know how i can do something when exiting a windows application, i wan to run a query UPDATE users SET on = 0; so i know when people are on my program
Main reason for this is i want to do a list of online people for my chat system so they know who they are chatting to i will be doing this with a foreach of where on = 1 in my mysql database users table
i have tryed doing my own close button but what do i do when it is force closed it can be force closed by task manager or if their computer restarts

A program can be killed, an internet connection can go dead or a nuclear bomb could be dropped on a town. The point is, the client can't always do the update.
Update your schema to have a "LastTimeSeen" column and have the other clients use this to decide if a peer is missing and then age that peer out of the system.

Handle the Form.Closing event:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.closing.aspx

Related

Why can't a windows service created in C# detect that a screen saver is currently running?

As part of some work I need to get done for Windows 10, I have written a code in C# that essentially detects every minute whether a PC is in screen saver mode or not, and it writes to a table in MySQL the relevant status ("PC in use" if the screen saver is off, "available PC" if the screen saver is on).
I did this using (full link if required - https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C):
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,
ref isRunning, 0 );
return isRunning;
}
The code works flawlessly in console application mode (I made a loop to test it out over a minute with a check up on screen save status every 10 seconds), this means in MySQL the status was set correctly every time, depending on the screen save status at the moment of the check up.
The problem occurs when I use this code for a windows service. The service is installed correctly, the log on tab is set on Local System (I also tried with the logged in user instead, same results) and I allow the service to interact with the desktop, just in case, but the difference here is that no matter if the PC enters screen save or not, it always returns false on GetScreenSaverRunning(), thus setting the status of the PC in MySQL as "PC in use", even if the screen saver is on at the moment of check up.
I get the sense that the problem isn't in the code itself, since it works without any issues as a console application, but perhaps something behind the scenes. I tried to search here and on many other websites, haven't found anything related to such a problem.
Does anyone have any idea at all what might be the issue? Any help and/or suggestions will be greatly appreciated!
Thank you in advance.
(I could post the code if required, but it is pretty much straight forward and the main part of it, controlling the screen save detection, is taken from the website mentioned above, afterwards it's a simple if (GetScreenSaverRunning() == true) )
Ever since Vista, Services are barred from a Interactive Session. Even if they run under the same rights, they do not get a interactive Session. I would guess that is getting in the way here.
While you can overwrite this behavior in the Service settings, this is not adviseable for new code. Consider making this a Background Task started by the Task Sheduler instead.
Because the windows service runs in different session then the windows logon. You can't interact with the desktop related services unless you run the windows service in win logon session. There used to be an option in Windows service manager where you can set the properties to "Interact with desktop session" but I don't think that ever worked.
There's a work around to run the windows service using the win logo session.
See this helper class that can get the current logged on user session and interact with the desktop services. https://github.com/murrayju/CreateProcessAsUser/blob/master/ProcessExtensions/ProcessExtensions.cs

Update Wifi networks programmatically

I'm trying to create program that connects to certain wifi network when it's in range, even if already connected to another wifi.
I'm using SimpleWifi, and basically it works great. Except that it does not see new wifi networks before I clicked wifi icon in Windows 10 taskbar to show list of networks.
How can I force c# program to update wifi network list?
Currently using IEnumerable<AccessPoint> accessPoints = wifi.GetAccessPoints().OrderByDescending(ap => ap.SignalStrength); to update wifi networks, but as I said, it does not see new networks before refreshed manually from Windows.
It's almost 3 years ago but here is my take on this issue anyways.
In that library you can call:
SimpleWifi.Wifi.Disconnect()
Which I do before re-connect and get the list of access points again. This works sort of, new networks introduced after windows discovery does actually show up, but are way slower than if you click "wifi" button in Windows, which will bring up newly discovered networks right away.
If someone knows a solution to "trigger" Windows/Managed wifi connections to update it's list, just like you do in Windows, I would appreciate that
SimpleWifi, like other Wifi libraries have this feature built-in. And its required as Windows does not always show all the wifi networks available correctly, unless queried..
the sample code can be found here: https://pastebin.com/1iCp41SP
, not the most elegant code , but worked in a WPF project.
This part of the code scans/refreshes the Wifi List in SimpleWifi
var testClient = new WlanClient();
foreach (WlanInterface wlanIface in testClient.Interfaces)
{
wlanIface.Scan();
}

How to create an automated column in SQL Server?

IDE: Visual Studio, C# .net 4.0, Winforms application
Is there any way in SQL Server to implement a column in a table which can set itself automatically to 0 when it has not received any ACK (acknowledgement) signal from the application side?
The requirement is I want to keep a column which can keep track that Is application is open or it has been closed?
One way to implement is using the OnClose() event, i.e. on Close() I can change it's value to 0. but the problem is suppose application got hanged for some reason or Power is gone than the value in database will not be updated to zero.
So I want to create an automated column which can track this situation and make itself zero when the application is not sending any request or idle means closed.
please suggest how to handle this.
You can't do that. The only thing you can do is to save GETDATE() in a column in a table as the last activity time of the application and invoke the stored procedure from a high-priority thread every 10 seconds for example.
When you want to know if the application is alive or not, just check this value, if more than 10 seconds is passed since then, you app is gone.
UPDATE:
A more precise but complex approach would be to listen on a socket inside your application and then whenever you want to know if the application is alive, send a request from your sql script to PING the application. You should use CLR programming for this approach, but I think the first one will be practically enough.
Considering it will be a multiple instance scenario where multiple instances of the application can point to same database. You can try the following:
Create a separate table to maintain sessions. This table would contain three columns 1)Machine name or IP 2) Session Id (GUID) and 3) TimeStamp.
Whenever application starts create a new session id and make an entry into this table it means new session is started.
Keep on updating timestamp on every request based on session id.
Have a timeout configured somewhere in web.config or database which will come in handy later.
Now when application is exiting gracefully then delete the row from the table.
Now if application crashes the row won't be delete so next time when application starts you can check if the row already exists. Use machine name or IP to query to the table.
Use the timeout setting configured in (3) above to determine since how long the application is idle.

Set service dependencies after install

I have an application that runs as a Windows service. It stores various things settings in a database that are looked up when the service starts. I built the service to support various types of databases (SQL Server, Oracle, MySQL, etc). Often times end users choose to configure the software to use SQL Server (they can simply modify a config file with the connection string and restart the service). The problem is that when their machine boots up, often times SQL Server is started after my service so my service errors out on start up because it can't connect to the database. I know that I can specify dependencies for my service to help guide the Windows service manager to start the appropriate services before mine. However, I don't know what services to depend upon at install time (when my service is registered) since the user can change databases later on.
So my question is: is there a way for the user to manually indicate the service dependencies based on the database that they are using? If not, what is the proper design approach that I should be taking? I've thought about trying to do something like wait 30 seconds after my service starts up before connecting to the database but this seems really flaky for various reasons. I've also considered trying to "lazily" connect to the database; the problem is that I need a connection immediately upon start up since the database contains various pieces of vital info that my service needs when it first starts. Any ideas?
Dennis
what your looking for is SC.exe. This is a command line tool that users can use to configure services.
sc [Servername] Command Servicename [Optionname= Optionvalue...]
more specificly you would want to use
sc [ServerName] config ServiceName depend=servicetoDependOn
Here is a link on the commandlike options for SC.EXE
http://msdn.microsoft.com/en-us/library/ms810435.aspx
A possible (far from ideal) code solution:
In you startup method code it as a loop that terminates when you've got a connection. Then in that loop trap any database connection errors and keep retrying as the following pseudo code illustrates:
bool connected = false;
while (!connected)
{
try
{
connected = openDatabase(...);
}
catch (connection error)
{
// It might be worth waiting for some time here
}
}
This means that your program doesn't continue until it has a connection. However, it could also mean that your program never gets out of this loop, so you'd need some way of terminating it - either manually or after a certain number of tries.
As you need your service to start in a reasonable time, this code can't go in the main initialisation. You have to arrange for your program to "start" successfully, but not do any processing until this method had returned connected = true. You might achieve this by putting this code in a thread and then starting your actual application code on the "thread completed" event.
Not a direct answer put some points you can look into
Windows service can be started Automatically with a delay. You can check this question in SO for some information about it.
How to make Windows Service start as “Automatic (Delayed Start)”
Check this post How to: Code Service Dependencies

Is it possible to Shut down a 'remote PC' programatically through .net application? [duplicate]

This question already has answers here:
Shutdown a remote computer connected in LAN in any preferable language
(7 answers)
Closed 4 years ago.
I am wondering, Is it possible to Shut down a remote PC programatically through .net application?
If yes, how it can be?
See this KB article
For example:
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName = "shutdown.exe";
proc.StartInfo.Arguments = #"\\computername /t:120 ""The computer is shutting down"" /y /c";
proc.Start();
The example above uses the following switches (excerpted from the linked article)
\\computername: Use this switch to specify the remote computer to shut down. If you omit this parameter, the local computer name is used.
/t:xx: Use this switch to specify the time (in seconds) after which the computer is shut down. The default is 20 seconds.
"The computer is shutting down": Use this switch to specify a message during the shutdown process. The maximum number of characters that the message can contain is 127.
/y: Use this switch to force a "yes" answer to all queries from the computer.
/c: Use this switch quit all running programs. If you use this switch, Windows forces all programs that are running to quit. The option to save any data that may have changed is ignored. This can result in data loss in any programs for which data is not previously saved.
WMI will work for this task. The Win32_OperatingSystem class has a method called Win32Shutdown. This can be used to shutdown a remote computer.
Win32Shutdown: http://msdn.microsoft.com/en-us/library/aa394058(VS.85).aspx
The following blog entry has a full program in C# that demonstrates how to shutdown a computer using WMI. Search for Win32Shutdown on the page (about the 2nd article down)
http://urkec.mojblog.rs/
You can use WMI from your program for that.
I have a local application running with an user than have a group policy indicating this user can’t shutdown the pc.
And then I use your code, but when I ask by user and password to impersonate my app. I received the next error
System.Management.ManagementException: it’s not possible to use the user’s credentials for the local connections
My way:
Process.Start("ShutDown", "/s");
Fired from a remote ASP.NET page, of course.

Categories

Resources