Is Powerpoint still a single instance app?

  • Thread starter Thread starter Howard Kaikow
  • Start date Start date
Mike M. said:
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.

It seems that the problem can be solved by enumerating processes.
 

Thanks, Howard. That still leaves me puzzled, though.

It refers to "Instancing" as having one of two values, Single- or MultiUse. It
doesn't refer to Instancing as a property distinct from those two.

And either I'm missing the kick in the head that triggers the AHA or the
article is wrong. It says:

"Depending on whether the server is designed as SingleUse or MultiUse, another
server process may or may not be launched." It doesn't say which is which, but
it seems reasonable to assume that "MultiUse" = "another server may be
launched".

It then goes on to say that Excel and Word are SingleUse, which doesn't seem
right to me. Rather, it seems to have reversed the values.

It does raise an interesting point that reinforces your thoughts, though:
we've been talking about user- and your_code-initiated instances of PPT, but
there might also be an instance initiated by the user or code activating a PPT
object (slide or presentation) from within another app.

The fun never ends. ;-)

If it's possible to identify and stop individual processes independent of the
application instance itself, it sounds as though you're onto a possible
solution to the problem.
 
Steve, I think this terminology goes against the grain. Sort of like
Unicast and Multicast in streaming video. MultiUse means that multiple
users attach to the single instance server. SingleUse means each user gets
their own instance of the server. AHA?
 
Steve Rindsberg said:
Thanks, Howard. That still leaves me puzzled, though.

It refers to "Instancing" as having one of two values, Single- or MultiUse. It
doesn't refer to Instancing as a property distinct from those two.

And either I'm missing the kick in the head that triggers the AHA or the
article is wrong. It says:

"Depending on whether the server is designed as SingleUse or MultiUse, another
server process may or may not be launched." It doesn't say which is which, but
it seems reasonable to assume that "MultiUse" = "another server may be
launched".

It then goes on to say that Excel and Word are SingleUse, which doesn't seem
right to me. Rather, it seems to have reversed the values.

It does raise an interesting point that reinforces your thoughts, though:
we've been talking about user- and your_code-initiated instances of PPT, but
there might also be an instance initiated by the user or code activating a PPT
object (slide or presentation) from within another app.

The fun never ends. ;-)

If it's possible to identify and stop individual processes independent of the
application instance itself, it sounds as though you're onto a possible
solution to the problem.

Yes, MSFT's terminology can be confusing.
I added to the confusion by initially using the wrong terminology.
MSFT appears to use that terminology consistently in various KB articles.

In effect, it means that for PowerPoint, there is a single instance of the
program running, as you can see if you look at the Task Manager, but there
may be multiple uses of that instance.

For, say Word, you can have multiple instances of Word running, which you
can see in the Task Manager.

After my code works with Powerpoint, if the code has created a NEW instance
of PowerPoint, i.e,, no other PPT had been running, then the code has to
determine whether it is safe to Quit PPT. I only do this, because in the
code of interest, I have no need to leave any Presentation active. For the
latterm the issue is not relevant, I'd just let PPT live!

At some point, I need to examine the running processes to determine whether
anybody else started using PPT AFTER I created the NEW instance.

The logic of the solution is straight-forward.
The only issue is how to do it.

I found a number of examples in the MSFT KB, one at ALLAPI, and one in Steve
Roman's API book that demonstrate how to use EnumProcesses, so I think I
can do this.

One disappointment is that PSAPI.DLL is supported only on NT/2000/XP.
Other mechanisms are available for Win 95/Win 98/Win Me.

Unfortunately, I no longer have a Win 98 system and my ancient Win 95 system
does not have the resources to run a VBA version of PPT. So, I will include
code to detect the OS and prevent the PPT stuff from runniing on other OS,
or warn the user that they cannot run code that starts PPT until AFTER my
PPT code has completed, unless PPT was already running.

I'll be disabling keyboard and mouse input during the interval my code needs
to decide whether to Quit PPT, so the user will not be able to start PPT
from the desktop during the very short interval my code is deciding whether
to Quit PPT.

Yes, I am a masochist!
 
Mike M. said:
Steve, I think this terminology goes against the grain. Sort of like
Unicast and Multicast in streaming video. MultiUse means that multiple
users attach to the single instance server. SingleUse means each user gets
their own instance of the server. AHA?

Terminology is in the eye of the beholder, heck, I still think that "PC"
means "plug compatible", not "imPersonal Computer".
 
Steve, I think this terminology goes against the grain. Sort of like
Unicast and Multicast in streaming video. MultiUse means that multiple
users attach to the single instance server. SingleUse means each user gets
their own instance of the server. AHA?

AHA!

Only Microsoft ... <shakes head> ....

Your passion is the software that inspires use to make it imparsible.
 
After my code works with Powerpoint, if the code has created a NEW instance
of PowerPoint, i.e,, no other PPT had been running, then the code has to
determine whether it is safe to Quit PPT. I only do this, because in the
code of interest, I have no need to leave any Presentation active. For the
latterm the issue is not relevant, I'd just let PPT live!

I'm caught up on that end of things. It was the confusion over multi/single
that set me back a notch or two. <g>

One other possibility (another KB article says this won't work with PPT97, not
sure of later versions, and that might be a deal-breaker for you, but ...)

If you use CreateObject("PowerPoint.Application") it launches PPT if PPT isn't
already running, gives you a ref to the running copy otherwise.

And if you set the ref to nothing, PowerPoint goes away IF your code launched
it. If it was alive first, it seems to stay alive after. If you invoke PPT
then somebody else does, then you quit, it still stays alive. I've poked at it
a bit this evening and it seems to work. How widely/reliably I can't promise.

The bug on PPT 97 is referenced in one of the links from that same 288902
article.

If that works, it could save lots of APIdiving.
Unfortunately, I no longer have a Win 98 system and my ancient Win 95 system
does not have the resources to run a VBA version of PPT.

If you run into this problem often, a copy of Virtual PC or VMWare is a
wonderful investment. One PC, multiple operating systems.
Yes, I am a masochist!

You've fallen in among people who write code to automate PPT. You fit right
in.
 
I also use C++ to automate PowerPoint and initially I was having a problem
with getting PowerPoint to go away after I closed my reference to it. That
was using PPT 2000. I didn't have any trouble (well, that specific trouble)
once I started using PPT 2002. I vaguely remember thinking there was a
problem with the reference counting in that version of PPT but it might just
be a bad sector in my memory or bad programming. I am becoming more
susceptible to both.
 
I also use C++ to automate PowerPoint and initially I was having a problem
with getting PowerPoint to go away after I closed my reference to it. That
was using PPT 2000. I didn't have any trouble (well, that specific trouble)
once I started using PPT 2002. I vaguely remember thinking there was a
problem with the reference counting in that version of PPT but it might just
be a bad sector in my memory or bad programming. I am becoming more
susceptible to both.

The article about '97 was quite old, from before 2000 came out.
Quite possibly the problem wasn't corrected in 2000.
That's good to know.
 
All I need to be able to do is detect whether my code needs to create a NEW
PowerPoint.

Then, when deciding whether to Quit, check the number of processes being
used by PPT. This is independent of PPT.

I've been distracted the past few daze, so I've not yet finished the
solution.
Expect to do so by week's end.
 
Are you referring to KB article 249169?

Not sure whether that applies.

I'd be using New to create the instance.
Guess I'll find out, but first I will get the code working with PPT 2003,
then test 97, 2000 and 2002.

At worst, if I know that I want to Quit, I should think that I'd be able to
kill the process via the API.
 
I was just referring to a co-worker's and my trial and error testing. Lots
of both. Just keep it in mind.

Since there is one and only one process named powerpnt.exe running I am not
sure how enumerating process is going to help. How will you determine what
process created the instance? Or are you looking for the existance of the
PowerPoint GUI?
 
Are you referring to KB article 249169?

Yes, that's the one.
Not sure whether that applies.

Not so much if you're going to deal with processes, I wouldn't think.
But if you were going to rely on setting the reference to PPT to nothing in
order to close PPT only if nobody else was using it, don't. According to the
article, it's a non-starter, since PPT doesn't properly keep reference counts.

And MikeM says the same's at least partially true of 2000.

In short, if you need to support all extant versions of PPT, you'll want to
just kind of close your eyes and turn away from this branch of the thread. ;-)
 
Mike M. said:
Since there is one and only one process named powerpnt.exe running I am not
sure how enumerating process is going to help. How will you determine what
process created the instance? Or are you looking for the existance of the
PowerPoint GUI?

I am investigating 2 structures.

PROCESSENTRY32 has a cntUsage member that is supposed to return the "Number
of references to the process". However, thus far, I've only been getting 0,
so I may not be yet correctly using the structure.

MODULEENTRY32 has a member GlblcntUsage which returns the "Global usage
count on the module" for the specified process; and there is a ProccntUsage
member which returns the "Module usage count in the context of the owning
process".

In order to access MODULEENTRY32, I have to use the Module32First and
Module32Next APIs. So far, I've not ben able to get those APIs to return a
success code.

I attacked this problem by attempting to translate C code to VB 6. I've not
done much with C, especially recently, so I likely screwed up somewhere.

My model is the following two articles in the MSDN library. You can find
them by searching for Module32First, among other ways. The articles are
included in the documentation for VS .NET 2003 and in the Oct 2001 MSDN
library.

One article is "Traversing the Module List", the other is "Taking a Snapshot
and Viewing the Process".

I may try plopping the code into VS C++ .NET to see if I can get the pure C
code to work.
 
Hi Howard,
I am investigating 2 structures.

PROCESSENTRY32 has a cntUsage member that is supposed to return the "Number
of references to the process". However, thus far, I've only been getting 0,
so I may not be yet correctly using the structure.

MODULEENTRY32 has a member GlblcntUsage which returns the "Global usage
count on the module" for the specified process; and there is a ProccntUsage
member which returns the "Module usage count in the context of the owning
process".

I'm guessing that at least one of those counters isn't properly maintained by
PPT97(and possibly 2000) and/or Windows; that'd explain the problem that Mike
and I referred to earler, where PPT doesn't always shut down when the last
reference to it is released.

If there are others that do work properly, you're onto something.
 
Please keep us informed if one of these works for you. I would like to be
more forgiving when closing PowerPoint as opposed to my, "You are done now"
approach.

Thanks.
 
I've really gone overboard.

I recalled that I have an old copy of MSFT Visual C++ 6 learning addition on
another system.

So I went to the MSDN site and downloaded the articles to try to get that C
code to run.

My first discovery was that the article at MSFT's MSDN site is significantly
different than the article I was using, so there was perhaps an error in the
earlier verion of the article that had caused my grief in trying to get the
critter to run in VB 6 and VB .NET.

Well, I managed to get the code to compile in C ++ 6, but I have not a clue
as to how to add a Form in C++ 6 and the output is rather unreadable as I
converted all the printf to std::cout.

So, I then rebooted to my real system and managed to import the workspace
into VS .NET C++.

However, .NET won't let me add a Form unless I convert the project from
Unmanaged to Managed. I have no clue on how to do that. Fortunately, I do
have a C++ book for .NET, so I'll take a look at that.

Of course, I'll still get the C# books (I'm leaning towards getting the
Liberty book and the Step By Step), as I will sill convert the critter to
C#, VB .NET and VB 6.

Hmm, I better hide, I think I see the men in the white coats coming!
 
I feel like I belong in a room with padded walls.

In any case, here's where I am at.

1. I downloaded the latest version of the base article that uses C code with
the structures I am investigating. The URLs are::

http://msdn.microsoft.com/library/d...e/taking_a_snapshot_and_viewing_processes.asp


http://msdn.microsoft.com/library/d...s/perfmon/base/traversing_the_module_list.asp

Do NOT use the articles from the earlier MSDN libraries, such as the Oct
2001 library. They differ, so there may have been an error in the earlier
versions.

2. Although, I 've not really used Visual C++ .NET before, I seem to have
gotten the code running in C++ .NET.

One problem tho, the project was automatically created as an unmanaged
project, so I am unable to add a Form to the project, so it is just a
console app, making it very dificult to examine the output.

I may be able to create an empty managed project and copy the code there.
I'll try that later.

I need to buy a book that tells me how to create various C++ .NET projects.
There are way too many combinations available.

3. I've gone this far and still intend to convert the code to C#, VB .NET
and VB 6.

Once I get all those variants, I'll allow others to check out the code to
see whether I've done things right.

Preliminary evidence is that PowerPoint does not make the usage counts
available via the two structures I've been examining, but I do not yet
accept that as a definitive answer.

a. I could have messed up something converting from C to C++.
b. I'd like to get the concurrence of others.
c. There may be another way, of which I am not yet aware, to get the usage
counts.
 
Back
Top