首先,请允许我发布有问题的代码!!! ...
/// <summary>
/// Represents the implementation of the Remote Launch Service.
/// </summary>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
[KnownType(typeof(RemoteProcessHandle))]
[KnownType(typeof(RemoteLaunchServiceResult<RemoteProcessHandle>))]
[KnownType(typeof(RemoteLaunchServiceResult<bool>))]
public sealed class RemoteLaunchService : IRemoteLaunchService
{
/// <summary>
/// Handles the event in which a process is started by the Remote Launch Service.
/// </summary>
/// <param name="sender">the object that raised the event.</param>
/// <param name="startInfo">the <see cref="RemoteProcessStartInfo"/> object containing information about the process that was started.</param>
/// <param name="handle">the <see cref="RemoteProcessHandle"/> for the resulting process.</param>
public delegate void ProcessStartedEventHandler(
object sender, RemoteProcessStartInfo startInfo, RemoteProcessHandle handle);
/// <summary>
/// Handles the event in which an attempt to close the main window of a process is made by the Remote Launch Service.
/// </summary>
/// <param name="sender">the object that raised the event.</param>
/// <param name="handle">the <see cref="RemoteProcessHandle"/> corresponding to the process.</param>
/// <param name="successful">true if the operation was successful, otherwise false.</param>
public delegate void ProcessMainWindowClosedEventHandler(
object sender, RemoteProcessHandle handle, bool successful);
/// <summary>
/// Handles the event in which a process is killed by the Remote Launch Service.
/// </summary>
/// <param name="sender">the object that raised the event.</param>
/// <param name="handle">the <see cref="RemoteProcessHandle"/> corresponding to the process.</param>
public delegate void ProcessKilledEventHandler(
object sender, RemoteProcessHandle handle);
/// <summary>
/// Handles the event in which an exception is thrown by the Remote Launch Service.
/// </summary>
/// <param name="sender">the object that raised the event.</param>
/// <param name="exception">the exception that was thrown.</param>
public delegate void ExceptionThrownEventHandler(
object sender, Exception exception);
/// <summary>
/// Handles the event in which a process is started by the Remote Launch Service.
/// </summary>
public event ProcessStartedEventHandler ProcessStarted;
/// <summary>
/// Handles the event in which an attempt to close the main window of a process is made by the Remote Launch Service.
/// </summary>
public event ProcessMainWindowClosedEventHandler ProcessMainWindowClosed;
/// <summary>
/// Handles the event in which a process is killed by the Remote Launch Service.
/// </summary>
public event ProcessKilledEventHandler ProcessKilled;
/// <summary>
/// Handles the event in which an exception is thrown by the Remote Launch Service.
/// </summary>
public event ExceptionThrownEventHandler ExceptionThrown;
/// <summary>
/// Starts a remote process via the Remote Launch Service, using information within the specified <see cref="RemoteProcessStartInfo"/>.
/// </summary>
/// <param name="startInfo">the <see cref="RemoteProcessStartInfo"/> object containing information about the process to start.</param>
/// <returns>a <see cref="RemoteLaunchServiceResult{RemoteProcessHandle}"/> containing a <see cref="RemoteProcessHandle"/> for the process.</returns>
public RemoteLaunchServiceResult<RemoteProcessHandle> Start(
RemoteProcessStartInfo startInfo)
{
try
{
// Start the process and retrieve the handle.
RemoteProcessHandle handle = new RemoteProcessHandle(Process.Start(startInfo.LocalProcessStartInfo));
// If there are any handlers registered to the appropriate event, raise it.
if (ProcessStarted != null) ProcessStarted(this, startInfo, handle);
// Return the result containing the handle.
return new RemoteLaunchServiceResult<RemoteProcessHandle>(handle, null);
}
catch (Exception exception)
{
// If an exception is thrown, raise the appropriate event (if any handlers are registered to it), and return the result containing the exception.
if (ExceptionThrown != null) ExceptionThrown(this, exception);
return new RemoteLaunchServiceResult<RemoteProcessHandle>(null, exception.Message);
}
}
/// <summary>
/// Attempts to close the main window of the process corresponding to the specified <see cref="RemoteProcessHandle"/>.
/// </summary>
/// <param name="handle">the <see cref="RemoteProcessHandle"/> corresponding to the process.</param>
/// <returns>a <see cref="RemoteLaunchServiceResult{bool}"/> containing whether the operation was successful or not.</returns>
public RemoteLaunchServiceResult<bool> CloseMainWindow(
RemoteProcessHandle handle)
{
try
{
// Attempt to close the main window of the process and retrieve whether this was successful.
bool successful = handle.LocalProcess.CloseMainWindow();
// If there are any handlers registered to the appropriate event, raise it.
if (ProcessMainWindowClosed != null) ProcessMainWindowClosed(this, handle, successful);
// Return the result containing whether the operation was successful or not.
return new RemoteLaunchServiceResult<bool>(successful, null);
}
catch (Exception exception)
{
// If an exception is thrown, raise the event (if any handlers are registered to it), and return the result containing the exception.
if (ExceptionThrown != null) ExceptionThrown(this, exception);
return new RemoteLaunchServiceResult<bool>(false, exception.Message);
}
}
/// <summary>
/// Kills the process corresponding to the specified <see cref="RemoteProcessHandle"/>.
/// </summary>
/// <param name="handle">the <see cref="RemoteProcessHandle"/> corresponding to the process.</param>
/// <returns>a <see cref="RemoteLaunchServiceResult{bool}"/> containing whether an exception was thrown or not.</returns>
public RemoteLaunchServiceResult<bool> Kill(
RemoteProcessHandle handle)
{
try
{
handle.LocalProcess.Kill();
// If there are any handlers registered to the appropriate event, raise it.
if (ProcessKilled != null) ProcessKilled(this, handle);
// Return the result indicating that no exception was thrown.
return new RemoteLaunchServiceResult<bool>(true, null);
}
catch (Exception exception)
{
// If an exception is thrown, raise the event (if any handlers are registered to it), and return the result containing the exception.
if (ExceptionThrown != null) ExceptionThrown(this, exception);
return new RemoteLaunchServiceResult<bool>(false, exception.Message);
}
}
/// <summary>
/// The default port number used by the Remote Launch Service.
/// </summary>
public const int DefaultPort = 2185;
/// <summary>
/// Gets the address of the Remote Launch Service running on the specified machine, using the specified port number.
/// </summary>
/// <param name="machineName">the name of the machine.</param>
/// <param name="port">the port number.</param>
/// <returns>a <see cref="string"/> containing the address.</returns>
public static string GetAddress(
string machineName, int port)
{
// The machine name and port number must be valid.
if (machineName == null) throw new ArgumentNullException(nameof(machineName));
if ((port < IPEndPoint.MinPort) || (port > IPEndPoint.MaxPort)) throw new ArgumentOutOfRangeException(nameof(port));
// Derive and return the address.
return string.Format(@"net.tcp://{0}:{1}/RemoteLaunchService", machineName, port);
}
/// <summary>
/// Gets the address of the Remote Launch Service running on this machine, using the specified port number.
/// </summary>
/// <param name="port">the port number.</param>
/// <returns>a <see cref="string"/> containing the address.</returns>
public static string GetAddress(
int port)
{
return GetAddress(Dns.GetHostName(), port);
}
}
我通过ChannelFactory
课程访问该服务,一切顺利,直到我点击Start()
方法中的return语句...
/// <summary>
/// Starts a remote process via the Remote Launch Service, using information within the specified <see cref="RemoteProcessStartInfo"/>.
/// </summary>
/// <param name="startInfo">the <see cref="RemoteProcessStartInfo"/> object containing information about the process to start.</param>
/// <returns>a <see cref="RemoteLaunchServiceResult{RemoteProcessHandle}"/> containing a <see cref="RemoteProcessHandle"/> for the process.</returns>
public RemoteLaunchServiceResult<RemoteProcessHandle> Start(
RemoteProcessStartInfo startInfo)
{
try
{
// Start the process and retrieve the handle.
RemoteProcessHandle handle = new RemoteProcessHandle(Process.Start(startInfo.LocalProcessStartInfo));
// If there are any handlers registered to the appropriate event, raise it.
if (ProcessStarted != null) ProcessStarted(this, startInfo, handle);
// Return the result containing the handle.
return new RemoteLaunchServiceResult<RemoteProcessHandle>(handle, null);
}
catch (Exception exception)
{
// If an exception is thrown, raise the appropriate event (if any handlers are registered to it), and return the result containing the exception.
if (ExceptionThrown != null) ExceptionThrown(this, exception);
return new RemoteLaunchServiceResult<RemoteProcessHandle>(null, exception.Message);
}
}
代码在不进入catch块的情况下正确执行了该过程,但是一旦我返回CommunicationException
就会抛出RemoteLaunchServiceResult
。有趣的是,如果我改变......
return new RemoteLaunchServiceResult<RemoteProcessHandle>(handle, null);
...到...
return new RemoteLaunchServiceResult<RemoteProcessHandle>(null, null);
...没有抛出任何异常,让我觉得它可能是RemoteProcessHandle
类的问题。这是这个班级的列表...
/// <summary>
/// Represents the information required to access a remote process after it has been started by the Remote Launch Service.
/// </summary>
[Serializable]
public sealed class RemoteProcessHandle : ISerializable
{
/// <summary>
/// Initializes a new instance of the <see cref="RemoteProcessHandle"/> class.
/// </summary>
/// <param name="process">the <see cref="Process"/> object to derive the handle from.</param>
public RemoteProcessHandle(
Process process)
{
if (process == null) return;
try { this.processID = process.Id; } catch { }
try { this.machineName = process.MachineName; } catch { }
}
/// <summary>
/// Initializes a new instance of the <see cref="RemoteProcessHandle"/> class from data contained within a <see cref="SerializationInfo"/> object.
/// </summary>
/// <param name="info">the <see cref="SerializationInfo"/> containing the information required to deserialize this <see cref="RemoteProcessHandle"/>.</param>
/// <param name="context">the <see cref="StreamingContext"/> containing the source of the serialized stream associated with this <see cref="RemoteProcessHandle"/>.</param>
public RemoteProcessHandle(
SerializationInfo info, StreamingContext context) : this(null)
{
try { this.processID = (int?)info.GetValue(nameof(this.processID), typeof(int?)); } catch { }
try { this.machineName = (string)info.GetValue(nameof(this.machineName), typeof(string)); } catch { }
}
// Instance variables.
private int? processID = null;
private string machineName = null;
/// <summary>
/// Gets the ID of the process that this <see cref="RemoteProcessHandle"/> represents.
/// </summary>
public int? ProcessID
{
get { return this.processID; }
}
/// <summary>
/// Gets the name of the machine running the process that this <see cref="RemoteProcessHandle"/> represents.
/// </summary>
public string MachineName
{
get { return this.machineName; }
}
/// <summary>
/// Gets the local <see cref="Process"/> corresponding to this <see cref="RemoteProcessHandle"/>.
/// </summary>
public Process LocalProcess
{
get
{
// The machine name within this information has got to match this machine, and the process ID mustn't be null.
if (!Dns.GetHostName().Equals(this.MachineName, StringComparison.OrdinalIgnoreCase)) throw new InvalidOperationException();
if (this.ProcessID == null) throw new InvalidOperationException();
// Get and return the process.
return Process.GetProcessById(this.ProcessID.Value);
}
}
/// <summary>
/// Gets the address of the Remote Launch Service, using the specified port number, running the process that this <see cref="RemoteProcessHandle"/> represents.
/// </summary>
/// <param name="port">the port number.</param>
/// <returns>a <see cref="string"/> containing the address.</returns>
public string GetRemoteLaunchServiceAddress(
int port)
{
return RemoteLaunchService.GetAddress(this.MachineName, port);
}
/// <summary>
/// Populates a <see cref="SerializationInfo"/> object with data required to serialize this <see cref="RemoteProcessHandle"/>.
/// </summary>
/// <param name="info">the <see cref="SerializationInfo"/> to contain the information required to serialize this <see cref="RemoteProcessHandle"/>.</param>
/// <param name="context">the <see cref="StreamingContext"/> containing the destination of the serialized stream associated with this <see cref="RemoteProcessHandle"/>.</param>
public void GetObjectData(
SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(this.processID), this.processID, typeof(int?));
info.AddValue(nameof(this.machineName), this.machineName, typeof(string));
}
}
请有人可以提出任何可能引起此异常的建议吗?
答案 0 :(得分:1)
我已设法修复此错误!...
[Serializable]
[KnownType(typeof(RemoteProcessHandle))]
public sealed class RemoteLaunchServiceResult<T>
{
// I solved the problem by adding the "KnownType" attribute. I thought
// it would have worked having it in the "RemoteLaunchService" class,
// but I was wrong!
}
感谢您输入的人!!!