c# – Clickonce应用程序和文件处理程序行为
作者:互联网
我有一个clickonce应用程序,我为这个应用程序设置了几个文件处理程序(为了这个例子,我想处理扩展名为.aaa或.bbb的文件).
如果我选择一个带有这些扩展名的文件,我的应用程序会按预期启动,一切都很好.但是,如果我选择多个文件并打开它们(通过按Enter键或右键单击并选择“打开”),则会启动我的aopplication的多个实例 – 每个文件被选中一个实例.
这不是我期望的行为,我只希望一个实例以AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData中的多个文件条目开头.这可以实现,还是我的期望不正确?
编辑:
只是详细说明:我们已经遵循了@Matthias提到的单实例方法,第一个启动实例创建了一个命名服务器管道.然后,后续实例启动,检测到它们是辅助实例,通过命名管道将其命令行参数(filename)传递给主实例,然后退出.主实例通过命名管道接收文件名,并执行其操作(启动文件导入向导).
当用户选择多个文件(即5个文件),然后选择在应用程序中打开这些文件时,就会出现问题.我没有从命令行提供的5个文件名开始一个辅助实例,而是启动了5个应用程序启动的辅助实例,每个实例在命令行上都有一个文件名.然后,每个都创建一个名为pipe的客户端,并将该文件名传递给主实例 – 因此名为pipe的服务器接收5个单独的消息.
跟进想法:
在聊聊这个之后,我发现这可能只是注册文件处理程序的工作方式,也许它与clickonce无关.也许解决方案是服务器命名管道在收到每条消息后暂停,并在操作之前尝试排队消息?
解决方法:
您可以通过实现single instance application来实现此目的.如果应用程序已在运行(第二次调用),您可以使用命名管道来通知应用程序(第一次调用)文件打开事件.
编辑
找到了早期项目的代码片段.我想强调代码肯定需要改进,但它应该是一个很好的点,你可以从哪里开始.
在你的静态主要:
const string pipeName = "auDeo.Server";
var ownCmd = string.Join(" ", args);
try
{
using (var ipc = new IPC(pipeName))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new ServerForm();
ipc.MessageReceived += m =>
{
var remoteCmd = Encoding.UTF8.GetString(m);
form.Invoke(remoteCmd);
};
if (!string.IsNullOrEmpty(ownCmd))
form.Invoke(ownCmd);
Application.Run(form);
}
}
catch (Exception)
{
//MessageBox.Show(e.ToString());
if (string.IsNullOrEmpty(ownCmd))
return;
var msg = Encoding.UTF8.GetBytes(ownCmd);
IPC.SendMessage(pipeName, msg);
}
IPC课程:
public class IPC : IDisposable
{
public IPC(string pipeName)
{
Stream = new NamedPipeServerStream(pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
AsyncCallback callback = null;
callback = delegate(IAsyncResult ar)
{
try
{
Stream.EndWaitForConnection(ar);
}
catch (ObjectDisposedException)
{
return;
}
var buffer = new byte[2000];
var length = Stream.Read(buffer, 0, buffer.Length);
var message = new byte[length];
Array.Copy(buffer, message, length);
if (MessageReceived != null)
MessageReceived(message);
Stream.Disconnect();
// ReSharper disable AccessToModifiedClosure
Stream.BeginWaitForConnection(callback, null);
// ReSharper restore AccessToModifiedClosure
};
Stream.BeginWaitForConnection(callback, null);
}
private NamedPipeServerStream Stream
{
get;
set;
}
#region IDisposable Members
public void Dispose()
{
if (Stream != null)
Stream.Dispose();
}
#endregion
public static void SendMessage(string pipeName, byte[] message)
{
using (var client = new NamedPipeClientStream(".", pipeName))
{
client.Connect();
client.Write(message, 0, message.Length);
client.Close();
}
}
~IPC()
{
Dispose();
}
public event MessageHandler MessageReceived;
}
标签:c,clickonce,filehandler 来源: https://codeday.me/bug/20190621/1251930.html