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

C#桌面应用与Flutter桌面应用能否离线互传字符串参数?

无网络环境下C#与Flutter桌面应用的本地通信方案

下面是几种无需网络的本地进程间通信(IPC)方案,直接适配C#和Flutter桌面应用,可实现字符串参数的互相传递:

1. 命名管道(Named Pipes)

这是Windows平台原生的IPC机制,跨语言兼容性好,C#和Flutter都能轻松实现。

C# 端实现(服务器/客户端)

using System.IO.Pipes;
using System.Text;

// 作为服务器监听管道
var pipeServer = new NamedPipeServerStream("FlutterCSharpIPC", PipeDirection.InOut);
pipeServer.WaitForConnection();

// 读取Flutter发来的字符串
byte[] buffer = new byte[1024];
int bytesRead = pipeServer.Read(buffer, 0, buffer.Length);
string receivedMsg = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"收到Flutter消息: {receivedMsg}");

// 发送响应给Flutter
string response = "C#已接收消息,这是响应";
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
pipeServer.Write(responseBytes, 0, responseBytes.Length);

pipeServer.Close();

Flutter 端实现(客户端)

可以用named_pipes第三方包简化开发:

import 'package:named_pipes/named_pipes.dart';

void main() async {
  final pipe = NamedPipeClient('FlutterCSharpIPC');
  await pipe.connect();

  // 发送字符串给C#
  await pipe.writeString("来自Flutter的测试消息");

  // 读取C#的响应
  String response = await pipe.readString();
  print("收到C#响应: $response");

  await pipe.disconnect();
}

注意:管道名称必须完全一致,Windows下要注意权限设置;如果是Linux/macOS平台,可以改用Unix域套接字实现类似逻辑。

2. 共享内存(Shared Memory)

适合高频、低延迟的消息传递,通过一块共享的内存区域实现数据交换。

C# 端实现

using System.IO.MemoryMappedFiles;
using System.Text;

// 创建或打开共享内存区域
using var mmf = MemoryMappedFile.CreateOrOpen("CSharpFlutterSharedMem", 1024);
using var stream = mmf.CreateViewStream();
using var writer = new BinaryWriter(stream);

// 写入字符串到共享内存
writer.Write("来自C#的共享内存消息");
writer.Flush();

// 读取Flutter写入的内容(可选)
stream.Position = 0;
using var reader = new BinaryReader(stream);
string receivedMsg = reader.ReadString();
Console.WriteLine($"共享内存收到Flutter消息: {receivedMsg}");

Flutter 端实现

使用shared_memory包操作共享内存:

import 'dart:convert';
import 'package:shared_memory/shared_memory.dart';

void main() async {
  // 打开共享内存
  int shmId = await SharedMemory.createOrOpen("CSharpFlutterSharedMem", 1024);
  
  // 读取C#写入的字符串
  Uint8List buffer = await SharedMemory.read(shmId, 0, 1024);
  String receivedMsg = utf8.decode(buffer).trim();
  print("共享内存收到C#消息: $receivedMsg");

  // 写入消息到共享内存
  Uint8List sendBuffer = utf8.encode("来自Flutter的共享内存消息");
  await SharedMemory.write(shmId, 0, sendBuffer);

  // 关闭共享内存
  await SharedMemory.close(shmId);
}

注意:共享内存没有内置同步机制,需要额外加互斥锁(比如C#用Mutex,Flutter用win32插件调用系统Mutex)避免读写冲突。

3. 本地文件监听(File Watcher)

适合低频率、简单的消息传递逻辑,通过监听指定本地文件的内容变化实现通信。

C# 端实现

using System.IO;
using System.Text;

// 监听消息文件变化
var watcher = new FileSystemWatcher(@"C:\Temp", "IPC_Message.txt");
watcher.Changed += (sender, e) => {
    string content = File.ReadAllText(e.FullName, Encoding.UTF8);
    Console.WriteLine($"收到文件消息: {content}");
    // 写入响应到指定文件
    File.WriteAllText(@"C:\Temp\IPC_Response.txt", "C#已接收消息");
};
watcher.EnableRaisingEvents = true;

// 发送消息到文件
File.WriteAllText(@"C:\Temp\IPC_Message.txt", "来自C#的文件消息");

Flutter 端实现

用path_provider获取本地目录,file_watcher监听文件变化:

import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:file_watcher/file_watcher.dart';

void main() async {
  Directory tempDir = await getTemporaryDirectory();
  String msgPath = "${tempDir.path}/IPC_Message.txt";
  String respPath = "${tempDir.path}/IPC_Response.txt";

  // 监听消息文件
  final watcher = FileWatcher(msgPath);
  watcher.events.listen((event) {
    if (event.type == ChangeType.modified) {
        String content = File(msgPath).readAsStringSync();
        print("收到文件消息: $content");
        File(respPath).writeAsStringSync("Flutter已接收消息");
    }
  });

  // 发送消息到文件
  File(msgPath).writeAsStringSync("来自Flutter的文件消息");
}

注意:要处理文件读写的并发问题,避免文件被占用,适合逻辑简单、对实时性要求不高的场景。

4. Windows消息(仅限Windows平台)

如果你的两个应用都运行在Windows上,用Windows消息机制是最轻便的方案,直接通过窗口句柄传递字符串。

C# 端实现

using System;
using System.Runtime.InteropServices;

public static class Win32API {
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow(string className, string windowName);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
}

void SendMessageToFlutter() {
    // 通过窗口标题查找Flutter应用窗口句柄
    IntPtr flutterWindow = Win32API.FindWindow(null, "Flutter App");
    if (flutterWindow != IntPtr.Zero) {
        // 自定义消息ID(WM_USER + 0x100,避免系统消息冲突)
        const uint WM_CUSTOM_MSG = 0x0400 + 0x100;
        // 将字符串转为指针传递
        string msg = "来自C#的Windows消息";
        IntPtr msgPtr = Marshal.StringToHGlobalAuto(msg);
        Win32API.SendMessage(flutterWindow, WM_CUSTOM_MSG, IntPtr.Zero, msgPtr);
        Marshal.FreeHGlobal(msgPtr);
    }
}

Flutter 端实现

用win32插件监听窗口消息:

import 'package:win32/win32.dart';

void main() {
  // 获取当前Flutter窗口句柄
  final hWnd = GetForegroundWindow();

  // 保存原有窗口过程,用于回调转发
  WNDPROC? oldProc;

  int windowProc(int hWnd, uint uMsg, int wParam, int lParam) {
    const WM_CUSTOM_MSG = 0x0400 + 0x100;
    if (uMsg == WM_CUSTOM_MSG) {
        // 解析收到的字符串
        String msg = Marshal.PtrToStringAuto(lParam);
        print("收到Windows消息: $msg");
        // 可选:发送响应给C#(需要提前获取C#窗口句柄)
        // SendMessage(cSharpWndHandle, WM_CUSTOM_MSG, 0, Marshal.StringToHGlobalAuto("Flutter已收到").address);
    }
    // 调用原有窗口过程处理其他消息
    return CallWindowProc(oldProc!, hWnd, uMsg, wParam, lParam);
  }

  // 设置自定义窗口过程
  oldProc = SetWindowLongPtr(hWnd, GWLP_WNDPROC, Pointer.fromFunction<IntPtr Function(IntPtr, UInt32, IntPtr, IntPtr)>(windowProc));
}

注意:自定义消息ID要两端保持一致,窗口句柄可以通过标题、进程ID等方式获取。


方案选择建议

  • 跨平台需求:优先选命名管道(Windows)/Unix域套接字(Linux/macOS),或共享内存
  • Windows专属场景:Windows消息最轻便高效
  • 简单低频率通信:本地文件监听成本最低

内容的提问来源于stack exchange,提问作者Pedro Lincolm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:56:03