将参数传递给正在运行的应用程序

Posted

技术标签:

【中文标题】将参数传递给正在运行的应用程序【英文标题】:Pass arguments to running application 【发布时间】:2011-04-17 04:16:33 【问题描述】:

我正在制作图片上传器(将图片上传到图片托管网站),但在传递参数时遇到了一些问题(图片位置到已运行的应用程序)

首先假设 MyApp.exe 一直在运行 每当我右键单击图像时,我都会在默认的 Windows 上下文菜单中添加一个项目,显示“上传图像”。 单击该按钮后,需要将位置传递给已运行的应用程序。

我的程序.cs:

static class Program

    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, UIntPtr
    wParam, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint RegisterWindowMessage(string lpString);

    [STAThread]
    static void Main(params string[] Arguments)
    
        if (Arguments.Length > 0)
        
    //This means that the the upload item in the context menu is clicked
    //Here the method "uploadImage(string location)"
    //of the running application must be ran
        
        else
        
    //just start the application
            Application.Run(new ControlPanel());
        
    

请注意,ControlPanel 类没有可见的表单,只有一个托盘图标存在,因为不需要表单。

我可以就如何做到这一点获得任何帮助吗?

【问题讨论】:

【参考方案1】:

假设您可以控制执行环境,监听应用程序可以只使用 WCF 甚至是原始 TCP 套接字公开一个端点。这样,任何其他应用程序都可以以动态但结构化的方式连接到它。

即使发送方和接收方在同一台机器上,使用网络传输解决方案(如 WCF 或 TCP)也是跨进程安全发送数据的好方法。

下面是一个如何在 TCP 中使用 c# 进行操作的示例:http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server

WCF 可能稍微复杂一些(部分原因在于它的灵活性,以及​​序列化限制),但是网上有很多关于如何使用它的文档。 WCF 是一种更加面向对象的解决方案,因为可以生成代理类,允许您对实际对象进行强类型调用,而不仅仅是发送消息。

【讨论】:

【参考方案2】:

您必须为其他应用程序建立一个通信渠道来发布图像。此沟通渠道可以是以下之一 - 不是完整列表,只是示例:

一个由您的应用程序监视的目录,文件一旦添加到该目录中就会被添加。 其他应用程序可以向其发送信息的端口。 接受图像的自托管 Web 服务。 接收图像的 TCP 端口。 命名管道。 ....

如您所见,有多种可能性。适合您的取决于您的情况。文件系统是一个可以使用FileSystemWatcher 示例see here 轻松实现的选项。

自托管网络服务公开了一个可以接收图像的网络服务。 See here 获取示例。

恕我直言,这是最简单的两个选项。但是……还有几个。

有关 TCP 端口,请参阅 Tim 的帖子。

【讨论】:

+1 表示 FileSystemWatcher 建议。我在许多应用程序上都使用了观察器,效果很好。如果需要同步通信或请求/响应关系,我不会使用它,但这听起来不像是要求。 嗨,谢谢你给了我一些额外的想法,但你应该知道我无法控制图像托管网站。我只是通过执行 POST 提交并检索响应来上传图像(其中包含上传图像的链接,在互联网上)我尝试了 TCP 的想法,但由于某种原因,我认为这不是我需要的东西。我有一个可以上传图片等功能的完整应用程序。我现在唯一需要的是:【参考方案3】:

我已经弄明白了,非常感谢发布http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a5bcfc8a-bf69-4bbc-923d-f30f9ecf5f64 链接的人,这正是我想要的!

这是一个完整的解决方案:

static class Program

    [STAThread]
    static void Main(params string[] Arguments)
    
        SingleInstanceApplication.Run(new ControlPanel(), NewInstanceHandler);
    

    public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)
    
        string imageLocation = e.CommandLine[1];
        MessageBox.Show(imageLocation);
        e.BringToForeground = false;
        ControlPanel.uploadImage(imageLocation);
    

    public class SingleInstanceApplication : WindowsFormsApplicationBase
    
        private SingleInstanceApplication()
        
            base.IsSingleInstance = true;
        

        public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
        
            SingleInstanceApplication app = new SingleInstanceApplication();
            app.MainForm = f;
            app.StartupNextInstance += startupHandler;
            app.Run(Environment.GetCommandLineArgs());
        
      

非常感谢大家,尤其是发布我上面提到的那个链接的人,但我猜他删除了他的答案?

问候, 肯尼

【讨论】:

肯尼,谢谢你的帖子。这对我帮助很大。无论如何要在 NewInstanceHandler 方法中引用表单(您的 ControlPanel)吗?我知道您在 ControlPanel 中引用了“uploadImage”方法,但这是一个静态方法。但我需要引用非静态方法。请告诉我【参考方案4】:

我在之前的解决方案中添加了一些小的补充,以引用表单上的 setter,以便将参数传递给它。

首先,创建对表单初始实例 (MainForm) 的静态引用。

然后,在随后发送参数时,NewInstanceHandler 可以使用保存的对表单的引用来访问它的公共方法/属性(在我的例子中,一个名为 AddItem 的设置器)。

一个简单的测试方法是向表单添加一个公共属性,使用 setter 来更改表单的文本属性(标题文本)。

[STAThread]
    static Form1 MainForm;

    static void Main(params string[] Arguments)
    
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        MainForm = new Form1();
        SingleInstanceApplication.Run(MainForm, NewInstanceHandler);
    

    public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)
    
        MainForm.AddItem = e.CommandLine[1];
        e.BringToForeground = false;
    

    public class SingleInstanceApplication : WindowsFormsApplicationBase
    
        private SingleInstanceApplication()
        
            base.IsSingleInstance = true;
        

        public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
        
            SingleInstanceApplication app = new SingleInstanceApplication();
            app.MainForm = f;
            app.StartupNextInstance += startupHandler;
            app.Run(Environment.GetCommandLineArgs());
        
     

【讨论】:

没错,我得到了同样的错误(当前上下文中不存在名称'MainForm')。安迪你有更新吗?我知道它真的很旧,希望你有解决方案【参考方案5】:

为避免在将命令行参数传递给现有实例后运行第二个实例,我在下面添加了代码 sn-p。

static class Program

    [STAThread]

   static void Main(params string[] Arguments)
   
        Form1 MainForm;
        bool bInstanceFlag;

        Mutex MyApplicationMutex = new Mutex(true, "MyApp_Mutex", out bInstanceFlag);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        if (!bInstanceFlag)
        
           MainForm = new Form1();
        SingleInstanceApplication.Run(MainForm, NewInstanceHandler);
    
    else
    
        MainForm = new Form1();
        SingleInstanceApplication.Run(MainForm, NewInstanceHandler);
        MainForm.Close();
    


public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)

    MainForm.AddItem = e.CommandLine[1];
    e.BringToForeground = false;


public class SingleInstanceApplication : WindowsFormsApplicationBase

    private SingleInstanceApplication()
    
        base.IsSingleInstance = true;
    

    public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
    
        SingleInstanceApplication app = new SingleInstanceApplication();
        app.MainForm = f;
        app.StartupNextInstance += startupHandler;
        app.Run(Environment.GetCommandLineArgs());
    


【讨论】:

以上是关于将参数传递给正在运行的应用程序的主要内容,如果未能解决你的问题,请参考以下文章

仅在将参数传递给程序时使用 openMP

nginx - 将请求标头变量作为查询参数传递给上游 URL

将命令行参数传递给 AWS Fargate 容器

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?