Checking if application is already running
Checking if application is already running
Checking if application is already running
Checking if application is already running
Checking if application is already running
Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running
Checking if application is already running Checking if application is already running
Checking if application is already running
Go Back  Xtreme Visual Basic Talk > > > Checking if application is already running


Reply
 
Thread Tools Display Modes
  #1  
Old 01-21-2009, 04:20 PM
jprg jprg is offline
Regular
 
Join Date: Dec 2008
Posts: 72
Default Checking if application is already running


Hi,
I want to be able to test if an Excel application is already running on the computer. If it is, I want to use it to create and save a new file. Excel will remain open.
If no Excel application is running, I will open Excel, create and save a new file, and then close Excel.
What is the best way to accomplish this?

Thank you.
Reply With Quote
  #2  
Old 01-22-2009, 10:08 AM
Mike Rosenblum's Avatar
Mike Rosenblum Mike Rosenblum is offline
Microsoft Excel MVP

Forum Leader
* Guru *
 
Join Date: Jul 2003
Location: New York, NY, USA
Posts: 7,848
Default

Hey jprg,

You can do this by first trying to "get" the Excel.Application that is already running and if that fails then create a new Excel.Application.

You can get the currently running process by name ("Excel.Application", in this case) either via the System.Runtime.InteropServices.Marshal.GetActiveObject method or via the Microsoft.VisualBasic.Interaction.GetObject method.

If you're using VB.NET, then using GetObject is probably easiest. Here's an example:

Code:
' VB.NET

Dim xlApp As Excel.Application
Try
    xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
Catch ex As Exception
    xlApp = New Excel.Application
End Try
And here's an example using the Marshal.GetActiveObject method using VB.NET:

Code:
' VB.NET
' Imports System.Runtime.InteropServices;

Dim xlApp As Excel.Application
Try
    xlApp = CType(Marshal.GetActiveObject("Excel.Application"), Excel.Application)
Catch ex As Exception
    xlApp = New Excel.Application
End Try
And Marshal.GetActiveObject using C#:

Code:
// C#
// using System.Runtime.InteropServices;

Excel.Application xlApp = null;
try
{
    xlApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
}
catch (Exception)
{
    xlApp = new Excel.Application
}
I think any of these should work for you. Give it a try and let us know how it goes...

Mike
__________________
My Articles:
| Excel from .NET | Excel RibbonX using VBA | Excel from VB6 | CVErr in .NET | MVP |
Avatar by Lebb
Reply With Quote
  #3  
Old 01-22-2009, 12:36 PM
BBauer42's Avatar
BBauer42 BBauer42 is offline
Contributor
 
Join Date: Dec 2005
Location: CT, USA
Posts: 448
Default

You could also try to read the process like this.

Code:
dim blnExcelOpen as boolean = False For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL") blnExcelOpen = True Exit For Next

If blnExcelOpen is true after the loop, there was an Excel App open.
__________________
www.sportsloon.com
Reply With Quote
  #4  
Old 01-22-2009, 04:12 PM
Mike Rosenblum's Avatar
Mike Rosenblum Mike Rosenblum is offline
Microsoft Excel MVP

Forum Leader
* Guru *
 
Join Date: Jul 2003
Location: New York, NY, USA
Posts: 7,848
Default

Good point...

But if you want to actually manipulate the Excel instance via automation in order to create and save a new file, etc., then it's pretty close to impossible to convert an instance that you grab within via the Process class to an Excel.Application instance.

The only way I know of, in fact, is a difficult trick using GetObject(), so I think you are better off just trying to use GetObject(, "Excel.Application") first, and then, if that fails, create a new Excel.Application.

It's worth being aware of the Process.GetProcessesByName() though -- you need this sometimes if you want to monitor multiple instances, or sometimes it can be used as a last-case scenario to kill a hanging instance.
__________________
My Articles:
| Excel from .NET | Excel RibbonX using VBA | Excel from VB6 | CVErr in .NET | MVP |
Avatar by Lebb
Reply With Quote
  #5  
Old 01-07-2010, 07:59 AM
Mike Rosenblum's Avatar
Mike Rosenblum Mike Rosenblum is offline
Microsoft Excel MVP

Forum Leader
* Guru *
 
Join Date: Jul 2003
Location: New York, NY, USA
Posts: 7,848
Default

As an update to my comment above that:

Quote:
If you want to actually manipulate the Excel instance via automation in order to create and save a new file, etc., then it's pretty close to impossible to convert an instance that you grab within via the Process class to an Excel.Application instance.
This definitely *can* be done. It's a complex procedure, but it does work as advertised. I wrote a forum reply on how to handle this here: Accessing Multiple Instances of Applications.

-- Mike
__________________
My Articles:
| Excel from .NET | Excel RibbonX using VBA | Excel from VB6 | CVErr in .NET | MVP |
Avatar by Lebb
Reply With Quote
  #6  
Old 01-07-2010, 11:51 PM
Roger_Wgnr's Avatar
Roger_Wgnr Roger_Wgnr is offline
CodeASaurus Hex

Forum Leader
* Expert *
 
Join Date: Jul 2006
Location: San Antonio TX
Posts: 2,427
Default

Mike, Just a question here for my own knowledge and curiosity.
Instead of using a Try Catch would it not be a better option to look for the process and then cast it if it is found like this
Code:
Dim xlApp As Excel.Application
For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL")
    xlApp = CType(Marshal.GetActiveObject("Excel.Application"), Excel.Application)
    Exit For 
Next
If xlApp is Nothing then
    xlApp = New Excel.Application
End If
__________________
Code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. ~Martin Golding
The user is a peripheral that types when you issue a read request. ~Peter Williams
MSDN Visual Basic .NET General FAQ
Reply With Quote
  #7  
Old 01-08-2010, 05:39 AM
Mike Rosenblum's Avatar
Mike Rosenblum Mike Rosenblum is offline
Microsoft Excel MVP

Forum Leader
* Guru *
 
Join Date: Jul 2003
Location: New York, NY, USA
Posts: 7,848
Default

Hey Roger,

Yes, you could check that an Excel process exists first by checking the Process.GetProcessesByName and then only call Marshal.GetActiveObject only if at least one Excel object is found. But you would *still* need to use a try-catch block, believe it or not.

Checking that an Excel process exists via Process.GetProcessesByName is a nice idea, but is not a huge help because the Marshal.GetActiveObject will tell you if a process exists as well, although it does so by throwing an exception. So to avoid having your program crash due to the exception, you either need a try-catch block, or you would need to check if the process exists first, say via Process.GetProcessesByName. So far so good, but there is a potential problem...

The problem is that the operating system is a multi-threaded environment. So even if your code is running single-threaded, the state that it is operating against is changing independently of your program. So between the time that you check for the existence of the the application via Process.GetProcessesByName and then subsequently attempt to get that process via Marshal.GetActiveObject, the state may have changed. In short, the application might now be gone, and, as a result, Marshal.GetActiveObject could still throw an exception.

Admittedly, the probability of the application being able to close in the millisecond (or microsecond) between checking Process.GetProcessesByName and then attempting to get the object for that process via Marshal.GetActiveObject is pretty remote. But if you want your code to run in a 100% fail-safe manner, then you would still need to use a try-finally block.

So, in the end, using Process.GetProcessesByName does not save you anything. The Process.GetProcessesByName method can tell you if the process exists, but so does the Marshal.GetActiveObject method, and Process.GetProcessesByName does not allow you to avoid a try-finally block anyway. (As surprising as that seems!)

Make sense?

Mike
__________________
My Articles:
| Excel from .NET | Excel RibbonX using VBA | Excel from VB6 | CVErr in .NET | MVP |
Avatar by Lebb
Reply With Quote
  #8  
Old 01-08-2010, 06:12 PM
Roger_Wgnr's Avatar
Roger_Wgnr Roger_Wgnr is offline
CodeASaurus Hex

Forum Leader
* Expert *
 
Join Date: Jul 2006
Location: San Antonio TX
Posts: 2,427
Default

Yep, Makes perfect sense.
I kinda wondered if it was going to be something like that but I have not done anything using any marshaling methods to this point but it's good knowledge to have.
__________________
Code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. ~Martin Golding
The user is a peripheral that types when you issue a read request. ~Peter Williams
MSDN Visual Basic .NET General FAQ
Reply With Quote
  #9  
Old 01-08-2010, 06:25 PM
Mike Rosenblum's Avatar
Mike Rosenblum Mike Rosenblum is offline
Microsoft Excel MVP

Forum Leader
* Guru *
 
Join Date: Jul 2003
Location: New York, NY, USA
Posts: 7,848
Default

I haven't used Marshal.GetActiveObject myself much to be honest. I used to use VBA.GetObject with VBA and VB 6.0 quite a bit, though.

The Marshal.GetActiveObject method is pretty much identical. In fact, there is an even more exact duplicate of the VBA.GetObject method exposed by the Microsoft.VisualBasic.Interaction.GetObject method. I haven't looked at it within a reflector, but I'd bet that it's simply calling Marshal.GetActiveObject behind the scenes...

These "GetObject' approaches are pretty weak, though. If there is more than one instance of the application that is running, you never know which one you are going to get. Although it is a lot more work, it is better to use an approach that can let you access the specific instance that you want, as described here.
__________________
My Articles:
| Excel from .NET | Excel RibbonX using VBA | Excel from VB6 | CVErr in .NET | MVP |
Avatar by Lebb
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Checking if application is already running
Checking if application is already running
Checking if application is already running Checking if application is already running
Checking if application is already running
Checking if application is already running
Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running Checking if application is already running
Checking if application is already running
Checking if application is already running
 
Checking if application is already running
Checking if application is already running
 
-->