将参数传递给正在运行的应用程序
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());
【讨论】:
以上是关于将参数传递给正在运行的应用程序的主要内容,如果未能解决你的问题,请参考以下文章