Log users off of server, if Access application stops running

I have an MS Access application, running on a very locked down 2012 R2, RDP server.  If an issue occurs that can't be handled by the Access application a user message pops us with one of the options being to log-off.  However, I had an issue yesterday, where something happened and Access just exited, but it left the user with a black screen requiring another user with Admin rights to log them off through the Task Manager.  I need this to be handled without Admin involvement.

I was thinking of writing a small c# app that is loaded by the Access application on startup.  My idea was to pass it the ProcessID through a command line switch, and then have the app monitor the PID every 30 seconds or so.  If the PID disappears (ie, Access has crashed out), it simply logs the user off.  However, resources on the server are tight, so I'm trying to find the best method.

Is this a good idea, or is there a better way?  Also, if anyone has any code suggestions, that would make my life easier.

Thank you.
Andy BrownDeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Shaun VermaakTechnical Specialist/DeveloperCommented:
[DllImport("user32.dll", SetLastError = true)]
static extern bool ExitWindowsEx(uint uFlags, uint dwReason);

Process[] processes = Process.GetProcessesByName("ProcessName");
if (processes.Length == 0)
{
     ExitWindowsEx(0, 0);
}

Open in new window

0
Andy BrownDeveloperAuthor Commented:
That's great - thank you Shaun.

Do you have any suggestions on how I should run this process/function?  I was thinking that it checks every 10-30 seconds or so, but as I'm pretty new to c#, I was wondering if there was a better/leaner way of doing it.
0
Shaun VermaakTechnical Specialist/DeveloperCommented:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace SomeNameSpace
{
    partial class Service : ServiceBase
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool ExitWindowsEx(uint uFlags, uint dwReason);
        private Timer timer = new Timer();
        public Service()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            int interval = 5000;
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Interval = interval;
            timer.AutoReset = true;
            timer.Enabled = true;
            timer.Start();

            base.OnStart(args);
        }

        protected override void OnContinue()
        {
            timer.Start();

            base.OnContinue();
        }

        protected override void OnPause()
        {
            timer.Stop();

            base.OnPause();
        }

        protected override void OnStop()
        {
            timer.Stop();

            base.OnStop();
        }

        protected override void OnShutdown()
        {
            timer.Stop();

            base.OnShutdown();
        }
        static void timer_Elapsed(object sender, EventArgs e)
        {
            Process[] processes = Process.GetProcessesByName("ProcessName");
            if (processes.Length == 0)
            {
                ExitWindowsEx(0, 0);
            }
        }
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

Mal OsborneAlpha GeekCommented:
Are the users being presented with a full desktop, or a remote app? If the former, maybe try setting the access program up as a remote app instead.

https://technet.microsoft.com/en-us/library/cc753844(v=ws.10).aspx
0
Andy BrownDeveloperAuthor Commented:
Thank you Mal - so, I'm guessing if it crashed, they could kill it through their own Task Manager?  That said, currently the way they are working (excluding this issue), is quite good.  Are there any obvious (when you know-how), pros/cons by moving to a remote app?
0
PatHartmanCommented:
The fact that Access just blanked indicates that you are using the Access runtime and/or an .accde and that there was an unhandled error.

When you use the runtime or an .accde, it is important to have extensive error trapping.  If the user has any idea what he was doing when Access just stopped, I would try to figure out where the procedure without the error handler is and fix that.
0
Andy BrownDeveloperAuthor Commented:
Hi Pat - good to hear from you.

Access runtime - correct.

The error trapping is good.  We've been running now for several months and this is the first instance where it's crashed them out.  Whenever an error occurs, it gets logged and I also get an email with the ID as to where is happening and fix it - but I haven't had a single error this month (other than this one).  I also think this error has been caused by a recent attack on the server, which is another story and one we have resolved.

Thanks for the feedback though.
0
PatHartmanCommented:
I can't swear to this but FMSINC.com's Total Access Analyzer might actually point out procedures that are missing error trapping.  I don't put error trapping in every procedure because it always seems like overkill to add 10 lines of error trapping code to a procedure with 1 line of code but it really depends on what the code is doing.  So, any procedure without error trapping could ultimately cause this type of failure.
0
Andy BrownDeveloperAuthor Commented:
I don't think it's that Pat.  

I wrote a function that generates the error tracking mechanism that I use, which I have on every procedure (almost).  If an error isn't handled in the procedure itself, it goes to a function that updates an error log, sends me an email (with procedure ID, line number, variables etc etc) and finally looks at the type of error to see what to do.  If it can't resolve the issue, the user is presented with a message and given the option to logout.

I'm not saying the code is 100% perfect (who can), but it's pretty robust, and in the case of the issue above - I think the lack of resources, caused by the hack was the root-cause.   All I'm trying to do is set up a worst case scenario, where if the user does end up back at the Desktop because of a crash and Access exiting - the user can restart with a new session.
0
Andy BrownDeveloperAuthor Commented:
Thank you everyone.  This certainly set me on the right path.  However, I asked another question with regards to the best type of application (class, console, form etc.), for this to run.  For some reason, I didn't get the exact answer (probably a badly worded question), but I did get some additional code that got me to 95% of where I needed to be

https://www.experts-exchange.com/questions/29070728/Best-type-of-c-solution.html?anchor=a42385878¬ificationFollowed=200874520#a42385878

In the end, I wrote a small, hidden console app, that is called when my application loads.  It sits there and checks for the ProcessID of the application every 15 seconds.  If it is no longer running - it logs the users off.

Thanks again for all of the great help/feedback.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.