Ah, I'm an idiot. CoInitializeSecurity is per-process, not per thread. I think this problem is related to the one described at http://lists.ironpython.com/pipermail/users-ironpython.com/2008-April/006941.html. If that's so, it suggests that loading the assembly manually with Assembly.Load instead of "require" - being sure to do whatever it takes to avoid triggering the AssemblyResolve event - might fix the problem.
Do you need to be in the MTA apartment? If so, you'd also need to create a new MTA thread or you'd need to start ir.exe with "-X:MTA". From: ironruby-core-boun...@rubyforge.org [mailto:ironruby-core-boun...@rubyforge.org] On Behalf Of Orion Edwards Sent: Wednesday, August 12, 2009 8:20 PM To: ironruby-core@rubyforge.org Subject: Re: [Ironruby-core] COM security question Ack. I've worked around the problem by creating a custom version of ir.exe which calls CoInitializeSecurity. It would be great if there were a less hacky way of doing this (that I wouldn't have to re-do when ironruby 1.0 comes out), but yeah :-( Here's the code namespace sec_ir { class CoInitializeRubyConsoleHost : ConsoleHost { [RubyStackTraceHidden, MTAThread] static int Main( string[] args ) { ComHelpers.CoInitializeSecurity(); SetHome(); return new CoInitializeRubyConsoleHost().Run(args); } // -------------------------------------------------------------------- protected override CommandLine CreateCommandLine() { return new RubyCommandLine(); } protected override Microsoft.Scripting.Hosting.LanguageSetup CreateLanguageSetup() { return Ruby.CreateRubySetup(); } protected override OptionsParser CreateOptionsParser() { return new RubyOptionsParser(); } protected override Type Provider { get { return typeof(RubyContext); } } // -------------------------------------------------------------------- static void SetHome() { try { var platform = PlatformAdaptationLayer.Default; var homeDirectory = RubyUtils.GetHomeDirectory(platform); platform.SetEnvironmentVariable("HOME", homeDirectory); } catch( SecurityException exception ) { if( exception.PermissionType != typeof(EnvironmentPermission) ) throw; } } } } static class ComHelpers { /// <summary> /// Call CoInitializeSecurity with dwImpLevel set to Impersonate. /// </summary> public static void CoInitializeSecurity() { CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, (uint)RpcAuthnLevel.PktPrivacy, (uint)RpcImpLevel.Impersonate, IntPtr.Zero, (uint)EoAuthnCap.DynamicCloaking, IntPtr.Zero); } /// <summary> /// Define RPC_C_AUTHN_LEVEL_ constants /// </summary> enum RpcAuthnLevel { Default = 0, None, Connect, Call, Pkt, PktIntegrity, PktPrivacy } /// <summary> /// Define RPC_C_IMP_LEVEL_ constants /// </summary> enum RpcImpLevel { Default = 0, Anonymous, Identify, Impersonate, Delegate } /// <summary> /// Define EOAC_ constants /// </summary> enum EoAuthnCap { None = 0x0000, MutualAuth = 0x0001, StaticCloaking = 0x0020, DynamicCloaking = 0x0040, AnyAuthority = 0x0080, MakeFullSIC = 0x0100, Default = 0x0800, SecureRefs = 0x0002, AccessControl = 0x0004, AppID = 0x0008, Dynamic = 0x0010, RequireFullSIC = 0x0200, AutoImpersonate = 0x0400, NoCustomMarshal = 0x2000, DisableAAA = 0x1000 } // Create the call with PreserveSig:=FALSE so the COM InterOp // layer will perform the error checking and throw an // exception instead of returning an HRESULT. // [DllImport("Ole32.dll", ExactSpelling = true, EntryPoint = "CoInitializeSecurity", CallingConvention = CallingConvention.StdCall, SetLastError = false, PreserveSig = false)] static extern void CoInitializeSecurity( IntPtr pVoid, int cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1, uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthList, uint dwCapabilities, IntPtr pReserved3 ); }
_______________________________________________ Ironruby-core mailing list Ironruby-core@rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core