Code:
/ 4.0 / 4.0 / 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. // ==++== // // 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
- AvTraceDetails.cs
- HMACSHA1.cs
- SoapObjectReader.cs
- ACL.cs
- SqlProviderServices.cs
- BoundColumn.cs
- SqlRecordBuffer.cs
- ServerReliableChannelBinder.cs
- WebPartConnectionsEventArgs.cs
- CheckBox.cs
- LocalFileSettingsProvider.cs
- QilXmlWriter.cs
- FragmentNavigationEventArgs.cs
- Win32NamedPipes.cs
- DateTimeConverter2.cs
- AuthenticationModuleElement.cs
- WorkflowValidationFailedException.cs
- HttpProfileBase.cs
- ReaderWriterLock.cs
- FormsAuthenticationUserCollection.cs
- FreeFormPanel.cs
- LastQueryOperator.cs
- smtppermission.cs
- AnimatedTypeHelpers.cs
- SecurityContext.cs
- DialogBaseForm.cs
- ObjectConverter.cs
- URLEditor.cs
- NavigationCommands.cs
- VirtualPathUtility.cs
- ScrollItemPatternIdentifiers.cs
- XpsDocument.cs
- HttpCachePolicy.cs
- Activator.cs
- LayoutTable.cs
- ListItemParagraph.cs
- WebBrowserUriTypeConverter.cs
- HandledMouseEvent.cs
- Label.cs
- RefreshPropertiesAttribute.cs
- TextSelectionHighlightLayer.cs
- DocumentViewerHelper.cs
- XmlSerializationReader.cs
- ListControl.cs
- DataGridViewLinkColumn.cs
- FontFamilyIdentifier.cs
- CompareInfo.cs
- RenderDataDrawingContext.cs
- TagMapCollection.cs
- SupportingTokenParameters.cs
- BinaryConverter.cs
- DataTableExtensions.cs
- PropertyDescriptorCollection.cs
- UserNameSecurityTokenProvider.cs
- TextProperties.cs
- ProxySimple.cs
- HtmlUtf8RawTextWriter.cs
- ModelProperty.cs
- WebServicesDescriptionAttribute.cs
- TraceProvider.cs
- RichTextBoxAutomationPeer.cs
- MediaContextNotificationWindow.cs
- _DomainName.cs
- DBSqlParser.cs
- EmissiveMaterial.cs
- TreeView.cs
- ProgressChangedEventArgs.cs
- DbgCompiler.cs
- InvokeGenerator.cs
- FormsAuthenticationConfiguration.cs
- DataGridViewDataConnection.cs
- TextTreeInsertElementUndoUnit.cs
- VarInfo.cs
- AnnotationObservableCollection.cs
- UserControlAutomationPeer.cs
- IIS7ConfigurationLoader.cs
- ToolStripItem.cs
- ControlBuilderAttribute.cs
- DataServiceRequestOfT.cs
- BitmapVisualManager.cs
- HostProtectionException.cs
- PingReply.cs
- ReaderContextStackData.cs
- ErrorWebPart.cs
- TreeViewItemAutomationPeer.cs
- NetworkCredential.cs
- Ipv6Element.cs
- ObjectManager.cs
- BindValidationContext.cs
- HighContrastHelper.cs
- OpCopier.cs
- EdmConstants.cs
- AccessText.cs
- ReaderWriterLockWrapper.cs
- XmlNamespaceManager.cs
- ImportContext.cs
- Bitmap.cs
- WindowsGraphics.cs
- XslException.cs
- RelatedCurrencyManager.cs