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

如何从独立C#程序访问Windows服务中创建的对象?

Absolutely you can access those objects from a standalone C# app—you just need to use inter-process communication (IPC) since the Windows Service runs in its own isolated process space, so you can't directly reach into its memory. Let's walk through the most common, practical ways to do this:

1. Named Pipes (Windows Native IPC)

This is a lightweight, reliable option built into Windows, perfect for simple one-way or two-way data transfer between local processes.

Service Side (Windows Service)

Set up a named pipe server to listen for client connections, then serialize your populated objects and send them over the pipe:

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

// Inside your Windows Service's logic
public void StartPipeServer()
{
    // Use a unique pipe name to avoid conflicts
    using var serverStream = new NamedPipeServerStream("MyServiceDataPipe", PipeDirection.InOut);
    serverStream.WaitForConnection();

    // Assume 'populatedObject' is your object from the database
    var serializedData = JsonSerializer.Serialize(populatedObject);
    
    using var writer = new StreamWriter(serverStream);
    writer.WriteLine(serializedData);
    writer.Flush();
}

Client Side (Standalone C# App)

Connect to the existing pipe, read the serialized data, and deserialize it back into your object type:

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

// Inside your standalone app
public YourObjectType GetDataFromService()
{
    using var clientStream = new NamedPipeClientStream(".", "MyServiceDataPipe", PipeDirection.InOut);
    clientStream.Connect(5000); // Timeout after 5 seconds

    using var reader = new StreamReader(clientStream);
    var serializedData = reader.ReadLine();
    
    return JsonSerializer.Deserialize<YourObjectType>(serializedData);
}
2. WCF (Windows Communication Foundation)

Great if you need more advanced features like bidirectional calls, transaction support, or multiple communication protocols.

Step 1: Define a Service Contract

Create a shared interface that both the service and client will use:

using System.ServiceModel;

[ServiceContract]
public interface IDataRetrievalService
{
    [OperationContract]
    YourObjectType GetLatestDatabaseObject();
}

Step 2: Host the Service in Your Windows Service

Implement the contract and host it using a named pipe binding (for local communication):

using System.ServiceModel;

public class DataRetrievalService : IDataRetrievalService
{
    public YourObjectType GetLatestDatabaseObject()
    {
        // Fetch and return your populated object from the database
        return YourDatabaseHelper.FetchAndPopulateObject();
    }
}

// Inside your Windows Service's OnStart method
var serviceHost = new ServiceHost(typeof(DataRetrievalService));
var pipeBinding = new NetNamedPipeBinding();
serviceHost.AddServiceEndpoint(
    typeof(IDataRetrievalService),
    pipeBinding,
    "net.pipe://localhost/MyDataService"
);
serviceHost.Open();

Step 3: Call the Service from Your Standalone App

Add a service reference (or use channel factory) to call the service method directly:

using System.ServiceModel;

public YourObjectType GetDataFromService()
{
    var binding = new NetNamedPipeBinding();
    var endpoint = new EndpointAddress("net.pipe://localhost/MyDataService");
    
    using var factory = new ChannelFactory<IDataRetrievalService>(binding, endpoint);
    var serviceClient = factory.CreateChannel();
    
    return serviceClient.GetLatestDatabaseObject();
}
3. gRPC (Modern, High-Performance IPC)

Ideal if you want cross-platform support or need efficient serialization (uses Protobuf under the hood).

Step 1: Define a .proto File

Create a proto file to describe your data structure and service methods:

syntax = "proto3";

service DataService {
  rpc GetLatestObject (EmptyRequest) returns (YourObject);
}

message EmptyRequest {}

message YourObject {
  string item_name = 1;
  int32 item_id = 2;
  // Add all your object properties here
}

Step 2: Implement the gRPC Service in Your Windows Service

Generate C# code from the proto file, then implement the service:

using Grpc.Core;

public class DataServiceImpl : DataService.DataServiceBase
{
    public override Task<YourObject> GetLatestObject(EmptyRequest request, ServerCallContext context)
    {
        var dbObject = YourDatabaseHelper.FetchAndPopulateObject();
        // Map your C# object to the gRPC-generated YourObject type
        return Task.FromResult(new YourObject
        {
            ItemName = dbObject.ItemName,
            ItemId = dbObject.ItemId
        });
    }
}

// Inside your Windows Service's OnStart method
var grpcServer = new Server
{
    Services = { DataService.BindService(new DataServiceImpl()) },
    Ports = { new ServerPort("localhost", 50051, ServerCredentials.Insecure) }
};
grpcServer.Start();

Step 3: Call the gRPC Service from Your Standalone App

Generate client code from the proto file, then connect and call the service:

using Grpc.Net.Client;

public YourObject GetDataFromService()
{
    using var channel = GrpcChannel.ForAddress("http://localhost:50051");
    var client = new DataService.DataServiceClient(channel);
    
    return client.GetLatestObject(new EmptyRequest());
}
Key Notes to Remember
  • Serialization Consistency: Make sure both the service and client use the same serialization format (JSON, Protobuf, etc.) and have identical definitions of your object type.
  • Permissions: Windows Services often run under restricted accounts—ensure your standalone app has permission to access the IPC endpoint (e.g., set appropriate security for named pipes).
  • Thread Safety: If multiple clients connect at once, add concurrency handling in your service to avoid race conditions when accessing database data or shared objects.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:52:05