0

我正在尝试在 c# .NET Framework 4.6 上制作一个简单的控制台应用程序客户端(starter.exe),以使用 Wireguard 源代码建立基于 WireGuard 协议的连接。

做了什么:

  • 从这里下载的wireguard源代码:git://git.zx2c4.com/wireguard-windows
  • 通过 build.bat在..\embeddable-dll-service\amd64\tunnel.dll中成功构建 Tunnel.dll
  • 在 Visual Studio 2015 中创建了一个项目。使用来自..\embeddable-dll-service\csharp的 c# 代码

从这里开始,一些奇怪的事情正在发生:

  • 如果启动 starter.exe \service <path to *.conf> 我收到错误

服务运行错误:服务进程无法连接到服务控制器。

  • 如果在没有参数的情况下启动 starter.exe 一切正常,直到我删除if{}块:

未处理的异常:System.ComponentModel.Win32Exception:服务没有及时响应
D:\Depository\BitBucket\WireGuard_Tunnel_Repository\WireGuardTunnel_proj\Launcher\Service 中 WireGuardTunnel.Service.Add(String configFile) 的启动或控制请求。 cs: WireGuardTunnel.Program.Main(String[] args) 中的第 69 行 D:\Depository\BitBucket\WireGuard_Tunnel_Repository\WireGuardTunnel_proj\Launcher\Program.cs:第 83 行

这意味着即使 if{} 块中的代码没有执行,它也会以某种方式影响应用程序的行为。

  • 接下来,由于我想让我的应用程序使用参数,我通过删除 Service.Run 后的 return 并将 args[1] 传递给 Service.Add(args[1]) 解决了这个问题。它工作正常,但我在日志中有一个额外的日志行(由于上面描述的 Service.Run 永久错误,第一个日志行):

服务运行错误:服务进程无法连接到服务控制器。
235660:[TUN] [chicago4] 监视网络接口
245661:[TUN] [chicago4] 解析 DNS 名称
245661:[TUN] [chicago4] 创建 Wintun 接口
225660:[TUN] [chicago4] 启动 WireGuard/0.3.1(Windows 6.1 .7601;amd64)

所以最后的问题:

  1. 为什么 Service.Run(confFile) 不起作用
  2. 为什么 Service.Run(confFile) 会影响 Service.Add(confFile)
  3. 为什么在我启动不带参数的 starte.exe 时执行 if{} 块

未经修改的原Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;

namespace Tunnel
{
    class Program
    {

        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(SetConsoleCtrlEventHandler handler, bool add);
        private delegate bool SetConsoleCtrlEventHandler(UInt32 signal);

        public static void Main(string[] args)
        {
            string baseDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
            string configFile = Path.Combine(baseDirectory, "demobox.conf");
            string logFile = Path.Combine(baseDirectory, "log.bin");

            if (args.Length == 2 && args[0] == "/service")
            {
                configFile = args[1];
                Service.Run(configFile);
                return;
            }

            try { File.Delete(logFile); } catch { }
            Ringlogger log = new Ringlogger(logFile, "GUI");

            var logPrintingThread = new Thread(() =>
            {
                var cursor = Ringlogger.CursorAll;
                while (Thread.CurrentThread.IsAlive)
                {
                    var lines = log.FollowFromCursor(ref cursor);
                    foreach (var line in lines)
                        Console.WriteLine(line);
                    Thread.Sleep(300);
                }
            });

            logPrintingThread.Start();

            SetConsoleCtrlHandler(delegate
            {
                Service.Remove(configFile);
                Environment.Exit(0);
                return true;
            }, true);

            try
            {
                Service.Add(configFile);
                logPrintingThread.Join();
            }
            finally
            {
                Service.Remove(configFile);
            }
        }
    }
}
4

0 回答 0