通过 C# API 调用 Windows Forms 应用程序

Calling a Windows Forms Application via C# API

我有一个用 C# 编写的 windows 表单应用程序,它允许我指向图像文件夹并将这些图像解析为用户易于查看的格式。这是一个独立的应用程序,运行良好。我想扩展这个应用程序,这样我就可以把它交给一个预建的数据集,而不是解析一个图像文件夹,所有的图像和元数据都由外部应用程序通过 API.

我已经能够将应用程序编译成 class 库并访问 classes 和结构来实际构建数据集而没有问题,我现在遇到的问题是启动使用我构建的数据集在外部应用程序。

对于上下文,我正在编写一个工具,允许用户从 Spotfire 调用此 windows 表单应用程序。在 spotfire 中,我正在解析一个 DataTable 对象并根据我拥有的信息构建数据集。构建此数据集后,我需要能够将应用程序作为独立进程启动,而不是在 Spotfire 内部显式调用表单。 (这是由于 Spotfire 中 GUI 线程的限制,我们不能在单线程应用程序中调用多线程进程,而且我们希望保持 Spotfire GUI 响应,如果我们直接调用表单则无法做到这一点)

我知道我可以使用 Process.Start() 独立启动 exe,但是这不允许我将我的信息传递给应用程序。我如何构建此应用程序以允许我将信息传递给它?我一直在尝试 google 如何做到这一点的例子,并不断空手而归,因为人们会参考 ASP.net 或我无法理解的事情。

提前致谢!

编辑:下面是一个很好地处理这个问题的应用程序示例。我们使用 DPlot Jr 在外部创建图形。 dplot.dll 公开了以下函数:

[System.Runtime.InteropServices.DllImport("dplotlib64.dll")]
public static extern int DPlot_Plot8(
    ref DPLOT d, double[] x, double[] y, string cmds);

然后我可以在我的代码中使用它

docNum = dplot.DPlot_Plot8(ref dPlot, X, Y, cmds);
docNums.Add(docNum);

以这种方式调用此函数实际上会启动 dplot 应用程序并传递我构建的对象 "dPlot" 以及 X 和 Y 数据以绘制信息。我想在我的 windows 表单应用程序中构建这样的东西,以便能够从外部应用程序轻松启动它。不幸的是,我不知道这个函数在 .dll

中是如何工作的

EDIT2:我已经能够按照 Aybe 的建议通过命令行修改运行时。在我的桌面应用程序中,我在主程序中创建了一个条件,就像这样。

        if (args.Length == 0 && false)
        {
            Application.Run(new frmWaveFormViewer());
        }
        else
        {
            DataSet dataSet = new DataSet();
            //dataSet.LoadMetaData(args[0]);
            dataSet.LoadMetaData(@"C:\Users\a0273881\AppData\Local\Temp\tmp1141.tmp");
            Application.Run(new frmWaveFormViewer(dataSet));
        }

然后用户可以使用以下命令从外部调用表单...

            DataSet dataSet = new DataSet(dpList);

            dataSet.PrintDatasetMetadataToFile(String.Format(@"C:\Spotfire\DataSetTesting_{0}.csv", DateTime.Now.ToString("yyyyMMdd_HHmmss")));
            string args = dataSet.GetMetaData();

            ProcessStartInfo starter = new ProcessStartInfo();
            starter.FileName = @"C:\Users\a0273881\Desktop\WaveFormViewer.exe";
            starter.Arguments = args;
            Process.Start(starter);

但是,这对其他开发人员来说并不容易使用。

我开始研究 WCF,谁能为傻瓜提供有关 WCF 的良好资源?我目前正在通读:http://www.codemag.com/article/0705041

我已经能够在应用程序启动时在其上生成一个 NamedPipeServer。命名的管道服务器用应用程序的名称+它生成的进程 ID 来命名自己。进程号记录到用户 appdata 文件夹中的 ini 文件中。该过程可以使用可选的命令行参数启动,以影响 "callingApplication" 的值,即 INI Header。这样,我们可以从不同的调用者创建应用程序的多个实例,而不会干扰并确保连接到正确的命名管道。

static void Main(string[] args)
{
    string callingApplication = "None";
    if (args.Length != 0)
    {
        callingApplication = args[0];
    }

    int pId = Process.GetCurrentProcess().Id;
    PipeServer.StartPipeServer(pId, callingApplication);

    // do things

    PipeServer.StopPipeServer();
}

通过 public 静态 class 中可用的 public 函数访问 PipeClient 端。通过管道连接的函数都位于一个单独的 PipeClient class 中。这些函数需要生成的进程 ID 才能连接到正确的管道。这些 api 函数可以从 api

启动或 return 所需的管道
public static class API
{
    public static int SendCommand(int aKey, ...)
    {
        try
        {
            PipeClient.StartCommandSendClient(input, aKey);
        }
        catch (TimeoutException)
        {
            // returns error codes based on exceptions
        }

        return 0; 
    }
}

因此,我设法在两个应用程序之间创建了一个 link。在此之前真正需要的是通过 API class 公开的方法的自定义实现,这些方法也具有要调用的自定义客户端方法。从我的调用应用程序调用所有这些都非常简单...

int aKey = API.GetKey("callingAppName");
API.SendCommand(aKey, "[Reset()][AddPoint(arg1, arg2, arg3)]");