protected static Process Start <T>(string executableFileName, T parameter, SubprocessConfiguration configuration, Uri address) { var configPath = Path.Combine(TempDir, "C" + Interlocked.Increment(ref _AssemblyCount) + ".T" + DateTime.Now.Ticks + ".config"); var configDocument = new ConfigXmlDocument(); AppendConfig(configDocument, ConfigurationUserLevel.None); AppendConfig(configDocument, ConfigurationUserLevel.PerUserRoaming); AppendConfig(configDocument, ConfigurationUserLevel.PerUserRoamingAndLocal); if (configuration.ShouldCreateConfig) { if (configDocument.DocumentElement == null) { configDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n<configuration></configuration>"); } configDocument.Save(configPath); configuration.RaiseConfigCreated(new ConfigCreatedEventArgs(configPath)); } else if (configDocument.DocumentElement != null) { configDocument.Save(configPath); } var psi = new ProcessStartInfo(executableFileName); var spp = new SubprocessArgument <T>(); spp.TemporaryDirectory = TempDir; spp.Address = address; spp.Parameter = parameter; spp.ParentProcessId = Process.GetCurrentProcess().Id; spp.IsStandalone = configuration.IsStandalone; if (configuration.AttachDebugger) { spp.DebuggerInfo = DebuggerInfoProvider.GetCurrent(); } var argFilePath = Path.Combine(TempDir, "A" + Interlocked.Increment(ref _AssemblyCount) + ".T" + DateTime.Now.Ticks + ".xml"); using (var fs = new FileStream(argFilePath, FileMode.Create)) { new DataContractSerializer(spp.GetType()).WriteObject(fs, spp); } psi.Arguments = configDocument.DocumentElement != null ? (argFilePath + " \"" + configPath + "\"") : argFilePath; var p = Process.Start(psi); return(p); }
/// <summary> /// アプリケーション定義のパラメーターとエントリポイントを指定して新しいサブプロセスを起動します。 /// </summary> /// <typeparam name="TParameter">サブプロセスに渡されるアプリケーション定義のパラメーターの型。</typeparam> /// <param name="method">サブプロセスの起動後に呼び出されるパブリックな静的メソッド。</param> /// <param name="parameter">サブプロセスに渡されるアプリケーション定義のパラメーター。</param> /// <param name="configuration">サブプロセスの起動設定。</param> /// <returns>サブプロセスの起動タスク。</returns> private Task <Subprocess> StartNewCore <TParameter>(MethodInfo method, TParameter parameter, SubprocessConfiguration configuration) { var conf = configuration ?? new SubprocessConfiguration(); return(OpenTask.ContinueWith(open => { if (!open.IsCompleted) { throw new InvalidOperationException(Resources.FailedToInitializeWcfServiceHost, open.Exception); } var tk = Tuple.Create(typeof(ServiceSubprocessHost <TService>), typeof(TParameter), conf.IsSTAThread, conf.IsWindowsApplication); var asf = GetDynamicEntryPoint( tk, new ServiceSubprocessEntryPointBuilder( typeof(SubprocessArgument <TParameter>), conf.IsSTAThread, conf.IsWindowsApplication, _StartInfoType.MakeGenericType(typeof(TParameter)).GetConstructors()[0], method)); var p = Start(asf, parameter, conf, _Address); lock (InstanceLock) { if (_Clients == null) { _Clients = new Dictionary <int, Subprocess>(); } var dsi = new Subprocess(p); dsi.Exited += Process_Exited; return _Clients[p.Id] = dsi; } })); }
/// <summary> /// アプリケーション定義のパラメーターとエントリポイントを指定して新しいサブプロセスを起動します。 /// </summary> /// <typeparam name="TParameter">サブプロセスに渡されるアプリケーション定義のパラメーターの型。</typeparam> /// <param name="entryPoint">サブプロセスの起動後に呼び出されるパブリックな静的メソッド。</param> /// <param name="parameter">サブプロセスに渡されるアプリケーション定義のパラメーター。</param> /// <param name="configuration">サブプロセスの起動設定。</param> /// <returns>サブプロセスの起動タスク。</returns> public Task <Subprocess> StartNew <TParameter>(Action <IServiceSubprocessStartInfo <TService, TParameter> > entryPoint, TParameter parameter, SubprocessConfiguration configuration = null) { ThrowIfInvalidEntryPoint(entryPoint); return(StartNewCore(entryPoint.GetInvocationList()[0].Method, parameter, configuration)); }
/// <summary> /// 指定したエントリポイントで新しいサブプロセスを起動します。 /// </summary> /// <param name="entryPoint">サブプロセスの起動後に呼び出されるパブリックな静的メソッド。</param> /// <param name="configuration">サブプロセスの起動設定。</param> /// <returns>サブプロセスの起動タスク。</returns> public Task <Subprocess> StartNew(Action <IServiceSubprocessStartInfo <TService> > entryPoint, SubprocessConfiguration configuration = null) { ThrowIfInvalidEntryPoint(entryPoint); return(StartNewCore <object>(entryPoint.GetInvocationList()[0].Method, null, configuration)); }
/// <summary> /// アプリケーション定義のパラメーターとエントリポイントを指定して新しいサブプロセスを起動します。 /// </summary> /// <typeparam name="TParameter">サブプロセスに渡されるアプリケーション定義のパラメーターの型。</typeparam> /// <param name="entryPoint">サブプロセスの起動後に呼び出されるパブリックな静的メソッド。</param> /// <param name="parameter">サブプロセスに渡されるアプリケーション定義のパラメーター。</param> /// <param name="configuration">サブプロセスの起動設定。</param> /// <returns>サブプロセスの起動タスク。</returns> public Task <DuplexSubprocess <TCallback> > StartNew <TParameter>(Action <IDuplexSubprocessStartInfo <TService, TCallback, TParameter> > entryPoint, TParameter parameter, SubprocessConfiguration configuration = null) { ThrowIfInvalidEntryPoint(entryPoint); return(StartNewCore(entryPoint.Method, parameter, configuration)); }
/// <summary> /// 指定したエントリポイントで新しいサブプロセスを起動します。 /// </summary> /// <param name="entryPoint">サブプロセスの起動後に呼び出されるパブリックな静的メソッド。</param> /// <param name="configuration">サブプロセスの起動設定。</param> /// <returns>サブプロセスの起動タスク。</returns> public Task <DuplexSubprocess <TCallback> > StartNew(Action <IDuplexSubprocessStartInfo <TService, TCallback> > entryPoint, SubprocessConfiguration configuration = null) { ThrowIfInvalidEntryPoint(entryPoint); return(StartNewCore <object>(entryPoint.Method, null, configuration)); }
/// <summary> /// アプリケーション定義のパラメーターとエントリポイントを指定して新しいサブプロセスを起動します。 /// </summary> /// <typeparam name="TParameter">サブプロセスに渡されるアプリケーション定義のパラメーターの型。</typeparam> /// <param name="method">サブプロセスの起動後に呼び出されるパブリックな静的メソッド。</param> /// <param name="parameter">サブプロセスに渡されるアプリケーション定義のパラメーター。</param> /// <param name="configuration">サブプロセスの起動設定。</param> /// <returns>サブプロセスの起動タスク。</returns> private Task <Subprocess> StartNewCore <TParameter>(MethodInfo method, TParameter parameter, SubprocessConfiguration configuration) { var conf = configuration ?? new SubprocessConfiguration(); return(Task.Run(() => { var tk = Tuple.Create(typeof(SubprocessHost), typeof(TParameter), conf.IsSTAThread, conf.IsWindowsApplication); var asf = GetDynamicEntryPoint( tk, new SubprocessEntryPointBuilder( typeof(SubprocessArgument <TParameter>), conf.IsSTAThread, conf.IsWindowsApplication, method)); var p = Start(asf, parameter, conf, null); lock (InstanceLock) { if (_Clients == null) { _Clients = new Dictionary <int, Subprocess>(); } var dsi = new Subprocess(p); dsi.Exited += Process_Exited; return _Clients[p.Id] = dsi; } })); }