You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UiPath类库活动与独立WinForms项目间实现数据交互

问题解答:UiPath活动与独立WinForms项目的通信及程序集引用

一、手动在WinForms项目中引用System.Activities和System.ComponentModel

按以下步骤操作:

  • 右键WinForms项目 → 选择添加 → 引用
  • 在弹出的引用管理器中切换到程序集 → 框架标签
  • 在列表中找到System.Activities和System.ComponentModel,勾选后点击确定
  • 若列表中找不到,可通过浏览选项卡手动定位到.NET Framework安装目录(通常为C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\vX.X\,X.X对应你的.NET版本),选择对应DLL添加引用

二、两个独立DLL项目间的通信(传递DataTable)

针对你的场景,推荐以下三种方案,可根据数据量和交互需求选择:

方案1:命令行参数传递序列化数据(小数据量场景)

将DataTable序列化为XML字符串,作为命令行参数传递给WinForms程序,再反序列化还原。

类库(UiPath活动)代码修改:

using System;
using System.Activities;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Xml.Serialization;
using System.Diagnostics;

namespace Datatable_Visualizer_Activity
{
    public class DatatableVisualizer : CodeActivity
    {
        [DisplayName("Datatable")]
        public InArgument<DataTable> Datatable { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            DataTable dt = Datatable.Get(context);
            
            // 序列化DataTable为XML
            string xmlData;
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
                serializer.Serialize(sw, dt);
                xmlData = sw.ToString();
            }
            
            // 启动WinForms程序并传递参数
            ProcessStartInfo psi = new ProcessStartInfo
            {
                FileName = "Data_Table_Visualizer___Editor.exe",
                Arguments = $"\"{xmlData}\"" // 用引号包裹避免特殊字符截断
            };
            Process.Start(psi);
        }
    }
}

WinForms项目代码修改:

首先修改Program.cs接收命令行参数:

using System;
using System.Windows.Forms;

namespace Data_Table_Visualizer___Editor
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm(args));
        }
    }
}

然后修改MainForm.cs:

using MaterialSkin;
using MaterialSkin.Controls;
using System.Data;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
using System.Xml.Serialization;

namespace Data_Table_Visualizer___Editor
{
    public partial class MainForm : Form
    {
        private DataTable dataTable;

        public MainForm(string[] args)
        {
            this.DoubleBuffered = true;
            InitializeComponent();
            dataGridView.Visible = false;
            ShowLoading(true);
            
            // 解析命令行参数还原DataTable
            if (args.Length > 0)
            {
                string xmlData = args[0];
                using (StringReader sr = new StringReader(xmlData))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
                    dataTable = (DataTable)serializer.Deserialize(sr);
                }
            }
            
            InitializeDataGridViewAsync();
        }

        private void ShowLoading(bool show)
        {
            progressBar.Visible = show;
        }

        private async void InitializeDataGridViewAsync()
        {
            await Task.Run(() =>
            {
                Invoke(new Action(() =>
                {
                    if (dataTable != null)
                    {
                        dataGridView.DataSource = dataTable;
                        dataGridView.DoubleBuffered(true);
                        dataGridView.AutoResizeColumns();

                        label_TotalNoColumns.Text = $"Total No Of Columns = {dataTable.Columns.Count}";
                        label_TotalNoRows.Text = $"Total No Of Rows = {dataTable.Rows.Count}";
                    }
                    ShowLoading(false);
                    dataGridView.Visible = true;
                }));
            });
        }

        private void dataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
        {
            e.Column.FillWeight = 10;
        }
    }

    public static class ExtensionMethods
    {
        public static void DoubleBuffered(this DataGridView dgv, bool setting)
        {
            Type dgvType = dgv.GetType();
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
            pi.SetValue(dgv, setting, null);
        }
    }
}

方案2:内存映射文件(大数据量场景)

当DataTable数据量较大时,命令行参数长度受限,可使用内存映射文件共享数据:

类库端核心代码:

using System.IO.MemoryMappedFiles;
using System.Runtime.Serialization.Formatters.Binary;

// ... 其他引用
protected override void Execute(CodeActivityContext context)
{
    DataTable dt = Datatable.Get(context);
    
    // 序列化为字节数组
    byte[] data;
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(ms, dt);
        data = ms.ToArray();
    }
    
    // 创建内存映射文件
    using (var mmf = MemoryMappedFile.CreateNew("DataTableMMF", data.Length))
    {
        using (var stream = mmf.CreateViewStream())
        {
            stream.Write(data, 0, data.Length);
        }
        
        // 启动WinForms程序并传递映射文件名
        Process.Start("Data_Table_Visualizer___Editor.exe", "DataTableMMF");
    }
}

WinForms端核心代码:

// 在MainForm构造函数中添加
if (args.Length > 0)
{
    string mmfName = args[0];
    using (var mmf = MemoryMappedFile.OpenExisting(mmfName))
    {
        using (var stream = mmf.CreateViewStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            dataTable = (DataTable)formatter.Deserialize(stream);
        }
    }
}

方案3:WCF本地命名管道(双向交互场景)

若需要WinForms向UiPath活动返回修改后的DataTable,可使用WCF的NetNamedPipeBinding:

  1. 定义共享契约接口(单独创建类库供两个项目引用)
  2. UiPath活动作为服务端发布数据,WinForms作为客户端连接获取数据
  3. 完成交互后可通过回调机制将修改后的数据返回

此方案复杂度较高,适合有双向通信需求的场景。

三、NuGet打包注意事项

  • 在NuSpec文件中通过<files>节点配置,将WinForms的EXE和类库DLL一起打包
  • UiPath活动中需通过NuGet安装路径动态定位WinForms EXE的位置,避免硬编码路径

内容的提问来源于stack exchange,提问作者Vasant Raval

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:52:07