传递参数以运行应用程序

时间:2010-09-25 13:28:26

标签: c# arguments

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

  • 首先让我们说MyApp.exe一直在运行
  • 每当我右键单击图像时,我在默认的Windows上下文菜单中添加了一个项目,上面写着“上传图片”。
  • 当点击它时,需要将该位置传递给已经运行的应用程序。

我的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类没有可见的表单,只有托盘图标,因为不需要表单。

我可以获得有关如何执行此操作的任何帮助吗?

5 个答案:

答案 0 :(得分:15)

我已经弄明白了,非常感谢发布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());
        }
    }  
}

非常感谢,特别是发布上述链接的人,但我猜他删除了他的答案?

此致 肯尼

答案 1 :(得分:4)

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

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

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

自托管Web服务公开可以接收图像的Web服务。 See here获取样本。

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

对于TCP端口,请参阅Tim的帖子。

答案 2 :(得分:2)

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

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

以下是使用c#:http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server

在TCP中执行此操作的示例

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

答案 3 :(得分:0)

我在上一个解决方案中添加了一些小的附加内容,以引用表单上的setter,以便将参数传递给它。

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

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

一种简单的测试方法是使用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());
        }
    } 

答案 4 :(得分:0)

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

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