public AddInActivatorProcess(string friendlyName, bool redirectOutput, AddInDomainSetup addInDomainSetup)
        {
            this._friendlyName         = friendlyName;
            this._redirectOutput       = redirectOutput;
            this._addInDomainSetup     = addInDomainSetup;
            this._assemblyFile         = AddInActivatorHostAssemblyCompiler.CreateRemoteHostAssembly(friendlyName, addInDomainSetup);
            this._addInDomainSetupFile = Path.Combine(addInDomainSetup.TempFilesDirectory, string.Format(ConfigFileStringFormat, friendlyName));
            this._addInDomainLogFile   = Path.Combine(addInDomainSetup.TempFilesDirectory, string.Format(LogFileStringFormat, friendlyName));

            ProcessStartInfo processStartInfo = new ProcessStartInfo();

            processStartInfo.CreateNoWindow         = true;
            processStartInfo.ErrorDialog            = false;
            processStartInfo.FileName               = this._assemblyFile;
            processStartInfo.RedirectStandardError  = true;
            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.UseShellExecute        = false;
            processStartInfo.Verb             = "runas";
            processStartInfo.WorkingDirectory = this._addInDomainSetup.WorkingDirectory;

            if (this._addInDomainSetup.EnvironmentVariables != null)
            {
                foreach (KeyValuePair <string, string> item in this._addInDomainSetup.EnvironmentVariables)
                {
                    processStartInfo.EnvironmentVariables[item.Key] = item.Value;
                }
            }

            this._process                     = new Process();
            this._process.StartInfo           = processStartInfo;
            this._process.OutputDataReceived += this.OnProcessDataReceived;
            this._process.ErrorDataReceived  += this.OnProcessDataReceived;
            this._process.Exited             += this.OnProcessExited;
            this._process.EnableRaisingEvents = true;
        }
        /// <summary>
        /// Static Method WriteSetupFile.
        /// </summary>
        /// <param name="addInDomainSetup">Instance of AddInDomainSetup.</param>
        /// <param name="filename">Setup file name.</param>
        internal static void WriteSetupFile(AddInDomainSetup addInDomainSetup, string filename)
        {
            BinaryFormatter formatter = new BinaryFormatter();

            using (FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                formatter.Serialize(fileStream, addInDomainSetup);
            }
        }
        public static string CreateRemoteHostAssembly(string friendlyName, AddInDomainSetup addInDomainSetup)
        {
            if (!Directory.Exists(addInDomainSetup.TempFilesDirectory))
            {
                Directory.CreateDirectory(addInDomainSetup.TempFilesDirectory);
            }

            ////Dictionary<string, string> providerOptions = new Dictionary<string, string> { { "CompilerVersion", "v2.0" } };

            CompilerResults results = null;

            List <string> compilerArgs = new List <string> {
                AddInPlatformTarget.GetPlatformTargetCompilerArgument(addInDomainSetup.Platform)
            };

#if DEBUG
            compilerArgs.Add("/define:DEBUG");
#endif
            CompilerParameters compilerParameters = new CompilerParameters();
            compilerParameters.CompilerOptions    = string.Join(" ", compilerArgs.ToArray());
            compilerParameters.GenerateExecutable = true;
            compilerParameters.GenerateInMemory   = false;
            compilerParameters.OutputAssembly     = Path.Combine(addInDomainSetup.TempFilesDirectory, string.Format(OutputAssemblyFileStringFormat, friendlyName));
            compilerParameters.ReferencedAssemblies.AddRange(ReferencedAssemblies);

            string assemblySource = DevLib.AddIn.Properties.Resources.Program.Replace("$[AddInActivatorHostTypeName]", typeof(AddInActivatorHost).AssemblyQualifiedName).Replace("$[AddInAssemblyName]", typeof(AddInActivatorHost).Assembly.FullName);

            ////using (CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions))
            using (CSharpCodeProvider provider = new CSharpCodeProvider())
            {
                results = provider.CompileAssemblyFromSource(compilerParameters, assemblySource);
            }

            if (results.Errors.HasWarnings)
            {
                AddInAssemblyCompilerException addInAssemblyCompilerException = new AddInAssemblyCompilerException("Succeeded to compile assembly for AddInDomain with warnings.", results.Errors);

                Debug.WriteLine(string.Format(AddInConstants.WarningStringFormat, "DevLib.AddIn.AddInActivatorHostAssemblyCompiler.CreateRemoteHostAssembly", results.ToString(), addInAssemblyCompilerException.ToString(), results.Output.ToString(), string.Empty));
            }

            if (results.Errors.HasErrors)
            {
                AddInAssemblyCompilerException addInAssemblyCompilerException = new AddInAssemblyCompilerException("Failed to compile assembly for AddInDomain due to compiler errors.", results.Errors);

                Debug.WriteLine(string.Format(AddInConstants.ExceptionStringFormat, "DevLib.AddIn.AddInActivatorHostAssemblyCompiler.CreateRemoteHostAssembly", results.ToString(), addInAssemblyCompilerException.ToString(), results.Output.ToString(), string.Empty));

                throw addInAssemblyCompilerException;
            }

            return(results.PathToAssembly);
        }
        public void Start()
        {
            this.CheckDisposed();

            this.DisposeClient();

            string guid = Guid.NewGuid().ToString();
            bool   isCreated;

            using (EventWaitHandle serverStartedHandle = new EventWaitHandle(false, EventResetMode.ManualReset, string.Format(AddInActivatorHost.AddInDomainEventNameStringFormat, guid), out isCreated))
            {
                if (!isCreated)
                {
                    throw new Exception(AddInConstants.EventHandleAlreadyExistedException);
                }

                string addInDomainAssemblyPath = typeof(AddInActivatorProcess).Assembly.Location;

                AddInDomainSetup.WriteSetupFile(this._addInDomainSetup, this._addInDomainSetupFile);

                //// args[0] = AddInDomain assembly path
                //// args[1] = GUID
                //// args[2] = PID
                //// args[3] = AddInDomainSetup file
                //// args[4] = Redirect output or not

                this._process.StartInfo.Arguments = string.Format("\"{0}\" {1} {2} \"{3}\" {4}", addInDomainAssemblyPath, guid, Process.GetCurrentProcess().Id.ToString(), this._addInDomainSetupFile, this._redirectOutput.ToString());
                this.IsRunning = this._process.Start();

                if (!this.IsRunning)
                {
                    Debug.WriteLine(string.Format(AddInConstants.ProcessStartExceptionStringFormat, this._process.StartInfo.FileName));
                    throw new Exception(string.Format(AddInConstants.ProcessStartExceptionStringFormat, this._process.StartInfo.FileName));
                }

                if (!serverStartedHandle.WaitOne(this._addInDomainSetup.ProcessStartTimeout))
                {
                    Debug.WriteLine(AddInConstants.ProcessStartTimeoutException);
                    throw new Exception(AddInConstants.ProcessStartTimeoutException);
                }

                this._process.BeginOutputReadLine();
                this._process.BeginErrorReadLine();
                this._process.PriorityClass = this._addInDomainSetup.ProcessPriority;
                this._addInActivatorClient  = new AddInActivatorClient(guid, this._addInDomainSetup);
                this.RaiseEvent(this.Attached);
            }
        }
Exemple #5
0
        public AddInActivatorClient(string guid, AddInDomainSetup addInDomainSetup)
        {
            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

            serverProvider.TypeFilterLevel = addInDomainSetup.TypeFilterLevel;

            BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

            Hashtable properties = new Hashtable();

            properties[AddInConstants.KeyIpcPortName]    = string.Format(AddInActivatorHost.AddInClientChannelNameStringFormat, guid);
            properties[AddInConstants.KeyIpcChannelName] = string.Format(AddInActivatorHost.AddInClientChannelNameStringFormat, guid);

            this._ipcChannel = new IpcChannel(properties, clientProvider, serverProvider);
            ChannelServices.RegisterChannel(this._ipcChannel, false);

            this._addInActivator = (AddInActivator)Activator.GetObject(typeof(AddInActivator), string.Format(AddInConstants.IpcUrlStringFormat, string.Format(AddInActivatorHost.AddInServerChannelNameStringFormat, guid), AddInActivatorHost.AddInActivatorName));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AddInActivatorHost" /> class.
        /// </summary>
        /// <param name="guid">Guid string.</param>
        /// <param name="processId">Process Id.</param>
        /// <param name="addInDomainSetup">Instance of AddInDomainSetup.</param>
        public AddInActivatorHost(string guid, int processId, AddInDomainSetup addInDomainSetup)
        {
            try
            {
                Directory.SetCurrentDirectory(addInDomainSetup.DllDirectory);
            }
            catch (Exception e)
            {
                InternalLogger.Log(e);
                throw;
            }

            this._process = Process.GetProcessById(processId);

            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

            serverProvider.TypeFilterLevel = addInDomainSetup.TypeFilterLevel;

            BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

            Hashtable properties = new Hashtable();

            properties[AddInConstants.KeyIpcPortName]    = string.Format(AddInServerChannelNameStringFormat, guid);
            properties[AddInConstants.KeyIpcChannelName] = string.Format(AddInServerChannelNameStringFormat, guid);

            this._ipcChannel = new IpcChannel(properties, clientProvider, serverProvider);
            ChannelServices.RegisterChannel(this._ipcChannel, false);

            RemotingConfiguration.RegisterWellKnownServiceType(typeof(AddInActivator), AddInActivatorName, WellKnownObjectMode.Singleton);

            bool isCreated;

            using (EventWaitHandle serverStartedHandle = new EventWaitHandle(false, EventResetMode.ManualReset, string.Format(AddInDomainEventNameStringFormat, guid), out isCreated))
            {
                if (isCreated)
                {
                    throw new Exception(AddInConstants.EventHandleNotExist);
                }

                serverStartedHandle.Set();
            }
        }
Exemple #7
0
        /// <summary>
        /// Runs AddInActivatorHost until the parent process exits.
        /// </summary>
        /// <param name="args">Command line arguments.</param>
        public static void Run(string[] args)
        {
            //// args[0] = AddInDomain assembly path
            //// args[1] = GUID
            //// args[2] = PID
            //// args[3] = AddInDomainSetup file
            //// args[4] = Redirect output or not

            if (args.Length < 4)
            {
                return;
            }

            string           friendlyName     = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);
            string           guid             = args[1];
            int              processId        = int.Parse(args[2]);
            AddInDomainSetup addInDomainSetup = AddInDomainSetup.ReadSetupFile(args[3]);
            AppDomain        appDomain        = AppDomain.CreateDomain(friendlyName, addInDomainSetup.Evidence, addInDomainSetup.AppDomainSetup);
            Type             type             = Assembly.GetEntryAssembly().GetType("DevLib.AddIn.AssemblyResolver");

            if (type == null)
            {
                throw new TypeLoadException(AddInConstants.AssemblyResolverException);
            }

            // add AddInDomain assembly to resolver
            if (addInDomainSetup.ExternalAssemblies == null)
            {
                addInDomainSetup.ExternalAssemblies = new Dictionary <AssemblyName, string>();
            }

            addInDomainSetup.ExternalAssemblies[typeof(AddInActivatorHost).Assembly.GetName()] = typeof(AddInActivatorHost).Assembly.Location;

            object resolver = appDomain.CreateInstanceFromAndUnwrap(
                type.Assembly.Location,
                type.FullName,
                false,
                BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance,
                null,
                new[] { addInDomainSetup.ExternalAssemblies },
                null,
                null,
                null);

            type.InvokeMember("Mount", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, resolver, null);

            AddInActivatorHost host = (AddInActivatorHost)appDomain.CreateInstanceFromAndUnwrap(
                typeof(AddInActivatorHost).Assembly.Location,
                typeof(AddInActivatorHost).FullName,
                false,
                BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance,
                null,
                new object[] { guid, processId, addInDomainSetup },
                null,
                null,
                null);

            host.WaitForExit();

            type.InvokeMember("Unmount", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, resolver, null);

            // if parent process (host) finishes, the current process must end
            Environment.Exit(0);
        }
Exemple #8
0
 /// <summary>
 /// Constructor of AddInDomainEventArgs.
 /// </summary>
 /// <param name="friendlyName"></param>
 /// <param name="addInTypeName"></param>
 /// <param name="addInObject"></param>
 /// <param name="addInDomainSetupInfo"></param>
 /// <param name="processInfo"></param>
 public AddInDomainEventArgs(string friendlyName, string addInTypeName, object addInObject, AddInDomainSetup addInDomainSetupInfo, AddInActivatorProcessInfo processInfo)
 {
     this.FriendlyName         = friendlyName;
     this.AddInTypeName        = addInTypeName;
     this.AddInObject          = addInObject;
     this.AddInDomainSetupInfo = addInDomainSetupInfo;
     this.ProcessInfo          = processInfo;
 }
Exemple #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AddInDomain" /> class.
 /// </summary>
 /// <param name="friendlyName">The friendly name of the AddInDomain.</param>
 /// <param name="showRedirectConsoleOutput">Whether the output of AddInActivatorProcess is shown in current console.</param>
 /// <param name="addInDomainSetup">Additional settings for creating AddInDomain.</param>
 public AddInDomain(string friendlyName = null, bool showRedirectConsoleOutput = true, AddInDomainSetup addInDomainSetup = null)
 {
     this.FriendlyName         = string.IsNullOrEmpty(friendlyName) ? AddInConstants.DefaultFriendlyName : friendlyName;
     this.AddInDomainSetupInfo = addInDomainSetup ?? new AddInDomainSetup();
     this.RedirectOutput       = showRedirectConsoleOutput;
     this.CreateAddInActivatorProcess();
 }