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
- SystemWebCachingSectionGroup.cs
- ValueQuery.cs
- Vector.cs
- RemotingAttributes.cs
- SID.cs
- Matrix3DStack.cs
- WindowsListViewItemCheckBox.cs
- XPathExpr.cs
- Query.cs
- CompositeDataBoundControl.cs
- BinarySecretKeyIdentifierClause.cs
- ErrorHandler.cs
- Normalization.cs
- SelectionPatternIdentifiers.cs
- ConfigurationConverterBase.cs
- RadioButtonAutomationPeer.cs
- RNGCryptoServiceProvider.cs
- UnsafeNativeMethods.cs
- URLAttribute.cs
- DropAnimation.xaml.cs
- BindableAttribute.cs
- ValidationSettings.cs
- DetailsViewInsertEventArgs.cs
- ColorTranslator.cs
- IpcClientManager.cs
- DesignerSerializerAttribute.cs
- MultipleViewProviderWrapper.cs
- WindowsAuthenticationModule.cs
- ImageSourceConverter.cs
- HttpEncoder.cs
- UshortList2.cs
- GetLastErrorDetailsRequest.cs
- CompilerState.cs
- ObjectQuery_EntitySqlExtensions.cs
- AssemblyName.cs
- RemotingAttributes.cs
- SurrogateEncoder.cs
- webeventbuffer.cs
- ContentControl.cs
- TextEncodedRawTextWriter.cs
- SignatureToken.cs
- SessionSymmetricTransportSecurityProtocolFactory.cs
- Message.cs
- RestClientProxyHandler.cs
- FixedDocument.cs
- Pkcs9Attribute.cs
- NativeCompoundFileAPIs.cs
- DispatcherExceptionEventArgs.cs
- SqlProvider.cs
- UnsafeNativeMethods.cs
- DoubleKeyFrameCollection.cs
- AttachedPropertyBrowsableWhenAttributePresentAttribute.cs
- AppearanceEditorPart.cs
- ApplicationGesture.cs
- BitSet.cs
- PropertyChangedEventArgs.cs
- IISMapPath.cs
- RegexCompilationInfo.cs
- BrowserTree.cs
- Int32Animation.cs
- MoveSizeWinEventHandler.cs
- ToolBarButtonClickEvent.cs
- CrossAppDomainChannel.cs
- MultipleViewProviderWrapper.cs
- GridViewColumnHeader.cs
- ClientCredentials.cs
- GeneralTransformGroup.cs
- DeclarativeCatalogPartDesigner.cs
- FormViewPagerRow.cs
- XmlSchemaSimpleContentExtension.cs
- WindowsFont.cs
- ComponentRenameEvent.cs
- Track.cs
- UpDownBase.cs
- DispatcherTimer.cs
- TextChange.cs
- StylusPointPropertyInfoDefaults.cs
- Mouse.cs
- ServiceModelPerformanceCounters.cs
- Permission.cs
- RoutedEventValueSerializer.cs
- ObjectViewListener.cs
- Options.cs
- WebHeaderCollection.cs
- ConfigurationConverterBase.cs
- EntityContainerEmitter.cs
- InnerItemCollectionView.cs
- SqlWriter.cs
- UserPersonalizationStateInfo.cs
- MappedMetaModel.cs
- EndpointPerformanceCounters.cs
- TimelineClockCollection.cs
- SafeMILHandle.cs
- UnrecognizedAssertionsBindingElement.cs
- HttpRuntimeSection.cs
- CalendarTable.cs
- HitTestParameters3D.cs
- ParallelTimeline.cs
- ObjectDataSourceFilteringEventArgs.cs
- CursorConverter.cs