Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Hosting / AddInProcess.cs / 1305376 / AddInProcess.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: AddInProcess ** ** Purpose: ** ===========================================================*/ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Runtime.Remoting; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.AddIn.Contract; using System.AddIn.Pipeline; using System.AddIn; using Microsoft.Win32; using System.Diagnostics.Contracts; namespace System.AddIn.Hosting { [Serializable] public enum Platform { Host = 0, AnyCpu = 1, X86 = 2, X64 = 3 } public sealed class AddInProcess { private bool _keepAlive = false; private volatile Process _process = null; private Guid _guid; private Platform _platform; private String _pathToAddInProcess; private readonly Object _processLock = new Object(); // Win32Error NativeErrorCode values const int ERROR_FILE_NOT_FOUND = 2; const int ERROR_ACCESS_DENIED = 5; // Time to wait for the external process to start up and report for duty // Default to 10 seconds private TimeSpan _startupTimeout = new TimeSpan(0, 0, 10); public TimeSpan StartupTimeout { get { return _startupTimeout; } set { if (value.TotalSeconds < 0) throw new ArgumentOutOfRangeException("value"); lock(_processLock) { if(_process == null) { _startupTimeout = value; } else { throw new InvalidOperationException(Res.ProcessAlreadyRunning); } } } } public Platform Platform { get { return _platform; } } // This is used to represent in-process situations private static AddInProcess s_currentProcess = new AddInProcess(true); //// [System.Security.SecurityCritical] [PermissionSet(SecurityAction.Demand, Name="FullTrust")] public AddInProcess() : this(Platform.Host) { } // Overloaded constructor to customize the addin process platform architecture and CLR version. [System.Security.SecurityCritical] [PermissionSet(SecurityAction.Demand, Name="FullTrust")] public AddInProcess(Platform platform) { _platform = platform; // Process the arguments early so we can throw an exception if they were invalid. String folder = RuntimeEnvironment.GetRuntimeDirectory(); String exeName = GetProcessName(platform); _pathToAddInProcess = Path.Combine(folder, exeName); if(!File.Exists(_pathToAddInProcess)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Res.MissingAddInProcessExecutable, _pathToAddInProcess)); } // Eagerly call this. Any MBRO objects created before this initialization // will not be usable. RemotingHelper.InitializeClientChannel(); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "internalOnly", Justification = "Reviewed")] internal AddInProcess(bool internalOnly) { // don't initialize remoting in this version. Therefore we don't need to be Full Trust. } // We should keep processId and Guid in [....]. That is, either // both are null or neither are null. public int ProcessId { // do the same LinkDemand that Process.GetCurrentProcess().Id demands [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] get { lock(_processLock) { if (this == s_currentProcess) return Process.GetCurrentProcess().Id; if (_process == null) return -1; return _process.Id; } } } internal static AddInProcess Current { get { return s_currentProcess; } } internal Guid Guid { get { if (IsCurrentProcess) return Guid.Empty; Start(); return _guid; } } // Flag public bool IsCurrentProcess { get { return this == s_currentProcess; } } public bool KeepAlive { get { return _keepAlive; } set { _keepAlive = value; } } public event EventHandler// ShuttingDown; // Message from the OOP AddInServer indicating there are no addins currently running. internal void SendShuttingDown(CancelEventArgs args) { if (KeepAlive) { args.Cancel = true; return; } ShutDownUnlessCancelled(args); } // This helper method may be called indirectly from user code via Shutdown() // or by a finalizer thread cleaning up the remote process. private void ShutDownUnlessCancelled(CancelEventArgs args) { if (ShuttingDown != null) ShuttingDown(this, args); if (args.Cancel) return; try { lock (_processLock) { // Give addins a chance to clean up by running finalizers // We'll get a remoting exception trying to read the response from this though. AddInServer server = GetAddInServer(); _process = null; _guid = Guid.Empty; // Warning - if this was called from the finalizer thread of AddInProcess, // nothing after this next call will execute, even if it's in a finally block, // due to the calling process being torn down. server.ExitProcess(); } } catch (RemotingException) {} catch (System.Runtime.Serialization.SerializationException) {} } internal AddInServer GetAddInServer() { return RemotingHelper.GetAddInServer(Guid.ToString()); } // // [System.Security.SecurityCritical] public bool Start() { if (this == s_currentProcess) throw new InvalidOperationException(Res.OperationNotValidOnCurrentProcess); if (_process == null) { lock (_processLock) { if (_process == null) { _process = CreateAddInProcess(); // register for SendShuttingDown callbacks AddInServer addInServer = GetAddInServer(); addInServer.Initialize(new EventWorker(this)); } } return true; } return false; } // returns true if it was successfully shut down by this method, false otherwise public bool Shutdown() { if (this == s_currentProcess) throw new InvalidOperationException(Res.OperationNotValidOnCurrentProcess); if (_process == null) return false; CancelEventArgs args = new CancelEventArgs(); ShutDownUnlessCancelled(args); if (args.Cancel) { return false; } return true; } [System.Security.SecurityCritical] private static String GetProcessName(Platform platform) { String exeName; switch(platform) { case Platform.Host: exeName = CurrentlyRunning32Bit() ? "AddInProcess32.exe" : "AddInProcess.exe"; break; case Platform.X86: exeName = "AddInProcess32.exe"; break; case Platform.X64: if(!CurrentlyRunning32Bit() || CurrentlyRunningWow64()) // verify we are on a 64bit os { exeName = "AddInProcess.exe"; } else { throw new InvalidOperationException(Res.Invalid64bitPlatformOn32bitOS); } break; case Platform.AnyCpu: exeName = "AddInProcess.exe"; break; default: throw new ArgumentOutOfRangeException("platform"); } return exeName; } private static bool CurrentlyRunning32Bit() { return System.IntPtr.Size == 4; } // Finds out whether we are in a WOW64 process (i.e. a process is 32bit and the OS is 64bit). // Returns false if we are in a 64bit process or on a 32bit OS. [System.Security.SecurityCritical] private static bool CurrentlyRunningWow64() { bool isWow = false; try { if(!NativeMethods.IsWow64Process(System.Diagnostics.Process.GetCurrentProcess().Handle, ref isWow)) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); // call failed } } catch(EntryPointNotFoundException) { return false; // Call doesn't exist in the current OS, so it means we're not in a wow process. } return isWow; // Return whatever IsWow64Process() returned through the out argument. } //// // // [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] [System.Security.SecurityCritical] private Process CreateAddInProcess() { Process addInProcess = new Process(); Guid guid = Guid.NewGuid(); String args = String.Format(CultureInfo.InvariantCulture, "/guid:{0} /pid:{1}", guid, Process.GetCurrentProcess().Id); addInProcess.StartInfo.CreateNoWindow = true; addInProcess.StartInfo.UseShellExecute = false; addInProcess.StartInfo.Arguments = args; addInProcess.StartInfo.FileName = _pathToAddInProcess; #if _DEBUG String debuggerPath = Environment.GetEnvironmentVariable("COMPLUS_AddInProcessDebugger"); String debuggerArgs = Environment.GetEnvironmentVariable("COMPLUS_AddInProcessDebuggerArgs"); if(!String.IsNullOrEmpty(debuggerPath)) { addInProcess.StartInfo.Arguments = ""; if(!String.IsNullOrEmpty(debuggerArgs)) { addInProcess.StartInfo.Arguments = debuggerArgs + " "; } addInProcess.StartInfo.Arguments += _pathToAddInProcess + " " + args; addInProcess.StartInfo.FileName = debuggerPath; } #endif // wait until it's ready EventWaitHandle readyEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "AddInProcess:" + guid); addInProcess.Start(); bool success = readyEvent.WaitOne(_startupTimeout, false); readyEvent.Close(); if (!success) { // Here's an effort to avoid leaving a half-baked process around if possible. try { addInProcess.Kill(); } catch (Exception) {} throw new InvalidOperationException(Res.CouldNotCreateAddInProcess); } _guid = guid; return addInProcess; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.// // // // // // // // // // //
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FontStyle.cs
- ClientConfigurationHost.cs
- DiscreteKeyFrames.cs
- InvalidWMPVersionException.cs
- TableSectionStyle.cs
- TableItemStyle.cs
- SpellerHighlightLayer.cs
- FormViewCommandEventArgs.cs
- BrowserInteropHelper.cs
- ListViewVirtualItemsSelectionRangeChangedEvent.cs
- QilName.cs
- ContentType.cs
- CheckBoxRenderer.cs
- SqlPersonalizationProvider.cs
- BrowserDefinitionCollection.cs
- ImpersonationContext.cs
- IPEndPointCollection.cs
- TextDocumentView.cs
- TextElementEnumerator.cs
- DragDeltaEventArgs.cs
- KnownColorTable.cs
- KeyValuePairs.cs
- XmlSchemaSubstitutionGroup.cs
- GlyphRunDrawing.cs
- HttpListener.cs
- ContainerControl.cs
- SerializerWriterEventHandlers.cs
- TextAnchor.cs
- ComponentEditorForm.cs
- ThicknessAnimation.cs
- XmlSchemaException.cs
- AmbiguousMatchException.cs
- SqlFlattener.cs
- CopyNamespacesAction.cs
- InputMethod.cs
- Attributes.cs
- DataSourceCacheDurationConverter.cs
- _AutoWebProxyScriptEngine.cs
- ConfigXmlAttribute.cs
- ComponentManagerBroker.cs
- Executor.cs
- DynamicPropertyHolder.cs
- ForeignKeyConstraint.cs
- TextCompositionEventArgs.cs
- RuntimeHelpers.cs
- IgnoreFileBuildProvider.cs
- SQLByteStorage.cs
- PropertyDescriptorCollection.cs
- ConfigurationValue.cs
- Group.cs
- Predicate.cs
- ButtonFlatAdapter.cs
- UnsafeNativeMethods.cs
- CodeSnippetStatement.cs
- Camera.cs
- SingleTagSectionHandler.cs
- GorillaCodec.cs
- PopupRootAutomationPeer.cs
- ContextStack.cs
- AppDomainGrammarProxy.cs
- QuaternionKeyFrameCollection.cs
- nulltextnavigator.cs
- translator.cs
- WebPartDescription.cs
- PersonalizationProvider.cs
- ReferenceEqualityComparer.cs
- ListSortDescription.cs
- PrefixQName.cs
- CompiledQueryCacheKey.cs
- Transaction.cs
- ConfigPathUtility.cs
- TextTreeTextNode.cs
- ipaddressinformationcollection.cs
- ListViewItemSelectionChangedEvent.cs
- TrackBarRenderer.cs
- XmlSchemaSimpleTypeRestriction.cs
- DigitShape.cs
- XmlIncludeAttribute.cs
- DataRelationCollection.cs
- validationstate.cs
- NegotiateStream.cs
- ListViewItemEventArgs.cs
- ControlAdapter.cs
- WindowsTokenRoleProvider.cs
- CodeComment.cs
- Geometry3D.cs
- LoginCancelEventArgs.cs
- SymmetricAlgorithm.cs
- DefaultSerializationProviderAttribute.cs
- DateTimeFormatInfo.cs
- WeakEventTable.cs
- PipelineDeploymentState.cs
- ScriptReferenceEventArgs.cs
- CompilationLock.cs
- DataViewManager.cs
- EventHandlerList.cs
- ServicePoint.cs
- WrappedIUnknown.cs
- SchemaLookupTable.cs
- wgx_exports.cs