使用参数启动 ac# 程序的第二个实例,该程序的第一个实例使用该参数

发布于 2024-10-16 22:56:21 字数 5188 浏览 2 评论 0原文

我有一个单实例程序,当它运行时我可以选择向它传递一个参数。

如果程序不带参数运行,只需在选项卡上打开 dataGridView 并将客户列表加载到其中。如果我双击一行,它会在第二个选项卡中打开该特定客户,并提供更多信息。

如果我使用参数(从 00000 到 99999 的客户 ID 号)启动程序,它会自动切换到第二个选项卡并加载各个客户数据。

不过,到目前为止一切顺利,我想要做的是让我的程序运行,但是如果使用参数调用该程序的第二个实例,例如 Program.exe 1234,我希望它直接跳到第二个选项卡并显示该客户的详细信息。

这是我到目前为止所拥有的。我这样做是不是找错了对象?我的印象是 Program.exe 应该监听另一个正在运行的实例并使用传递给它的参数。

任何建议将不胜感激。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.IO;

命名空间 SiteConnex { 公共类 SingleApplication { /// 导入 [DllImport("user32.dll")] 私有静态 extern int ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] 私有静态 extern int SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] 私有静态 extern int IsIconic(IntPtr hWnd); 公共静态布尔 SecondInstance = false; 公共静态字符串 siteid = ""; 公共静态布尔 gotosite = false;

    public static void Main(string[] args)
    {
        // string siteid = "";
        // bool gotosite = false;
        // bool secondInstance = false;
        int testSiteid = 0;
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        try
        {
            siteid = Convert.ToString(args[0]);
        }
        catch (Exception noArgs)
        {
            // No commandline args have been passed.
        }

// 检查传递的参数实际上是一个有效的数字,否则就像没有传递参数一样。 尝试 { testSiteid = Convert.ToInt32(siteid); if ((testSiteid > 00000) || (testSiteid < 99999)) { 转到站点=真; } 别的 { 站点ID =“”; } } 捕获(异常 e) { // 如果出现异常,则意味着 siteid 已传递了无用的数据。 }

/// Check if it's running, if it is, pass siteid and gotosite through... and acts as if it has a valid siteid passed to it. // Application.Run(new Form1(siteid, gotosite)); Run(siteid, gotosite, secondInstance); } private static IntPtr GetCurrentInstanceWindowHandle() { IntPtr hWnd = IntPtr.Zero; Process process = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(process.ProcessName); foreach(Process _process in processes) { // Get the first instance that is not this instance, has the // same process name and was started from the same file name // and location. Also check that the process has a valid // window handle in this session to filter out other user's // processes. if (_process.Id != process.Id && _process.MainModule.FileName == process.MainModule.FileName && _process.MainWindowHandle != IntPtr.Zero) { hWnd = _process.MainWindowHandle; break; } } return hWnd; } /// SwitchToCurrentInstance private static void SwitchToCurrentInstance(string siteid, bool gotosite, bool secondInstance) { IntPtr hWnd = GetCurrentInstanceWindowHandle(); if (hWnd != IntPtr.Zero) { // Restore window if minimised. Do not restore if already in // normal or maximised window state, since we don't want to // change the current state of the window. if (IsIconic(hWnd) != 0) { ShowWindow(hWnd, SW_RESTORE); } // Set foreground window. SetForegroundWindow(hWnd); secondInstance = true; } } /// Execute a form base application if another instance already running on /// the system activate previous one /// <param name="frmMain">main form</param> /// true if no previous instance is running // public static bool Run(System.Windows.Forms.Form frmMain) public static bool Run(string siteid, bool gotosite, bool secondInstance) { if(IsAlreadyRunning()) { //set focus on previously running app SwitchToCurrentInstance(siteid, gotosite, secondInstance); return false; } Application.Run(new Form1(siteid, gotosite, secondInstance)); return true; } /// check if given exe alread running or not /// returns true if already running private static bool IsAlreadyRunning() { string strLoc = Assembly.GetExecutingAssembly().Location; FileSystemInfo fileInfo = new FileInfo(strLoc); string sExeName = fileInfo.Name; bool bCreatedNew; mutex = new Mutex(true, "Global\\"+sExeName, out bCreatedNew); if (bCreatedNew) mutex.ReleaseMutex(); return !bCreatedNew; } static Mutex mutex; const int SW_RESTORE = 9; }

}

I have a single instance program, which when it runs I can choose to pass a single parameter to it.

If the program runs with no parameters, just opens up on a tab a dataGridView and loads a list of customers into it. If I double click a row it opens up that particular customer in a 2nd tab with more info on it.

If I start the program with a parameter, (a customer id number from 00000 to 99999) it automatically switches to the 2nd tab and loads that individual customers data.

So far so good, however, What I want to be able to do is have my program running, but if a 2nd instance of the program is called with a parameter, e.g. Program.exe 1234, I want it to just jump straight to the 2nd tab and display that customer's details.

This is what I have so far. Am I barking up the wrong tree with the way I'm trying to do this? I get the impression the Program.exe should be listening for another instance running and using the parameter passed to it.

Any advice would be greatly appreciated.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.IO;

namespace SiteConnex { public class SingleApplication { /// Imports [DllImport("user32.dll")] private static extern int ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] private static extern int SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern int IsIconic(IntPtr hWnd); public static bool secondInstance = false; public static string siteid = ""; public static bool gotosite = false;

    public static void Main(string[] args)
    {
        // string siteid = "";
        // bool gotosite = false;
        // bool secondInstance = false;
        int testSiteid = 0;
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        try
        {
            siteid = Convert.ToString(args[0]);
        }
        catch (Exception noArgs)
        {
            // No commandline args have been passed.
        }

// check that the parameter passed is actually a valid number, otherwise just act like no params passed.
try
{
testSiteid = Convert.ToInt32(siteid);
if ((testSiteid > 00000) || (testSiteid < 99999))
{
gotosite = true;
}
else
{
siteid = "";
}
}
catch (Exception e)
{
// If you get an exception it means siteid had duff data passed into it.
}

/// Check if it's running, if it is, pass siteid and gotosite through... and acts as if it has a valid siteid passed to it.
// Application.Run(new Form1(siteid, gotosite));
Run(siteid, gotosite, secondInstance);
}

private static IntPtr GetCurrentInstanceWindowHandle()
{
IntPtr hWnd = IntPtr.Zero;
Process process = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(process.ProcessName);
foreach(Process _process in processes)
{
// Get the first instance that is not this instance, has the
// same process name and was started from the same file name
// and location. Also check that the process has a valid
// window handle in this session to filter out other user's
// processes.

if (_process.Id != process.Id &&
_process.MainModule.FileName == process.MainModule.FileName &&
_process.MainWindowHandle != IntPtr.Zero)
{
hWnd = _process.MainWindowHandle;
break;
}
}
return hWnd;
}

/// SwitchToCurrentInstance

private static void SwitchToCurrentInstance(string siteid, bool gotosite, bool secondInstance)
{
IntPtr hWnd = GetCurrentInstanceWindowHandle();
if (hWnd != IntPtr.Zero)
{
// Restore window if minimised. Do not restore if already in
// normal or maximised window state, since we don't want to
// change the current state of the window.
if (IsIconic(hWnd) != 0)
{
ShowWindow(hWnd, SW_RESTORE);
}
// Set foreground window.
SetForegroundWindow(hWnd);
secondInstance = true;
}
}
/// Execute a form base application if another instance already running on
/// the system activate previous one
/// <param name="frmMain">main form</param>
/// true if no previous instance is running

// public static bool Run(System.Windows.Forms.Form frmMain)
public static bool Run(string siteid, bool gotosite, bool secondInstance)
{
if(IsAlreadyRunning())
{
//set focus on previously running app
SwitchToCurrentInstance(siteid, gotosite, secondInstance);
return false;
}
Application.Run(new Form1(siteid, gotosite, secondInstance));
return true;
}
/// check if given exe alread running or not
/// returns true if already running

private static bool IsAlreadyRunning()
{
string strLoc = Assembly.GetExecutingAssembly().Location;
FileSystemInfo fileInfo = new FileInfo(strLoc);
string sExeName = fileInfo.Name;
bool bCreatedNew;
mutex = new Mutex(true, "Global\\"+sExeName, out bCreatedNew);
if (bCreatedNew)
mutex.ReleaseMutex();
return !bCreatedNew;
}
static Mutex mutex;
const int SW_RESTORE = 9;
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

姐不稀罕 2024-10-23 22:56:21

啊哈...找到了答案...有人叫 MadHatter 制作了一个 SingleInstance 应用程序,它完全符合我的要求,而且看起来相当简单。

http://sanity-free.org/misc/SingleInstanceApp.zip

Ah ha... found the answer in this... Someone called MadHatter made an SingleInstance app that does exactly what I was looking to do and seems fairly straight forwards.

http://sanity-free.org/misc/SingleInstanceApp.zip

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文