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

C# 将参数传递给正在运行的应用程序,c#,arguments,C#,Arguments,我正在制作一个图像上传程序(将图像上传到图像托管网站),在传递参数(图像位置到已经运行的应用程序)时遇到一些问题 首先,假设MyApp.exe始终在运行 每当我右键单击图像时,我都会在默认的windows上下文菜单中添加一个项目,上面写着“上载图像” 单击该按钮时,需要将位置传递给已经运行的应用程序 My program.cs: static class Program { [DllImport("user32.dll")] static extern IntPtr Find

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

  • 首先,假设MyApp.exe始终在运行
  • 每当我右键单击图像时,我都会在默认的windows上下文菜单中添加一个项目,上面写着“上载图像”
  • 单击该按钮时,需要将位置传递给已经运行的应用程序
My program.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类没有可见的表单,因为不需要表单,所以只显示一个托盘图标


我可以得到关于如何执行此操作的帮助吗?

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

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

下面是一个如何使用c#在TCP中执行此操作的示例:


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

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

  • 应用程序监视的目录,文件添加到该目录后即被添加
  • 其他应用程序可以向其发送信息的端口
  • 接受图像的自托管web服务
  • 接收图像的TCP端口
  • 命名管道
如你所见,有几种可能性。适合您的方案取决于您的场景。文件系统是一个选项,可以使用示例的
FileSystemWatcher
轻松实现

自托管web服务公开可以接收图像的web服务。来个样品

嗯,这是两个最简单的选择。但是还有几个


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

我已经找到了答案,非常感谢发布链接的人,这正是我想要的

以下是完整解决方案的一个示例:

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());
        }
    }  
}
非常感谢所有人,尤其是我上面提到的那个发布链接的人,但我猜他删除了他的答案

问候,,
Kenny

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

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

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

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


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

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());
    }
}
}

+1获取文件系统观察者建议。我在许多应用程序中使用了watcher,并取得了很好的效果。如果需要同步通信或请求/响应关系,我不会使用它,但听起来这些不是要求。嗨,谢谢,这给了我一些额外的想法,但你应该知道我无法控制图像托管网站。我只是上传了一张图片,通过提交和检索回复(其中包含上传图片的链接,在互联网上),我尝试了TCP的想法,但出于某种原因,我不认为这是我需要的东西。我有一个完整的工作应用程序,上传图像等。我现在唯一需要的是:肯尼,谢谢你的帖子。这对我帮助很大。在NewInstanceHandler方法中是否有引用表单(您的控制面板)的方法?我知道您正在引用控制面板中的“uploadImage”方法,但这是一种静态方法。但我需要参考非静态方法。请确切地告诉我,我得到了相同的错误(名称“MainForm”在当前上下文中不存在)。安迪,你有最新消息吗。我知道它真的很旧了,希望你有解决办法
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());
    }
}
}