Is Powerpoint still a single instance app?

H

Howard Kaikow

As of Powerpoint 2000, it is my understanding that there can only be a
single instance of Powerpoint running.
Is that still true for Powerpoint 2002 and 2003?

I've been using code such as the following:

'Get existing instance of PowerPoint; otherwise create a new one
' Powerpoint is a single instance application
On Error Resume Next
Set appPPT = GetObject(, "PowerPoint.Application")
If Err.Number = 0 Then
blnNewPPT = False
Else
Set appPPT = New PowerPoint.Application
blnNewPPT = True
End If
On Error GoTo 0
and then

With appPPT
If blnNewPPT Then
.Quit
Else
.ActivePresentation.Close
End If
End With

However, I suspect that code may not be good enough.
Do I not need to know whether the single instance of Powerpoint is being
used by another user, even if I created the instance within the code?
 
S

Steve Rindsberg

As of Powerpoint 2000, it is my understanding that there can only be a
single instance of Powerpoint running.
Is that still true for Powerpoint 2002 and 2003?

Still true. All versions from 97 on are devoutly single-instance.

A few things that might help distinguish between a session you invoked from
scratch and a reference to an existing session:

With app.PPT
if .Presentations.Count = 1 Then
if .Presentations(1).Path = "" and _
.Presentations(1).Name = "Presentation1" Then
' it's your session or
' somebody started PPT but hasn't done anything yet
End If
End if

End With
 
H

Howard Kaikow

Steve Rindsberg said:
Still true. All versions from 97 on are devoutly single-instance.

Should "devoutly" be "devilishly"?
A few things that might help distinguish between a session you invoked from
scratch and a reference to an existing session:

With app.PPT
if .Presentations.Count = 1 Then
if .Presentations(1).Path = "" and _
.Presentations(1).Name = "Presentation1" Then
' it's your session or
' somebody started PPT but hasn't done anything yet
End If
End if

End With

Ayup, I thought about those, but the real issue is control.
If I decide that I own the session and nobody else is using powerpoint,
there is still an instant or so, during which I'd be killing the critter and
somebdy might have just started a session.

I run only in a single user environment, so I cannot test some concerns?

Is the single instance of PowerPoint system wide, or is it on a desktop by
desktop basis, on a multi-user system?
If the latter, I could disable the desktop whilst I kill the critter.
 
S

Steve Rindsberg

Should "devoutly" be "devilishly"?

<g>

That depends on whether you want to have multiple instances or to be certain of
which instance you have. ;-)
Ayup, I thought about those, but the real issue is control.
If I decide that I own the session and nobody else is using powerpoint,
there is still an instant or so, during which I'd be killing the critter and
somebdy might have just started a session.

Point taken, and it'd be better to head that off at the pass if possible.
Still, in that case the worst that'd happen is that the new session wouldn't
start. I can't tell you how often I'm sure I doubleclicked something but got
no reaction, oh well, try again. Wouldn't this appear to be one of those? In
other words, it might be very mildly puzzling, surely far less than normal
Windows behavior can be, but wouldn't cause any loss of data.


I run only in a single user environment, so I cannot test some concerns?

Is the single instance of PowerPoint system wide, or is it on a desktop by
desktop basis, on a multi-user system?
If the latter, I could disable the desktop whilst I kill the critter.

It would almost have to be on a desktop by desktop basis, else PowerPoint would
be stumbling all over itself whenever two users had it active. Same would be
true of any app I'd think. Not so much true of the app, in fact, but a
question of whether Windows permits them to see one another. It'd have to be
keeping them all (and each user's session) in separate memory spaces wouldn't
it?

To be sure, that's speculation on my part.
 
H

Howard Kaikow

Steve Rindsberg said:
That depends on whether you want to have multiple instances or to be certain of
which instance you have. ;-)

The goal is to automate powerpoint from word in an a vb 6 program.
once the task is done, there's no need to retain the powerpoint instance,
not unlike a multi-use app, i.e., it's bad to allow instances of multi-use
apps to be left active.
Point taken, and it'd be better to head that off at the pass if possible.
Still, in that case the worst that'd happen is that the new session wouldn't
start. I can't tell you how often I'm sure I doubleclicked something but got
no reaction, oh well, try again. Wouldn't this appear to be one of those? In
other words, it might be very mildly puzzling, surely far less than normal
Windows behavior can be, but wouldn't cause any loss of data.

I guess the best I can do, is lock the desktop momentarily, and check the
Presentations count.
If = 1, then I'd quit powerpoint, otherwise, I'd let it live and be
visible.

Of course, visibility is another issue.

If I created the instance with GetObject, instead of NEW, I'd have to take
care not to make powerpoint invisible if some else is udsing the critter.
It would almost have to be on a desktop by desktop basis, else PowerPoint would
be stumbling all over itself whenever two users had it active. Same would be
true of any app I'd think. Not so much true of the app, in fact, but a
question of whether Windows permits them to see one another. It'd have to be
keeping them all (and each user's session) in separate memory spaces wouldn't
it?

That's what I would think.
I'll code as if that were true, i.e., lock the desktop while using a NEW
powerpoint instance.
 
H

Howard Kaikow

It has ben suggested that id, instead og killing the powerpoint instance, if
i just set it to Nothing, the instance of powerpoint will go away if there
are no other powerpoint sessions.

I'll try this later.

I would feel comfortable relying on this only if I saw documentation of this
behavior, and for powerpont 97, 2000, 2002 and 2003.
 
H

Howard Kaikow

Came up with a "solution".
Seems too simple to be correct.

For the code below, one needs a Userform with 3 buttons.

1. Shut down any running PowerPoint.
2. Click on the Create PPT button.
3. After the program creates a PPT session, create a PPT session via the
GUI, not using the icon minimized by the code.
4. Click on the Close PPT button.
5. Click on the Bye Bye button.

This code would appear to work for those cases in which my code need not
keep a presentation alive. So, if I close all the code's presentations, this
method appears to work.

If I have to keep a presentation alive, that should be no problem as I just
would not close PowerPoint, just set its object variable = Nothing.

Does this hanky panky solve the problem?

Option Explicit
Private appPPT As Powerpoint.Application
Private blnNewPPT As Boolean
' Private MyPrivateName As String

Private Sub btnByeBye_Click()
Unload Me
End Sub

Private Sub btnClosePPT_Click()
With appPPT
If blnNewPPT Then
If .Presentations.Count = 0 Then
.Quit
lstActions.AddItem "New instance was Quit."
Else
lstActions.AddItem "New instance was NOT Quit."
End If
Else
On Error Resume Next
.ActivePresentation.Close
On Error GoTo 0
lstActions.AddItem "Extant instance was not Quit."
End If
End With
Set appPPT = Nothing
lstActions.AddItem "Set instance = Nothing."
On Error Resume Next
lstActions.AddItem Err.Number & ":" & Err.Description
On Error GoTo 0
End Sub

Private Sub btnCreatePPT_Click()
'Get existing instance of PowerPoint; otherwise create a new one
On Error Resume Next
Set appPPT = GetObject(, "PowerPoint.Application")
lstActions.AddItem Err.Number & ":" & Err.Description
If Err.Number = 0 Then
blnNewPPT = False
lstActions.AddItem "Extant instance is being used."
Else
Set appPPT = New Powerpoint.Application
blnNewPPT = True
lstActions.AddItem "New instance was created."
End If
With appPPT
' MyPrivateName = "HK" & Now & CDbl(Now)
.Visible = True
.WindowState = ppWindowMinimized
lstActions.AddItem "Presentations Count: " & .Presentations.Count
End With
On Error GoTo 0
End Sub
 
H

Howard Kaikow

The "solution" does not detect a Powerpoint session that has no
presentations, other than my own.

Is there an API, or some such that can tell me a reference count, or
whatever, number of PowerPoint instances being used?

P.S.: I've been using the wrong terminology. MSFT uses "multi-use" and I've
been using "single use".
 
H

Howard Kaikow

i stumbled upon a possible solution last night.
i'll try to verify later today or tonight.
 
S

Steve Rindsberg

I guess the best I can do, is lock the desktop momentarily, and check the
Presentations count.
If = 1, then I'd quit powerpoint, otherwise, I'd let it live and be
visible.

Depending on user settings and version, PPT may automatically create a blank
presentation on startup, so presentation count might be 0 or 1 even if you've
invoked it. That's why I suggested the other rigamarole re checking the
presentation's name (always Presentation1 until it's been saved) and the path
(blank until it's been saved).
 
S

Steve Rindsberg

Howard,

What about iterating through the current window collection before attempting to
get a PPT object; if any of the windows belong to PowerPoint, then somebody's
using it.

PowerPoint 11 (2003) down to PPT97:
"PP11FrameClass"
"PP10FrameClass"
"PP9FrameClass"
"PP97FrameClass"
 
H

Howard Kaikow

http://www.standards.com/; See Howard Kaikow's web site.
Steve Rindsberg said:
Depending on user settings and version, PPT may automatically create a blank
presentation on startup, so presentation count might be 0 or 1 even if you've
invoked it. That's why I suggested the other rigamarole re checking the
presentation's name (always Presentation1 until it's been saved) and the path
(blank until it's been saved).

Yes, I realize that, and there may even be no presentation.
That's why I'm trying the following.
-------------------------
I've come up with the following, is it valid?

1. Make sure that PowerPoint is not running.

2. Run a VB 6 program that creates a NEW instance of PowerPoint.

3. While the program in step 2 is still running, and PPT has not been Quit,
run another VB 6 program that enumerates desktop processes, call the output
List 1.

4. While the PPT from step 2 is still running, start PowerPoint from the
desktop. Since I had already created an instance in step 2, both should end
up using the same instance as PowerPoint is multi-use, single instance.

5. Now, again run the program that enumerates desktop processes, call the
output List 2.

Both List 1 and List 2 give the same handle for PowerPoint, and the same
number of top level windows,

List 1 does not list an active presentation, whilst List 2 lists
Presentation1. So the first bit of info is that the PowerPoint window will
be that of the latest use of Powerpoint. So this doesn't help solve my
problem.

However, the Total Thread Windows is 9 for List 1, 11 for List 2

I am enumerating the processes using code based on KB article 183009 and
only incrementing the counters when PP11FrameClass is found.

So, is it safe to ASSuME that I can determine that there is another user
using my PowerPoint object if the thread count is greater than the number
reported by List 1?
 
H

Howard Kaikow

Steve Rindsberg said:
Howard,

What about iterating through the current window collection before attempting to
get a PPT object; if any of the windows belong to PowerPoint, then somebody's
using it.

See my posting of a few minutes ago where I enumerated processes.
The sticky point is that my New instance of PPT is still open when I do the
iterations, i.e., I'm trying to determine whether I can Quit.

I am hoping that I can do this based on the thread count, as discussed in my
other posting.

it is necessary to do this iterating only if the presentation count is 0, as
i have already closed my, if any, presentation.
 
H

Howard Kaikow

Not yet there, the code from the KB article is enumerating Windows, not
processes, so doesn't handle case where presentation count = 0.
 
S

Steve Rindsberg

See my posting of a few minutes ago where I enumerated processes.
The sticky point is that my New instance of PPT is still open when I do the
iterations, i.e., I'm trying to determine whether I can Quit.

So the problem at this point is:

Having fired off your own instance of PPT, how can you be certain that a user
hasn't in the interim invoked PPT on their own?

If you know that you started by invoking PPT when it wasn't previously open,
then you should also be able to maintain a count of any presentations you've
opened or created; if someone manually starts/opens another presentation, then
..Presentations.Count will be higher than your total, so it wouldn't be safe to
force PPT to quit.

Does that oonch us a bit closer? ;-)
 
H

Howard Kaikow

Steve Rindsberg said:
Having fired off your own instance of PPT, how can you be certain that a user
hasn't in the interim invoked PPT on their own?

If you know that you started by invoking PPT when it wasn't previously open,
then you should also be able to maintain a count of any presentations you've
opened or created; if someone manually starts/opens another presentation, then
Presentations.Count will be higher than your total, so it wouldn't be safe to
force PPT to quit.

Does that oonch us a bit closer? ;-)

No.

Because the presentation count could still be 0.

Enumerating processes appears to resolve the problem, but I want to simplify
the code.
 
S

Steve Rindsberg

No.

Because the presentation count could still be 0.

Possibly for that instant, but closing an instance of PPT with no open
presentations will do no harm.
 
H

Howard Kaikow

Steve Rindsberg said:
Possibly for that instant, but closing an instance of PPT with no open
presentations will do no harm.

It sure does.

It closes the other uses of PPT.
Users, and other code, whould not be very ubhappy if theirPPT suddenly
disappeared.

To restate the problem.
----------------------------
I was using the wrong terminology.

PowerPoint is a Multi-use, single Instance app.

Assume that PPT is not running.

Then my code creates a NEW instance of PPT.
Then, while my code is running, PPT is again started by a user from the
desktop or via another piece of code.
Etc.

AFAIK, it is possible for all uses of PPT to have, at any point in time, a
Presentations.Count of 0, so I cannot tell whether I should Quit my instance
of PPT, based on Presentation count, lest it affect the other uses.

At some point, I would do the following:

1. DoEvents
2. Disable keyboard and mouse input
3. test for number of PowerPoint critters.
4. If only 1 critter, Quit PPT, otherwise let it live.
5. Enable keyboard and mouse input
6. exit from my code.

Enumerating processes, using say, the example at ALLAPI, lists a different
working set size for each use of PPT.

In my case, all I need to know is whether there is one use or more, does not
matter how many. If 1 use, then I can safely Quit my instance of Powerpoint.

I need to study the ALLAPI, and other examples, to make sure the info is
what I need.
 
M

Mike M.

My app has been doing what Steve suggests for almost 4 years without any
reports of problems. There is one and only one instance of Powerpoint
(powerpnt.exe) running regardless of how many programs have a reference
count to it or if a user opened the GUI for Powerpoint. I check to make
sure that presentations count <= 0 then I call the Powerpoint quit method.
If a user has started the GUI and closed the pres1 (or whatever) default
presentation Powerpoint creates then indeed when you quit PowerPoint it
closes the GUI. If other programs have connected to that instance of
Powerpoint then they would get an exception when they referenced that
object. But that is why there is a big disclaimer on the MS web site that
tells us not to use Powerpoint in an automated fashion. We are pretty much
out there on our own. I had originally hoped they would expose the
reference count through a method or property but I didn't see it.

Good luck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top