実行環境
VB/C#
WPF .Net Framework4.7.2
実現したいこと
プロセス間通信を行いフォームからフォームへ通信を行いたいです。
進捗状況
Form1,Form2の画面の表示(インスタンスの生成)は出来ています。
ソースコード
※フォーム1はC#、フォーム2はVBで開発しています。
①フォーム1のXAML
<Window x:Class="Form1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="450" Width="800"> <Grid> <TextBox x:Name="TextBox1" HorizontalAlignment="Left" Height="23" Margin="61,40,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <Button Content="Button" HorizontalAlignment="Left" Margin="238,40,0,0" VerticalAlignment="Top" Width="75" Height="23" Click="Button_Click"/> </Grid> </Window>
②フォーム1のコードビハインドクラス
namespace Form1 { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private IWcfClient Host; public MainWindow() { Process.Start("Form2.exe"); Host = new ChannelFactory<IWcfClient>( new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress("net.pipe://localhost/Form2")).CreateChannel(); InitializeComponent(); } /// <summary> /// ボタン押下時のイベント /// </summary> private void Button_Click(object sender, RoutedEventArgs e) { try { var message = Host.CallExecute(TextBox1.Text); MessageBox.Show(message); } catch(FaultException<FailureInfo> fx) { FailureInfo info = fx.Detail; MessageBox.Show(info.Message); } } } }
③サービスのインタフェース
namespace Form1 { [ServiceContract] public interface IWcfClient { [OperationContract] [FaultContract(typeof(FailureInfo))] string CallExecute(string text); } }
④サービスの具象クラス
namespace Form1 { [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class WcfClient: IWcfClient { public string CallExecute(string text) { // WCF通信で発生する例外を追跡するためにthrow throw new FaultException<FailureInfo>(new FailureInfo(), "WCF通信エラー"); } } }
⑤デバッグ用(FaultExceptionでプロセス間通信の例外を見るために使用)
namespace Form1 { [DataContract] public class FailureInfo { [DataMember] public string Message { get; set; } } }
⑥フォーム2のコードビハインドクラス
''' <summary> ''' Form2のコードビハインド ''' </summary> Public Class MainWindow Public Host As ServiceHost Public Const Uri As String = "net.pipe://localhost/Form2" Public Sub New() Host = New ServiceHost(GetType(WcfClient)) Host.AddServiceEndpoint( GetType(IWcfClient), New NetNamedPipeBinding(NetNamedPipeSecurityMode.None), New Uri(Uri)) Host.Open() InitializeComponent() End Sub ''' <summary> ''' テキストボックスに値をセットする ''' </summary> Public Function Reply(ByVal text As String) As String // テキストボックスにフォーム1より受け取った値をセット TextBox1.Text = text Return "Form2 Replyメソッドが呼ばれました" End Function End Class
試行内容
「④サービスの具象クラス」を以下のようにFacadeを用い、呼び出すアセンブリ・クラス・メソッドを動的に指定出来るように書き替え、Form1からForm2へプロセス間通信を実行しました。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class WcfClient: IWcfClient { public string CallExecute(string text) { // Facadeを用いてForm2のReplyメソッドをコール return Facade<string>("Form2.exe", "Form2.MainWindow", "Reply", text); } private T Facade<T>(string assembly, string className, string methodName, string text = "") { string path = Environment.CurrentDirectory + @"\" + assembly; Assembly asm = Assembly.LoadFrom(path); object obj = asm.CreateInstance(className); Type type = obj.GetType(); MethodInfo mi = type.GetMethod(methodName); object[] param = new object[1]; param[0] = text; object returnObj = mi.Invoke(obj, param); return (T)returnObj; } } }
上記を実行した結果、以下のスタックトレースが出力されました。
System.ServiceModel.FaultException HResult=0x80131501 Message=内部エラーのため、クライアントは要求を処理できませんでした。このエラーの詳細については、例外情報をクライアントに返信するためにサーバーで IncludeExceptionDetailInFaults を有効にするか (ServiceBehaviorAttribute または <serviceDebug> 構成動作を通じて)、Microsoft .NET Framework SDK ドキュメントに従ってトレースを有効にして、サーバーのトレース ログを調べてください。 Source=mscorlib スタック トレース: 場所 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 場所 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 場所 Form1.IWcfClient.CallExecute(String text) 場所 Form1.MainWindow.Button_Click(Object sender, RoutedEventArgs e) (C:\workspace\20191020\WcfConnection\Form1\MainWindow.xaml.cs):行 34 場所 System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 場所 System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 場所 System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 場所 System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) 場所 System.Windows.Controls.Primitives.ButtonBase.OnClick() 場所 System.Windows.Controls.Button.OnClick() 場所 System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) 場所 System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e) 場所 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 場所 System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 場所 System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 場所 System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 場所 System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) 場所 System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e) 場所 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 場所 System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 場所 System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 場所 System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 場所 System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 場所 System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) 場所 System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) 場所 System.Windows.Input.InputManager.ProcessStagingArea() 場所 System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) 場所 System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) 場所 System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) 場所 System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 場所 System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 場所 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 場所 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 場所 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 場所 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 場所 System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 場所 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 場所 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 場所 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 場所 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 場所 System.Windows.Application.RunDispatcher(Object ignore) 場所 System.Windows.Application.RunInternal(Window window) 場所 System.Windows.Application.Run(Window window) 場所 System.Windows.Application.Run() 場所 Form1.App.Main()
調べたところ、FaultExceptionの実行例外の詳細をクライアント側で取得するためには⑤のようなデバッグ追跡用のデータクラスが必要であったため、「FailureInfoクラス」を新規作成しました。
そしてプロセス間通信の実行例外(FaultException)のスタックトレースを確認するため「④サービスの具象クラス」のように書き換えました。
質問内容
「④サービスの具象クラス」でFaultExceptionをスローし、プロセス間通信の実行例外のスタックトレースを確認した結果、以下が出力されました。
自身で調査しましたが、真因が追求出来ていません。解決策をご存知の方いらっしゃいましたらご教授お願い致します。
場所 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 場所 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 場所 Form1.IWcfClient.CallExecute(String text) 場所 Form1.MainWindow.Button_Click(Object sender, RoutedEventArgs e) (C:\workspace\20191020\WcfConnection\Form1\MainWindow.xaml.cs):行 34
回答2件
あなたの回答
tips
プレビュー