.Net COM interop initialization question

  • Thread starter Thread starter Mark
  • Start date Start date
M

Mark

Hi...

I have a bit of an odd situation I'm trying to work around. Our code has a
bunch of ASP.Net code with several of the objects registered for COM interop.

Our websites also have an ISAPI filter that makes use of these COM interop
objects.

By default, in production, our app/objects read some configuration from the
registry.

My problem is that I'm trying to set up a box for shared development so
multiple people can RDP into a box and work - and these COM interop objects
are causing some headaches.

I tweaked our code so that the ASP.Net side can override the registry
settings with web.config changes and that works fine.

What doesn't currently work is that we only have 1 copy of the COM interop
objects registered at one time. Leaving aside the issue where user/website A
can be calling/using the COM interop object from user/website B's directory,
I've been trying to get user/website A's use of the COM interop objects
initialized with different values.

Here's what I tried:

1) I gave each user his own App Pool
2) I tweaked DllMain in the ISAPI filter to set the current working
directory to the website home
3) I created a w3wp.exe.config file with the setting overrides I wanted.

The hope was that even though I was running the code from a different path,
the COM interop objects for *my* w3wp.exe process would see w3wp.exe.config
and read settings from there.

Unfortunately it didn't work. When my website fired up and the ISAPI filter
fired up the com interop objects, they still got the configuration from the
shared registry settings.

Any idea where I went wrong in the above?

Thanks
Mark
 
Unfortunately it didn't work. When my website fired up and the ISAPI
filter fired up the com interop objects, they still got the
configuration from the shared registry settings.

Any idea where I went wrong in the above?

Think about how the IIS process works, I am not sure you can get around
this. The only way I can think of that might possible setting up a WCF UI
with a COM wrapper, but even then you could end up with a single instance
of the COM component (have to think this one through).

Perhaps setting up the COM component in COM+ might help overcome some of
the issues, but I am not 100% sure of that either.

is there a .NET equivalent you can code in for the future?

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
Hi Greg...

Thanks for answering... I'm not sure what you're getting at with "Think
about how the IIS process works".

I found other articles (not related to IIS) that said .Net COM interop would
look for <image>.config files for settings in general. With IIS6, that
process would be w3wp.exe, hence w3wp.exe.config.

Of the points not covered in the articles I read were
1) Possibly when they said <image>.config, were they referring to the
registered dlls, not the instantiating process?

2) A managed program will look for and load its app.exe.config file from the
get-go; if the consumer of the COM objects is unmanaged, it wouldn't. Will
the COM interop do the looking for the config file? Perhaps that's what you
were alluding to?

I'll see if I can get a small test case thrown together...

Thanks
Mark
 
Thanks for answering... I'm not sure what you're getting at with "Think
about how the IIS process works".


DISCLAIMER: Oversimplification in process

When you say ISAPI, do you mean something you wrote in C++ as an ISAPI
filter or do you mean a .NET HTTPhandler that calls COM components? I was
thinking the later when I started answering this thread and may be off
track. If so, apologies.

COM is a very complex subject, especially in regards to .NET.

When you cross the boundary from managed to unmanaged code, you open
yourself for errors. The standard .NET callable wrapper simply acts as a
proxy between the COM bits and the .NET bits, but this may not be enough,
especially if you have multiple applications hitting the same bits.

In newer versions of windows, there are some ways around the COM issue.
And, if the component is installed in COM+, you have other options. But the
person who programmed the COM component may have still boxed you in with
the way they set things up.

Since I don't know the actual component, I am shooting in the dark hoping
to hit a target. ;-)

IIS sits on top of COM+ (the MTS part primarily, where it has sat since IIS
4.0, at least I don't think earlier versions used MTS, but someone will
likely correct me if so). .NET sits on top of IIS. There is already a lot
of interop with the native components to get web processes finished, even
though some is going away as they retool .NET, the CLR, etc.

What I am attempting to do here is give you some places to look other than
a single document that is designed to solve a single problem. Even if the
problem sounds just like yours, the installation of the COM bits on the
server may null and void the solution.

As for COM: Depending on the component you are using, you may be completely
leaving the IIS/COM+ process to access the component. In these cases, it is
almost guaranteed to be a bottleneck.

if you don't mind me asking, what is the COM component in question?


Long term, I still think re-examining what the component does, and finding
a .NET option, is probably the wisest solution.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
Hello
Unfortunately it didn't work. When my website fired up and the ISAPI
filter fired up the com interop objects, they still got the configuration from
the shared registry settings.

You can probably work around this problem by registering your COM component
to per-user registry profile. HKCR is a combination of
HKLM\Software\Classes\ and HKCU\Software\Classes\. By default, the COM
component is registered under HKLM\Software\Classes\, which is shared by
all users. You can consider registering it to HKCU\Software\Classes\, and
then the component will be only visible to that user.
http://blogs.msdn.com/jaredpar/archive/2005/05/29/423000.aspx


Regards,
Jialiang Ge
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
 
Thank you for responding Jialiang...

That is an interesting approach. To be clear, since this is pertaining to
IIS instances, I'd probably have to run each instance under a specific user
to take advantage of this, correct?

I mean, the IIS instance would have to be running under the right user for
HKCU to be in effect...

Thanks
Mark


"Jialiang Ge [MSFT]" said:
Hello
Unfortunately it didn't work. When my website fired up and the ISAPI
filter fired up the com interop objects, they still got the configuration from
the shared registry settings.

You can probably work around this problem by registering your COM component
to per-user registry profile. HKCR is a combination of
HKLM\Software\Classes\ and HKCU\Software\Classes\. By default, the COM
component is registered under HKLM\Software\Classes\, which is shared by
all users. You can consider registering it to HKCU\Software\Classes\, and
then the component will be only visible to that user.
http://blogs.msdn.com/jaredpar/archive/2005/05/29/423000.aspx


Regards,
Jialiang Ge
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================

.
 
Hi Greg...

A lot of this is very old code... The ISAPI filter is, in fact, old C++.
The COM objects it's referencing *used* to be in C++ but as various pieces
were migrated to .Net, the same interface was exposed to the old code as .net
COM interop. Mostly the classes are abstractions of database interfaces
(logical names for dbs controlled by a central class).

They are inproc com components, so there's no interprocess communication
going on.

And yes, this does mean that we have the same classes running twice for
every w3wp process running. We have one app domain for the com objects
invoked by the C++ and another when the aspx pages actually run.

The larger task of rearchitecting everything is more than people have been
willing to bite off so far...

As I say, I read an article or 2 found through Google where they say .net
com interop will try to look for <app>.config to initialize itself (though no
one specified what <app> would be or how the interaction with unmanaged code
would work).

I took a gamble that
a) the .net com interop code would be looking for the invoking process name
(w3wp.exe.config)
b) that since the parent was unmanaged and wouldn't have already loaded an
<app>.config that the com interop would
c) given b) that I'd have a little time in the unmanaged code to set the
directory before the com objects were called so they'd be looking in the
right place.

Seems some part of the above wasn't working the way I was hoping.

Maybe you're right - you can spend so much time trying to work around the
gorilla in the room that it may just be more profitable to tackle some of the
old problems.

Thanks
Mark
 
Maybe you're right - you can spend so much time trying to work around
the gorilla in the room that it may just be more profitable to tackle
some of the old problems.

Mark:

One possibility, although kludgy, would be to recompile the components with
different GUIDs, so they are seen differently. This will not eliminate all
problems, but could route each app to a different "component". Long term
maintenance would be a bear, however (a different gorilla?), so it would be
a stop gap measure only.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
Thank you for responding Jialiang...

That is an interesting approach. To be clear, since this is
pertaining to IIS instances, I'd probably have to run each instance
under a specific user to take advantage of this, correct?

I mean, the IIS instance would have to be running under the right user
for HKCU to be in effect...

Jialiang's idea could work well if you were merely talking the Terminal
Services part of the equation. Since you are focusing on IIS, I don't think
it is workable ... unfortunately.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
Just as a general FYI, I found the flaw in my earlier reasoning...
ConfigurationManager doesn't care what your current working directory is - it
looks in the home directory of the .exe running. So if I moved my config
files to C:\windows\system32\inetsrv, the .net COM objects do see and process
the config.

Unfortunately putting things in inetsrv doesn't move me around my problem at
all...

Thanks
Mark
 
Ah well... I tried my next straw to grasp at - If I put a w3wp.exe.config in
inetsrv and had

<appSettings file="%MyPath%\My.config" />

in there, I might be able to get each web instance to set its own source.

Problem is that <appSettings file= doesn't appear to expand environment
variables...

Why are the easy solutions always so hard? :)
 
Okay, I think I found my loophole. Some are going to find this a gross hack,
but I think it'll work.

In the inetsrv directory, I have a w3wp.exe.config that looks like this:

<configuration>
<appSettings file="D:My.config"/>
</configuration>

Then I put all my web instances on drive D and have the isapi filter set the
current working directory to the website instance home.

The file attribute can expand relative paths *including* the
drive-current-working-directory.

This way you have multiple websites all going to their particular config...

Thanks
Mark
 
Okay, I think I found my loophole. Some are going to find this a
gross hack, but I think it'll work.

In the inetsrv directory, I have a w3wp.exe.config that looks like
this:

<configuration>
<appSettings file="D:My.config"/>
</configuration>

Then I put all my web instances on drive D and have the isapi filter
set the current working directory to the website instance home.

The file attribute can expand relative paths *including* the
drive-current-working-directory.

This way you have multiple websites all going to their particular
config...

Sounds like you may have found the kludge that works. I had to get
around networking security here today, so I understand the hacker
mentality. ;-)

I am going to play with this at some time, as it sounds interesting. Not
first on my list with the new VS 2010 bits.

Peace and Grace,


--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
Back
Top