我描述可能不是那么准确。。
现在我们要实现在命令行多次执行某一程序时,该程序只会执行出现一次,每次运行的不同结果会以选项卡的形式出现在程序窗口中,就像这样目前我已经可以做到识别出是否是第一次运行该程序,但不会实现每当再运行一次该程序时,如何动态添加一个tabpage,(通过button什么的添加我会,但是直接在运行程序的时候就自动添加我不太会)...
谢谢大家

解决方案 »

  1.   

    TabPage tp = new TabPage();
    ...
    TabControl1.Pages.Add(tp);
      

  2.   

    可以搞一个全局的tabcontrol,在program中就可以访问,主窗体中就将这个全局的控件添加到界面,第二个实例启动时,在program中就可以对这个控件添加页面
      

  3.   

    我的TabControl应该在哪里定义呢?每次运行程序初始化一个TabControl的时候不是会导致每次都是新的选项卡么...我是希望能够多次运行这个程序不同的结果以选项卡的程序分别呈现...(都在这个程序中)...
      

  4.   

    interface IRemoteApplicationInterface
    {
    void RemoteApplicationNotification();
    } class RemotableApplication : MarshalByRefObject, IRemoteApplicationInterface
    {
    /// <summary>
    /// Start for remote application notification.
    /// </summary>
    /// <param name="name">remote name.</param>
    /// <param name="action">remote notification action.</param>
    public static void RemoteApplicationNotification(string name, Action action)
    {
    System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Ipc.IpcChannel(name + ".IPC"), false);
    System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotableApplication), "Launch", System.Runtime.Remoting.WellKnownObjectMode.SingleCall);
    System.Diagnostics.Debug.Assert(remoteApplicationNotificationAction == null);
    remoteApplicationNotificationAction = action;
    } /// <summary>
    /// call the running application to do...
    /// </summary>
    /// <param name="name">remote name.</param>
    public static void NotificationRemoteApplication(string name)
    {
    var ra = Activator.GetObject(typeof(IRemoteApplicationInterface), "ipc://" + name + ".IPC/Launch") as IRemoteApplicationInterface;
    if (ra != null)
    {
    ra.RemoteApplicationNotification();
    }
    } #region IRemoteApplicationInterface 成员 static Action remoteApplicationNotificationAction = null;
    void IRemoteApplicationInterface.RemoteApplicationNotification()
    {
    if (remoteApplicationNotificationAction != null)
    {
    remoteApplicationNotificationAction();
    }
    } #endregion
    } static class UniqueEntry
    {
    public static void Run(string name, Action run, Action notification, Func<bool> notify)
    {
    bool created;
    string mname = Environment.UserName + "." + name;
    var mutex = new System.Threading.Mutex(true, @"Local\" + mname, out created);
    if (!created)
    { // 程序在运行中。
    if (notify())
    {
    try
    {
    RemotableApplication.NotificationRemoteApplication(mname);
    }
    catch
    {
    }
    }
    return;
    }
    else
    {
    try
    {
    RemotableApplication.RemoteApplicationNotification(mname, notification);
    }
    catch (Exception ex)
    {
    System.Diagnostics.Debug.WriteLine(ex.ToString());
    return;
    }
    }
    run();
    System.GC.KeepAlive(mutex);
    }
    } /// <summary>
    /// Application Entry Point.
    /// </summary>
    [System.STAThreadAttribute()]
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    static void Main(string[] args)
    {
    AShura.Windows.Helpers.UniqueEntry.Run("myname", () =>
    {
    try
    {
    App app = new App();
    app.InitializeComponent();
    app.Run();
    }
    catch
    {
    System.Windows.Application.Current.Shutdown();
    }
    }, () =>
    {
    if (!System.Windows.Application.Current.Dispatcher.CheckAccess())
    {
    System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
    {
    if (((App)System.Windows.Application.Current).NotifyWindow != null)
    {
    ((App)System.Windows.Application.Current).NotifyWindow.NotifyFromRemoteApplication();
    }
    }));
    }
    else
    {
    if (((App)System.Windows.Application.Current).NotifyWindow != null)
    {
    ((App)System.Windows.Application.Current).NotifyWindow.NotifyFromRemoteApplication();
    }
    }
    }, () => !args.IsServiceMode());
    }
    发一个我以前的代码,不过这个是没有参数的。
    如果你需要命令行参数,那么修改开始的接口方法。并且修改相应的方法。
      

  5.   

    楼上的方法应该是对的。也可以用消息实现,看上去还简单些:using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;public class Program
    {
    [STAThread]
    private static void Main()
    {
    Process current = Process.GetCurrentProcess();
    var runningProcess = Process.GetProcessesByName(current.ProcessName).FirstOrDefault(p => p.Id != current.Id);
    if (runningProcess == null)
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new WindowsApplication1.Form1());
    }
    else
    {
    var hwnd = runningProcess.MainWindowHandle;
    SetForegroundWindow(hwnd);
    SendMessage(hwnd, WM_COMMAND, 101, IntPtr.Zero);
    }
    } [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int wMsg, uint wParam, IntPtr lParam);
    public const int WM_COMMAND = 0x0111;
    }// Form1.cs 文件
    using System;
    using System.Windows.Forms;namespace WindowsApplication1
    {
    public partial class Form1 : Form
    {
    private TabControl _tabs; public Form1()
    {
    InitializeComponent();
    _tabs = new TabControl() {Dock = DockStyle.Fill};
    Controls.Add(_tabs);
    } private int i = 0;
    protected override void WndProc(ref Message m)
    {
    if (m.Msg == Program.WM_COMMAND && (uint)m.WParam == 101)
    {
    var page = new TabPage("File" +(++i));
    _tabs.TabPages.Add(page);
    return;
    }
    base.WndProc(ref m);
    }
    }
    }
      

  6.   

    像你这样做的话main函数的参数应该怎么传递啊...你这样不是说从第二次之后运行的程序参数一直是一开的么..
      

  7.   

    传递参数可以用WM_COPYDATA:using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;public class Program
    {
    [STAThread]
    private static void Main()
    {
    Process current = Process.GetCurrentProcess();
    var runningProcess = Process.GetProcessesByName(current.ProcessName).FirstOrDefault(p => p.Id != current.Id);
    if (runningProcess == null)
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new WindowsApplication1.Form1());
    }
    else
    {
    var hwnd = runningProcess.MainWindowHandle;
    SetForegroundWindow(hwnd);
    var cd = new COPYDATASTRUCT();
    cd.lpData = "test " + DateTime.Now;
    cd.cbData = cd.lpData.Length+1;
    SendMessage(hwnd, WM_COPYDATA, 101, ref cd);
    }
    } public struct COPYDATASTRUCT
    {
    public uint dwData;
    public int cbData;
    public string lpData;
    } [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int wMsg, uint wParam, IntPtr lParam);
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int wMsg, uint wParam, ref COPYDATASTRUCT lParam);
    public const int WM_COMMAND = 0x0111;
    public const int WM_COPYDATA = 74;
    }// Form1.cs 文件
    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;namespace WindowsApplication1
    {
    public partial class Form1 : Form
    {
    private TabControl _tabs; public Form1()
    {
    InitializeComponent();
    _tabs = new TabControl() { Dock = DockStyle.Fill };
    Controls.Add(_tabs);
    } private int i = 0;
    protected override void WndProc(ref Message m)
    {
    if (m.Msg == Program.WM_COPYDATA && (uint)m.WParam == 101)
    {
    var cd = (Program.COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(Program.COPYDATASTRUCT));
    var page = new TabPage("File" + (++i));
    page.Controls.Add(new Label(){Text = cd.lpData, AutoSize = true});
    _tabs.TabPages.Add(page);
    return;
    }
    base.WndProc(ref m);
    }
    }
    }
      

  8.   

    刚刚我也恰巧查到了用结构体来解决传递string的问题,但是这个程序用消息的话有一个问题就是如果我第一次执行这个程序,那么是建立了一个空的Form,并不会新建tab什么的,我必须再次运行才会新建一个tab,请问这个有办法解决么..
      

  9.   

    那你就在初始化时加上page就行了:
    public Form1()
    {
        InitializeComponent();
        _tabs = new TabControl() { Dock = DockStyle.Fill };
        Controls.Add(_tabs);
        var page = new TabPage("File0");
        _tabs.TabPages.Add(page);
    }