Can't 'CoInitializeSecurity(...)' - worked in VS '03, not in VS '0

G

Guest

In order to get events back from a DCOM server (an embedded device running
Windows CE), I seem to have to turn off security for my process. To do this,
I'm saying:

int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, 1,
3, IntPtr.Zero, 0, IntPtr.Zero);

in the constructor of the first static member of my 'Main' executable class.
This worked OK in VisualStudio '03 under .NET v1, but no longer works under
VisualStudio '05 under .NET v2. The 'ret' I now get is 0x80010119, which
'Error Lookup's to:

Security must be initialized before any interfaces are marshalled or
unmarshalled. It cannot be changed once initialized.

As far as I can tell, this is the first line of my code that's getting
executed, so it seems that either the framework or the compiler is doing
something hidden from me.

Can anyone explain this and/or suggest a work-around?
 
W

Willy Denoyette [MVP]

| In order to get events back from a DCOM server (an embedded device running
| Windows CE), I seem to have to turn off security for my process. To do
this,
| I'm saying:
|
| int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero,
1,
| 3, IntPtr.Zero, 0, IntPtr.Zero);
|
| in the constructor of the first static member of my 'Main' executable
class.
| This worked OK in VisualStudio '03 under .NET v1, but no longer works
under
| VisualStudio '05 under .NET v2. The 'ret' I now get is 0x80010119, which
| 'Error Lookup's to:
|
| Security must be initialized before any interfaces are marshalled or
| unmarshalled. It cannot be changed once initialized.
|
| As far as I can tell, this is the first line of my code that's getting
| executed, so it seems that either the framework or the compiler is doing
| something hidden from me.
|
| Can anyone explain this and/or suggest a work-around?
|
|

Not sure what you mean with "contructor of your Main executable class",
anyway, you need to call this as early as possible on program entry, that is
before you call into anything that could initialize COM) in your Main static
function.

Willy.
 
A

Andreas Mueller

DrBonzo said:
In order to get events back from a DCOM server (an embedded device running
Windows CE), I seem to have to turn off security for my process. To do this,
I'm saying:

int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, 1,
3, IntPtr.Zero, 0, IntPtr.Zero);

in the constructor of the first static member of my 'Main' executable class.
This worked OK in VisualStudio '03 under .NET v1, but no longer works under
VisualStudio '05 under .NET v2. The 'ret' I now get is 0x80010119, which
'Error Lookup's to:

Security must be initialized before any interfaces are marshalled or
unmarshalled. It cannot be changed once initialized.

As far as I can tell, this is the first line of my code that's getting
executed, so it seems that either the framework or the compiler is doing
something hidden from me.
This is correct, .NET is build on (D)COM and therefore does call
CoInitializeSecurity itself.
Can anyone explain this and/or suggest a work-around?

As this can happen any time, e.g. when .NET wants to load another
assembly before your call to CoInitializeSecurity, the only workaround I
have found is to provide a "shim" application that just calls
CoInitializeSecurity and then hosts your application using
AppDomain.ExecuteAssembly().

I have tested this in C# implementation and it works, if the
CoInitializeSecurity is implemented inside of he shim's app assembly.

static void main()
{
CoInitializeSecurity(..);
AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
}

To be on the safe side we have decided to build the shim app using raw
unmanaged C++.

HTH,
Andy
 
G

Guest

Andreas Mueller said:
This is correct, .NET is build on (D)COM and therefore does call
CoInitializeSecurity itself.

As this can happen any time, e.g. when .NET wants to load another
assembly before your call to CoInitializeSecurity, the only workaround I
have found is to provide a "shim" application that just calls
CoInitializeSecurity and then hosts your application using
AppDomain.ExecuteAssembly().

I have tested this in C# implementation and it works, if the
CoInitializeSecurity is implemented inside of he shim's app assembly.

static void main()
{
CoInitializeSecurity(..);
AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
}

To be on the safe side we have decided to build the shim app using raw
unmanaged C++.

HTH,
Andy

Thanks, Andy - I was afraid of something like this.

I was trying to avoid being verbose, but just for completeness, here's the
solution structure (simplified):

Solution: sol
(project/assembly) core
core.cs
UI
UI.cs
exe
(references core & UI)
exe.cs

exe.cs contains:

public sealed class Exe {
private static Core _core;
. . .

and the Core constructor starts off with the CoInitializeSecurity.

To follow up on Andy's suggestion, I don't suppose it's possible to mix
languages in the same 'solution', is it?
 
W

Willy Denoyette [MVP]

|
|
| "Andreas Mueller" wrote:
|
| > DrBonzo wrote:
| > > In order to get events back from a DCOM server (an embedded device
running
| > > Windows CE), I seem to have to turn off security for my process. To
do this,
| > > I'm saying:
| > >
| > > int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero,
IntPtr.Zero, 1,
| > > 3, IntPtr.Zero, 0, IntPtr.Zero);
| > >
| > > in the constructor of the first static member of my 'Main' executable
class.
| > > This worked OK in VisualStudio '03 under .NET v1, but no longer works
under
| > > VisualStudio '05 under .NET v2. The 'ret' I now get is 0x80010119,
which
| > > 'Error Lookup's to:
| > >
| > > Security must be initialized before any interfaces are marshalled or
| > > unmarshalled. It cannot be changed once initialized.
| > >
| > > As far as I can tell, this is the first line of my code that's getting
| > > executed, so it seems that either the framework or the compiler is
doing
| > > something hidden from me.
| > This is correct, .NET is build on (D)COM and therefore does call
| > CoInitializeSecurity itself.
| > >
| > > Can anyone explain this and/or suggest a work-around?
| > >
| > >
| >
| > As this can happen any time, e.g. when .NET wants to load another
| > assembly before your call to CoInitializeSecurity, the only workaround I
| > have found is to provide a "shim" application that just calls
| > CoInitializeSecurity and then hosts your application using
| > AppDomain.ExecuteAssembly().
| >
| > I have tested this in C# implementation and it works, if the
| > CoInitializeSecurity is implemented inside of he shim's app assembly.
| >
| > static void main()
| > {
| > CoInitializeSecurity(..);
| > AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
| > }
| >
| > To be on the safe side we have decided to build the shim app using raw
| > unmanaged C++.
| >
| > HTH,
| > Andy
| >
| > --
| > You can email me directly by removing the NOSPAm below
| > (e-mail address removed)
| >
|
| Thanks, Andy - I was afraid of something like this.
|
| I was trying to avoid being verbose, but just for completeness, here's the
| solution structure (simplified):
|
| Solution: sol
| (project/assembly) core
| core.cs
| UI
| UI.cs
| exe
| (references core & UI)
| exe.cs
|
| exe.cs contains:
|
| public sealed class Exe {
| private static Core _core;
| . . .
|
| and the Core constructor starts off with the CoInitializeSecurity.
|
| To follow up on Andy's suggestion, I don't suppose it's possible to mix
| languages in the same 'solution', is it?
|

Did you read my reply?
The default CoInitializeSecurity is called by the CLR at the first call into
COM, that is' when the first RCW get's created. That means that you need to
call CoInitializeSecurity as early as you can, and the earliest is in your
Main entry of the program's exe assembly. Note that setting the security can
only be done and is "per process", not per application domain!!, doing it in
a constructor of a dynamically loaded type make little sense unless you
disregard the error returned by CoInitializeSecurity.

Willy.
 
G

Guest

Willy Denoyette said:
|
|
| "Andreas Mueller" wrote:
|
| > DrBonzo wrote:
| > > In order to get events back from a DCOM server (an embedded device
running
| > > Windows CE), I seem to have to turn off security for my process. To
do this,
| > > I'm saying:
| > >
| > > int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero,
IntPtr.Zero, 1,
| > > 3, IntPtr.Zero, 0, IntPtr.Zero);
| > >
| > > in the constructor of the first static member of my 'Main' executable
class.
| > > This worked OK in VisualStudio '03 under .NET v1, but no longer works
under
| > > VisualStudio '05 under .NET v2. The 'ret' I now get is 0x80010119,
which
| > > 'Error Lookup's to:
| > >
| > > Security must be initialized before any interfaces are marshalled or
| > > unmarshalled. It cannot be changed once initialized.
| > >
| > > As far as I can tell, this is the first line of my code that's getting
| > > executed, so it seems that either the framework or the compiler is
doing
| > > something hidden from me.
| > This is correct, .NET is build on (D)COM and therefore does call
| > CoInitializeSecurity itself.
| > >
| > > Can anyone explain this and/or suggest a work-around?
| > >
| > >
| >
| > As this can happen any time, e.g. when .NET wants to load another
| > assembly before your call to CoInitializeSecurity, the only workaround I
| > have found is to provide a "shim" application that just calls
| > CoInitializeSecurity and then hosts your application using
| > AppDomain.ExecuteAssembly().
| >
| > I have tested this in C# implementation and it works, if the
| > CoInitializeSecurity is implemented inside of he shim's app assembly.
| >
| > static void main()
| > {
| > CoInitializeSecurity(..);
| > AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
| > }
| >
| > To be on the safe side we have decided to build the shim app using raw
| > unmanaged C++.
| >
| > HTH,
| > Andy
| >
| > --
| > You can email me directly by removing the NOSPAm below
| > (e-mail address removed)
| >
|
| Thanks, Andy - I was afraid of something like this.
|
| I was trying to avoid being verbose, but just for completeness, here's the
| solution structure (simplified):
|
| Solution: sol
| (project/assembly) core
| core.cs
| UI
| UI.cs
| exe
| (references core & UI)
| exe.cs
|
| exe.cs contains:
|
| public sealed class Exe {
| private static Core _core;
| . . .
|
| and the Core constructor starts off with the CoInitializeSecurity.
|
| To follow up on Andy's suggestion, I don't suppose it's possible to mix
| languages in the same 'solution', is it?
|

Did you read my reply?
The default CoInitializeSecurity is called by the CLR at the first call into
COM, that is' when the first RCW get's created. That means that you need to
call CoInitializeSecurity as early as you can, and the earliest is in your
Main entry of the program's exe assembly. Note that setting the security can
only be done and is "per process", not per application domain!!, doing it in
a constructor of a dynamically loaded type make little sense unless you
disregard the error returned by CoInitializeSecurity.

Willy.

Yes, Willy, I read your reply, but I'm apparently confused (basically, I'm a
C++ guy and inherited this C# code - this was my legator's 1st C# program & I
think he went a bit 'feature wild' - I see no good reason for this to be a
multi-assembly solution, but I've been too lazy to flatten it). ... so
what's an "RCW"? ... and how does "application domain" relate to the
process? ... maybe I need to spend some more time with the dox.

From experimenting with setting breakpoints, I can assure you that the Core
constructor gets executed before any Main() in the Exe class, so the 1st COM
call is apparently happening before even that, but I don't really understand
where.
 
W

Willy Denoyette [MVP]

|
|
| "Willy Denoyette [MVP]" wrote:
|
| >
| > | > |
| > |
| > | "Andreas Mueller" wrote:
| > |
| > | > DrBonzo wrote:
| > | > > In order to get events back from a DCOM server (an embedded device
| > running
| > | > > Windows CE), I seem to have to turn off security for my process.
To
| > do this,
| > | > > I'm saying:
| > | > >
| > | > > int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero,
| > IntPtr.Zero, 1,
| > | > > 3, IntPtr.Zero, 0, IntPtr.Zero);
| > | > >
| > | > > in the constructor of the first static member of my 'Main'
executable
| > class.
| > | > > This worked OK in VisualStudio '03 under .NET v1, but no longer
works
| > under
| > | > > VisualStudio '05 under .NET v2. The 'ret' I now get is
0x80010119,
| > which
| > | > > 'Error Lookup's to:
| > | > >
| > | > > Security must be initialized before any interfaces are marshalled
or
| > | > > unmarshalled. It cannot be changed once initialized.
| > | > >
| > | > > As far as I can tell, this is the first line of my code that's
getting
| > | > > executed, so it seems that either the framework or the compiler is
| > doing
| > | > > something hidden from me.
| > | > This is correct, .NET is build on (D)COM and therefore does call
| > | > CoInitializeSecurity itself.
| > | > >
| > | > > Can anyone explain this and/or suggest a work-around?
| > | > >
| > | > >
| > | >
| > | > As this can happen any time, e.g. when .NET wants to load another
| > | > assembly before your call to CoInitializeSecurity, the only
workaround I
| > | > have found is to provide a "shim" application that just calls
| > | > CoInitializeSecurity and then hosts your application using
| > | > AppDomain.ExecuteAssembly().
| > | >
| > | > I have tested this in C# implementation and it works, if the
| > | > CoInitializeSecurity is implemented inside of he shim's app
assembly.
| > | >
| > | > static void main()
| > | > {
| > | > CoInitializeSecurity(..);
| > | > AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
| > | > }
| > | >
| > | > To be on the safe side we have decided to build the shim app using
raw
| > | > unmanaged C++.
| > | >
| > | > HTH,
| > | > Andy
| > | >
| > | > --
| > | > You can email me directly by removing the NOSPAm below
| > | > (e-mail address removed)
| > | >
| > |
| > | Thanks, Andy - I was afraid of something like this.
| > |
| > | I was trying to avoid being verbose, but just for completeness, here's
the
| > | solution structure (simplified):
| > |
| > | Solution: sol
| > | (project/assembly) core
| > | core.cs
| > | UI
| > | UI.cs
| > | exe
| > | (references core & UI)
| > | exe.cs
| > |
| > | exe.cs contains:
| > |
| > | public sealed class Exe {
| > | private static Core _core;
| > | . . .
| > |
| > | and the Core constructor starts off with the CoInitializeSecurity.
| > |
| > | To follow up on Andy's suggestion, I don't suppose it's possible to
mix
| > | languages in the same 'solution', is it?
| > |
| >
| > Did you read my reply?
| > The default CoInitializeSecurity is called by the CLR at the first call
into
| > COM, that is' when the first RCW get's created. That means that you need
to
| > call CoInitializeSecurity as early as you can, and the earliest is in
your
| > Main entry of the program's exe assembly. Note that setting the security
can
| > only be done and is "per process", not per application domain!!, doing
it in
| > a constructor of a dynamically loaded type make little sense unless you
| > disregard the error returned by CoInitializeSecurity.
| >
| > Willy.
| >
| >
| >
|
| Yes, Willy, I read your reply, but I'm apparently confused (basically, I'm
a
| C++ guy and inherited this C# code - this was my legator's 1st C# program
& I
| think he went a bit 'feature wild' - I see no good reason for this to be a
| multi-assembly solution, but I've been too lazy to flatten it). ... so
| what's an "RCW"? ... and how does "application domain" relate to the
| process? ... maybe I need to spend some more time with the dox.
|
| From experimenting with setting breakpoints, I can assure you that the
Core
| constructor gets executed before any Main() in the Exe class, so the 1st
COM
| call is apparently happening before even that, but I don't really
understand
| where.

This is not possible normally, the Main function is the first function
called by the CLR after the main assembly has been loaded (the exe). My
guess is that you are loading the assembly (or assemblies) from unmanaged
code through COM interop, that is, your main program is unmanaged (C++ ??)
and your .NET assemblies are registered as COM servers, right?.
If that's the case, it makes no sense to CoInitializeSecurity in an assembly
(it never does), it's too late, it's up to the main program (the unmanaged
code) to initialize COM security before calling into COM. ( that is creating
an instance of Core).

Willy.
 
G

Guest

Willy Denoyette said:
|
|
| "Willy Denoyette [MVP]" wrote:
|
| >
| > | > |
| > |
| > | "Andreas Mueller" wrote:
| > |
| > | > DrBonzo wrote:
| > | > > In order to get events back from a DCOM server (an embedded device
| > running
| > | > > Windows CE), I seem to have to turn off security for my process.
To
| > do this,
| > | > > I'm saying:
| > | > >
| > | > > int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero,
| > IntPtr.Zero, 1,
| > | > > 3, IntPtr.Zero, 0, IntPtr.Zero);
| > | > >
| > | > > in the constructor of the first static member of my 'Main'
executable
| > class.
| > | > > This worked OK in VisualStudio '03 under .NET v1, but no longer
works
| > under
| > | > > VisualStudio '05 under .NET v2. The 'ret' I now get is
0x80010119,
| > which
| > | > > 'Error Lookup's to:
| > | > >
| > | > > Security must be initialized before any interfaces are marshalled
or
| > | > > unmarshalled. It cannot be changed once initialized.
| > | > >
| > | > > As far as I can tell, this is the first line of my code that's
getting
| > | > > executed, so it seems that either the framework or the compiler is
| > doing
| > | > > something hidden from me.
| > | > This is correct, .NET is build on (D)COM and therefore does call
| > | > CoInitializeSecurity itself.
| > | > >
| > | > > Can anyone explain this and/or suggest a work-around?
| > | > >
| > | > >
| > | >
| > | > As this can happen any time, e.g. when .NET wants to load another
| > | > assembly before your call to CoInitializeSecurity, the only
workaround I
| > | > have found is to provide a "shim" application that just calls
| > | > CoInitializeSecurity and then hosts your application using
| > | > AppDomain.ExecuteAssembly().
| > | >
| > | > I have tested this in C# implementation and it works, if the
| > | > CoInitializeSecurity is implemented inside of he shim's app
assembly.
| > | >
| > | > static void main()
| > | > {
| > | > CoInitializeSecurity(..);
| > | > AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
| > | > }
| > | >
| > | > To be on the safe side we have decided to build the shim app using
raw
| > | > unmanaged C++.
| > | >
| > | > HTH,
| > | > Andy
| > | >
| > | > --
| > | > You can email me directly by removing the NOSPAm below
| > | > (e-mail address removed)
| > | >
| > |
| > | Thanks, Andy - I was afraid of something like this.
| > |
| > | I was trying to avoid being verbose, but just for completeness, here's
the
| > | solution structure (simplified):
| > |
| > | Solution: sol
| > | (project/assembly) core
| > | core.cs
| > | UI
| > | UI.cs
| > | exe
| > | (references core & UI)
| > | exe.cs
| > |
| > | exe.cs contains:
| > |
| > | public sealed class Exe {
| > | private static Core _core;
| > | . . .
| > |
| > | and the Core constructor starts off with the CoInitializeSecurity.
| > |
| > | To follow up on Andy's suggestion, I don't suppose it's possible to
mix
| > | languages in the same 'solution', is it?
| > |
| >
| > Did you read my reply?
| > The default CoInitializeSecurity is called by the CLR at the first call
into
| > COM, that is' when the first RCW get's created. That means that you need
to
| > call CoInitializeSecurity as early as you can, and the earliest is in
your
| > Main entry of the program's exe assembly. Note that setting the security
can
| > only be done and is "per process", not per application domain!!, doing
it in
| > a constructor of a dynamically loaded type make little sense unless you
| > disregard the error returned by CoInitializeSecurity.
| >
| > Willy.
| >
| >
| >
|
| Yes, Willy, I read your reply, but I'm apparently confused (basically, I'm
a
| C++ guy and inherited this C# code - this was my legator's 1st C# program
& I
| think he went a bit 'feature wild' - I see no good reason for this to be a
| multi-assembly solution, but I've been too lazy to flatten it). ... so
| what's an "RCW"? ... and how does "application domain" relate to the
| process? ... maybe I need to spend some more time with the dox.
|
| From experimenting with setting breakpoints, I can assure you that the
Core
| constructor gets executed before any Main() in the Exe class, so the 1st
COM
| call is apparently happening before even that, but I don't really
understand
| where.

This is not possible normally, the Main function is the first function
called by the CLR after the main assembly has been loaded (the exe). My
guess is that you are loading the assembly (or assemblies) from unmanaged
code through COM interop, that is, your main program is unmanaged (C++ ??)
and your .NET assemblies are registered as COM servers, right?.
If that's the case, it makes no sense to CoInitializeSecurity in an assembly
(it never does), it's too late, it's up to the main program (the unmanaged
code) to initialize COM security before calling into COM. ( that is creating
an instance of Core).

Willy.

None of the assemblies are registered COM servers, and the whole solution is
pure C# and thus all managed I presume. The core assembly does reference the
type library for the DCOM remote object, though. Since _core is a static
member it's constructor gets invoked before any other method (just like C++,
right?).

But here's something interesting: under VS '03, when I break at the
CoInitializeSecurity call the call stack shows:

location in Core constructor
location of: private static Core _core

but under VS '05 it shows:

location in Core constructor
location of: private static Core _core
[Native to Managed Transition]
[Managed to Native Transition]

I'm guessing this Managed->Native->Managed transition is what's doing some
(D)COM thing, but it's nothing in my code - must be one of: a) something in
the .NET v2 framework, b) something in VS '05, or c) something introduced in
the solution migration from '03 to '05 (I just let VS '05 do its automatic
upgrading). Is there some way in the debugger to get more details about this
transition? I have "Show External Code" turned on already.
 
W

Willy Denoyette [MVP]

|
|
| "Willy Denoyette [MVP]" wrote:
|
| >
| > | > |
| > |
| > | "Willy Denoyette [MVP]" wrote:
| > |
| > | >
| > | > | > | > |
| > | > |
| > | > | "Andreas Mueller" wrote:
| > | > |
| > | > | > DrBonzo wrote:
| > | > | > > In order to get events back from a DCOM server (an embedded
device
| > | > running
| > | > | > > Windows CE), I seem to have to turn off security for my
process.
| > To
| > | > do this,
| > | > | > > I'm saying:
| > | > | > >
| > | > | > > int ret = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero,
| > | > IntPtr.Zero, 1,
| > | > | > > 3, IntPtr.Zero, 0, IntPtr.Zero);
| > | > | > >
| > | > | > > in the constructor of the first static member of my 'Main'
| > executable
| > | > class.
| > | > | > > This worked OK in VisualStudio '03 under .NET v1, but no
longer
| > works
| > | > under
| > | > | > > VisualStudio '05 under .NET v2. The 'ret' I now get is
| > 0x80010119,
| > | > which
| > | > | > > 'Error Lookup's to:
| > | > | > >
| > | > | > > Security must be initialized before any interfaces are
marshalled
| > or
| > | > | > > unmarshalled. It cannot be changed once initialized.
| > | > | > >
| > | > | > > As far as I can tell, this is the first line of my code that's
| > getting
| > | > | > > executed, so it seems that either the framework or the
compiler is
| > | > doing
| > | > | > > something hidden from me.
| > | > | > This is correct, .NET is build on (D)COM and therefore does call
| > | > | > CoInitializeSecurity itself.
| > | > | > >
| > | > | > > Can anyone explain this and/or suggest a work-around?
| > | > | > >
| > | > | > >
| > | > | >
| > | > | > As this can happen any time, e.g. when .NET wants to load
another
| > | > | > assembly before your call to CoInitializeSecurity, the only
| > workaround I
| > | > | > have found is to provide a "shim" application that just calls
| > | > | > CoInitializeSecurity and then hosts your application using
| > | > | > AppDomain.ExecuteAssembly().
| > | > | >
| > | > | > I have tested this in C# implementation and it works, if the
| > | > | > CoInitializeSecurity is implemented inside of he shim's app
| > assembly.
| > | > | >
| > | > | > static void main()
| > | > | > {
| > | > | > CoInitializeSecurity(..);
| > | > | > AppDomain.CurrentDomain.ExecuteAssembly("yourapp.exe");
| > | > | > }
| > | > | >
| > | > | > To be on the safe side we have decided to build the shim app
using
| > raw
| > | > | > unmanaged C++.
| > | > | >
| > | > | > HTH,
| > | > | > Andy
| > | > | >
| > | > | > --
| > | > | > You can email me directly by removing the NOSPAm below
| > | > | > (e-mail address removed)
| > | > | >
| > | > |
| > | > | Thanks, Andy - I was afraid of something like this.
| > | > |
| > | > | I was trying to avoid being verbose, but just for completeness,
here's
| > the
| > | > | solution structure (simplified):
| > | > |
| > | > | Solution: sol
| > | > | (project/assembly) core
| > | > | core.cs
| > | > | UI
| > | > | UI.cs
| > | > | exe
| > | > | (references core & UI)
| > | > | exe.cs
| > | > |
| > | > | exe.cs contains:
| > | > |
| > | > | public sealed class Exe {
| > | > | private static Core _core;
| > | > | . . .
| > | > |
| > | > | and the Core constructor starts off with the CoInitializeSecurity.
| > | > |
| > | > | To follow up on Andy's suggestion, I don't suppose it's possible
to
| > mix
| > | > | languages in the same 'solution', is it?
| > | > |
| > | >
| > | > Did you read my reply?
| > | > The default CoInitializeSecurity is called by the CLR at the first
call
| > into
| > | > COM, that is' when the first RCW get's created. That means that you
need
| > to
| > | > call CoInitializeSecurity as early as you can, and the earliest is
in
| > your
| > | > Main entry of the program's exe assembly. Note that setting the
security
| > can
| > | > only be done and is "per process", not per application domain!!,
doing
| > it in
| > | > a constructor of a dynamically loaded type make little sense unless
you
| > | > disregard the error returned by CoInitializeSecurity.
| > | >
| > | > Willy.
| > | >
| > | >
| > | >
| > |
| > | Yes, Willy, I read your reply, but I'm apparently confused (basically,
I'm
| > a
| > | C++ guy and inherited this C# code - this was my legator's 1st C#
program
| > & I
| > | think he went a bit 'feature wild' - I see no good reason for this to
be a
| > | multi-assembly solution, but I've been too lazy to flatten it). ...
so
| > | what's an "RCW"? ... and how does "application domain" relate to the
| > | process? ... maybe I need to spend some more time with the dox.
| > |
| > | From experimenting with setting breakpoints, I can assure you that the
| > Core
| > | constructor gets executed before any Main() in the Exe class, so the
1st
| > COM
| > | call is apparently happening before even that, but I don't really
| > understand
| > | where.
| >
| > This is not possible normally, the Main function is the first function
| > called by the CLR after the main assembly has been loaded (the exe). My
| > guess is that you are loading the assembly (or assemblies) from
unmanaged
| > code through COM interop, that is, your main program is unmanaged (C++
??)
| > and your .NET assemblies are registered as COM servers, right?.
| > If that's the case, it makes no sense to CoInitializeSecurity in an
assembly
| > (it never does), it's too late, it's up to the main program (the
unmanaged
| > code) to initialize COM security before calling into COM. ( that is
creating
| > an instance of Core).
| >
| > Willy.
| >
| >
| >
|
| None of the assemblies are registered COM servers, and the whole solution
is
| pure C# and thus all managed I presume. The core assembly does reference
the
| type library for the DCOM remote object, though. Since _core is a static
| member it's constructor gets invoked before any other method (just like
C++,
| right?).
|
Ok, I see all C#, and what kind of application is this, Windows forms or
other?
If it's a non-windows application, you should remove the [STAThread]
attribute from Main or change it into [MTAThread], the STAThread attribute
forces the run-time to initialize COM and it's default security before the
main thread starts executing Main, so initializing COM and COM security at
this point is too late. When Main is not attributed or MTAThread attributed,
no such initialization is done before Main enters.
However, if it's a Windows Forms application things are lot more
complicated. Windows Forms requires you to run Main in an STA. The easiest
thing to do is use the process wide security setting through the registry
(run dcomcnfg). If you need to set the security from code you will have to
PInvoke SetBlanket or CoSetProxyBlanket,
AFIIK, this behavior is the same in VS2003 (.NET 1.1), so my guess is that
the STA attribute (supposed it's there) was added when converting your
project to VS2005.



| But here's something interesting: under VS '03, when I break at the
| CoInitializeSecurity call the call stack shows:
|
| location in Core constructor
| location of: private static Core _core
|
| but under VS '05 it shows:
|
| location in Core constructor
| location of: private static Core _core
| [Native to Managed Transition]
| [Managed to Native Transition]
|

This is new in VS2005, native/managed transitions are now tracked.

Willy.
 
G

Guest

Willy Denoyette said:
|
Ok, I see all C#, and what kind of application is this, Windows forms or
other?
If it's a non-windows application, you should remove the [STAThread]
attribute from Main or change it into [MTAThread], the STAThread attribute
forces the run-time to initialize COM and it's default security before the
main thread starts executing Main, so initializing COM and COM security at
this point is too late. When Main is not attributed or MTAThread attributed,
no such initialization is done before Main enters.
However, if it's a Windows Forms application things are lot more
complicated. Windows Forms requires you to run Main in an STA. The easiest
thing to do is use the process wide security setting through the registry
(run dcomcnfg). If you need to set the security from code you will have to
PInvoke SetBlanket or CoSetProxyBlanket,
AFIIK, this behavior is the same in VS2003 (.NET 1.1), so my guess is that
the STA attribute (supposed it's there) was added when converting your
project to VS2005.



| But here's something interesting: under VS '03, when I break at the
| CoInitializeSecurity call the call stack shows:
|
| location in Core constructor
| location of: private static Core _core
|
| but under VS '05 it shows:
|
| location in Core constructor
| location of: private static Core _core
| [Native to Managed Transition]
| [Managed to Native Transition]
|

This is new in VS2005, native/managed transitions are now tracked.

Willy.
Ahhh, the fog is lifting . . .

Yes, it's a Window Forms app and, indeed, before migration, the Core
constructor contained:

System.Threading.Thread.CurrentThread.ApartmentState =
System.Threading.ApartmentState.STA;

which VS '05 didn't allow. I had forgotten this &| thought it not relevant.
Silly me.

I think I'll try Andreas approach, tho, since it's easier for me to
understand.
 

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