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
- Compilation.cs
- TextBoxDesigner.cs
- WinFormsSpinner.cs
- CachedTypeface.cs
- XamlStream.cs
- LogSwitch.cs
- TickBar.cs
- DataGridViewColumnEventArgs.cs
- MultiPartWriter.cs
- BamlCollectionHolder.cs
- MulticastNotSupportedException.cs
- _NetRes.cs
- _FtpDataStream.cs
- ParserContext.cs
- _ConnectionGroup.cs
- ModuleBuilder.cs
- ProgressBar.cs
- ListBindingHelper.cs
- ColorConvertedBitmapExtension.cs
- MD5.cs
- Utils.cs
- ResumeStoryboard.cs
- DSGeneratorProblem.cs
- AppDomainManager.cs
- Activation.cs
- NaturalLanguageHyphenator.cs
- KnownTypes.cs
- ReachVisualSerializerAsync.cs
- IInstanceContextProvider.cs
- GeneralTransform2DTo3D.cs
- MarkerProperties.cs
- SolidColorBrush.cs
- JournalEntryStack.cs
- DataFormats.cs
- EntityProviderServices.cs
- TextLineResult.cs
- WindowsRegion.cs
- AsyncCompletedEventArgs.cs
- XsdBuildProvider.cs
- CursorInteropHelper.cs
- DiagnosticSection.cs
- ContentDisposition.cs
- ConstantCheck.cs
- CustomDictionarySources.cs
- DataSourceXmlAttributeAttribute.cs
- GraphicsState.cs
- LogReservationCollection.cs
- BookmarkScopeInfo.cs
- EntityDataSourceDataSelectionPanel.designer.cs
- BackoffTimeoutHelper.cs
- BaseUriHelper.cs
- XmlCharCheckingWriter.cs
- XamlFrame.cs
- DynamicQueryableWrapper.cs
- TextServicesLoader.cs
- Stacktrace.cs
- X509AudioLogo.cs
- Rotation3DAnimation.cs
- HtmlInputControl.cs
- KerberosRequestorSecurityToken.cs
- ReservationCollection.cs
- StringResourceManager.cs
- CodeAssignStatement.cs
- BamlVersionHeader.cs
- FontSizeConverter.cs
- ExtentKey.cs
- FtpWebResponse.cs
- HiddenField.cs
- IconConverter.cs
- ObjectListCommandEventArgs.cs
- ToolStripDropDownButton.cs
- ConfigXmlCDataSection.cs
- SystemIcmpV6Statistics.cs
- TextSchema.cs
- WindowVisualStateTracker.cs
- AvTrace.cs
- LeaseManager.cs
- XmlSerializableServices.cs
- XmlTextAttribute.cs
- UnitControl.cs
- UnsafeNativeMethods.cs
- Point.cs
- Rfc2898DeriveBytes.cs
- ToolStripItemTextRenderEventArgs.cs
- PriorityBindingExpression.cs
- UnaryNode.cs
- SchemaImporterExtension.cs
- Size3D.cs
- DependencyPropertyChangedEventArgs.cs
- LicenseContext.cs
- PathGeometry.cs
- HtmlTableRowCollection.cs
- SqlProcedureAttribute.cs
- SoapIgnoreAttribute.cs
- SafeRightsManagementEnvironmentHandle.cs
- TcpConnectionPoolSettingsElement.cs
- ResourcesGenerator.cs
- CategoryAttribute.cs
- StringExpressionSet.cs
- StylusPointPropertyInfoDefaults.cs