Windows Processes - Allowing only one (VB.Net)

~J~

~J~

Soldato
Joined
20 Oct 2003
Posts
7,558
Location
London
Help!

Trying to get the code working below but to no joy.

In short, I want to load an application ONCE and ONCE only during a given time period (in the example, it's notepad).

But I've got two problems (big ones too!!)

Firstly, Notepad doesn't open up. It loads as a process, you can check by looking at the windows task manager, but not as an app.

Secondly, I just can't seem to get the thing checking to see if the process is already running, and if it is, then ignore the init for the notepad.

Anyone any ideas?

Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
_BatchImportProcess.StartInfo.FileName = "C:\WINDOWS\NotePad.Exe"
_BatchImportProcess.StartInfo.CreateNoWindow = False
_BatchImportProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
_BatchImportProcess.StartInfo.ErrorDialog = True
_BatchImportProcess.StartInfo.UseShellExecute = True
Timer1.Enabled = True
End Sub

Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
If Not _BatchImportProcess.HasExited = True Then
_BatchImportProcess.Kill()
End If
Timer1.Enabled = False
End Sub

Private Sub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
Timer1.Enabled = False
Dim _StartTime As New TimeSpan(10, 0, 0)
Dim _EndTime As New TimeSpan(18, 1, 0)
Dim _Start As Integer = Now.TimeOfDay.CompareTo(_StartTime)
Dim _End As Integer = Now.TimeOfDay.CompareTo(_EndTime)

Dim c As Process()
c = Process.GetProcessesByName(_BatchImportProcess.ProcessName.ToString)

If _Start = 1 And _End = -1 And c.Length = 0 Then
EventLog1.WriteEntry("Watson Batch Import", "Batch entry started at " & Now.ToLongTimeString & " on " & Now.ToLongDateString)
_BatchImportProcess.Start()
End If

Timer1.Enabled = True
End Sub
 
Never tried to do this myself but I am sure you will need to use something like the FindWindow API or similar to do what you are after.

sfx
 
Services are always running and therefore do not run under the same account details as the current logged on user. This is because they need to be able to run when no-one's logged onto the system. You're best bet is to run the service as the currently logged on user (not great, as it'll quit when you log off), or not use a service in the first place. Services usually shouldn't be running programs that get in the face of users....
 
Cheers for the help guys, just a couple of points...

I've managed to get only one instance working now, but I can't get the "Notepad" app to open up even though it's appearing within the task-manager.

Notepad is only an example, the system will launch the actual app (Sage) during the evening whilst no one is at work to import data. I agree totally that the service shouldn't get in the face of the user, hence why it's run at 20:00 on an evening, and will occur on the server that the Sage data is held.

It's literally now a case of asking why/how to get the Notepad to open up fully rather than a new process of Notepad that isn't accessible to the user.
 
Like I said, it's not only good practice to stop services getting the faces of users, it's made very difficult. Every process that produces a window that the user sees is run under the username of the person that is logged in. If you go into your task manager, and look at the username column, all the processes are running with your username in that column are processes which could in theory interact with your desktop. If you check the Show processes from all users, you'll start to see the services that might be running as a LOCAL SERVICE or as SYSTEM. These cannot interact with your desktop, because they don't have access to it.

Therefore, if you're running your service under the default SYSTEM account, and you try to start a process like notepad, that will also be run under the SYSTEM account. As a result, the process will start, and it'll work, but it'll effectively be displayed on the SYSTEM's desktop, which doesn't actually exist.

All of the above is only relevent if you are trying to get a service to interact with a user's desktop. There are really only two ways of doing this:

a) run the service as the currently logged in user. This means if you log out, the service will quit.

b) Don't use a service. Instead, use an application that runs in the background under the logged in user. This will be able to show/hide windows much like any other application.

Now, all of this is a complete red herring if what you're trying to do is a regular automated process when no-one is about. If no-one is about, you don't need a user interface to be brought up, you can just pass off commands to the process on what it needs to do, and it'll handle it as the SYSTEM user.

The other question that's worth asking is why you're not using a scheduled task to do this if it's a regular occurance?
 
I don't think notepad will ever be visdable if you try starting it as a service, notepad is not meant to be run as a service and I doubt Microsoft intended it to be run as a service either. So starting it as a service will get the process going but nothing else.

Sage probably has service capabilities so you should have no problem there, but for notepad you really need to either shell it from your own application and us an API to check for how many times notepad.exe is open. Be careful though if you plan to kill one if another instance does open up as you may kill the wrong one. :)

sfx
 
So basically, it is working, but Notepad isn't the right way to test it then?

Sage doesn't have service capabilities in the way that the customer wants.

It would be fantastic if the customer had SQL Server as I could set up an automated DTS package to do the import of the data, but they are using MSDE which doesn't have this facility, and thus the API calls are within a DLL that Sage uses to copy, extract, covert and import the data (BACS payments) into Sage.

As for using a scheduled task, I agree, it would be an easy way out, but the client in question has one of these ridiculously water-right security policies where automated tasks that call an EXE are not allowed, it has to be done as a service.

I'll have a go with the actual app itself and see if that fires, there's a lot of examples on the net though that show the Calc or the Notepad been fired as examples, so I'm still not convinced I'm going forward correctly as they seem to be getting results quite good (http://www.vbforums.com/showthread.php?t=384214 is an almost word for word example of what I'm trying to achieve, my post attached at the bottom).

But thanks for the help again, it's really appreciated...
 
I'd say your best bet is to see if the sage process is happy running as the SYSTEM user, doing it's thing and then quitting. If so, then just start it from a service, and it'll work even when no-one is logged in :)
 
Windows Services can interact with the current desktop without being logged in as the current user. All you need to do is specify a flag when you install the service, or you can tick the box manually on the Properties of your service in the Services MMC.

serviceinteract.gif


But as said, Notepad isn't runnable as a service as it doesn't implement the required interfaces.
 
Last edited:
Tried the above mate, cheers for that.

Still no joy. I've tried loads of apps and none of them are firing at all. I get the process, but no interactive window at all.

I just don't understand where I'm going wrong. There's loads of examples that are using Notepad or Calc for a 'taster', mine just aint firing at all.

Starting to annoy me now - lol.
 
Well as shown on that forum you just posted you can start notepad as a service by the looks of it and I just tested it and it opened up fine. I also made it so only one instance can be run from my application.

This is C# but the framework is the same.

Code:
            if (Process.GetProcessesByName("notepad").Length == 0)
            {
                Process.Start("notepad.exe");
            }

sfx
 
I know mate, it's really damn frustrating to see everyone else do it but me :(

Maybe I'm cursed! lol

I'll keep battling on, I have to, I'm just wondering if it's anything to do with my machine or not.

The code has changed since the above, only one instance, at the correct time, all works perfectly, just doesn't show for the user to interact with.

Thanks for the follow up though, glad to see there's some hope.
 
Have you tried using ProcessStartInfo instead as with that you can say if it is visable, minimized etc...?

sfx
 
Back
Top Bottom