编程语言
首页 > 编程语言> > c# – Clickonce应用程序和文件处理程序行为

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