Как перезапустить Linux из приложения. NET Core - PullRequest
0 голосов
/ 21 июня 2020

У меня Raspberry Pi 4 с ОС Raspberry Pi. Я пытаюсь создать. NET Приложение Core 3.1, которое может перезагрузить эту малину. Я нашел этот вопрос на SO. Я следую ответу от @ Dai (используя «lib c .so.6»). Когда я пытаюсь использовать

LINUX_REBOOT_CMD_RESTART
LINUX_REBOOT_CMD_POWER_OFF
LINUX_REBOOT_CMD_RESTART2

, я все еще получаю errno = 1 (должно быть EPERM). Нужно ли мне запускать приложение. NET Core с разрешениями sudo (как я могу это сделать?)? Или мне что-то еще не хватает? Спасибо !!

РЕДАКТИРОВАТЬ: Я использую этот код:

internal static class NativeMethods
    {
        [DllImport("libc.so.6", SetLastError = true)] // You may need to change this to "libc.so.6" or "libc.so.7" depending on your platform)
        public static extern Int32 reboot(Int32 magic, Int32 magic2, Int32 cmd, IntPtr arg);

        public const Int32 LINUX_REBOOT_MAGIC1 = unchecked((int)0xfee1dead);
        public const Int32 LINUX_REBOOT_MAGIC2 = 672274793;
        public const Int32 LINUX_REBOOT_MAGIC2A = 85072278;
        public const Int32 LINUX_REBOOT_MAGIC2B = 369367448;
        public const Int32 LINUX_REBOOT_MAGIC2C = 537993216;

        public const Int32 LINUX_REBOOT_CMD_RESTART = 0x01234567;
        public const Int32 LINUX_REBOOT_CMD_HALT = unchecked((int)0xCDEF0123);
        public const Int32 LINUX_REBOOT_CMD_CAD_ON = unchecked((int)0x89ABCDEF);
        public const Int32 LINUX_REBOOT_CMD_CAD_OFF = 0x00000000;
        public const Int32 LINUX_REBOOT_CMD_POWER_OFF = 0x4321FEDC;
        public const Int32 LINUX_REBOOT_CMD_RESTART2 = unchecked((int)0xA1B2C3D4);
        public const Int32 LINUX_REBOOT_CMD_SW_SUSPEND = unchecked((int)0xD000FCE2);
        public const Int32 LINUX_REBOOT_CMD_KEXEC = 0x45584543;

        public const Int32 EPERM = 1;
        public const Int32 EFAULT = 14;
        public const Int32 EINVAL = 22;
    }


   public static void Restart()
    {
        Int32 ret = reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART, IntPtr.Zero);

        // `reboot(LINUX_REBOOT_CMD_POWER_OFF)` never returns if it's successful, so if it returns 0 then that's weird, we should treat it as an error condition instead of success:
        if (ret == 0) throw new InvalidOperationException("reboot(LINUX_REBOOT_CMD_POWER_OFF) returned 0.");

        // ..otherwise we expect it to return -1 in the event of failure, so any other value is exceptional:
        if (ret != -1) throw new InvalidOperationException("Unexpected reboot() return value: " + ret);

        // At this point, ret == -1, which means check `errno`!
        // `errno` is accessed via Marshal.GetLastWin32Error(), even on non-Win32 platforms and especially even on Linux

        Int32 errno = Marshal.GetLastWin32Error();
        switch (errno)
        {
            case EPERM:
                throw new UnauthorizedAccessException("You do not have permission to call reboot()");

            case EINVAL:
                throw new ArgumentException("Bad magic numbers (stray cosmic-ray?)");

            case EFAULT:
            default:
                throw new InvalidOperationException("Could not call reboot():" + errno.ToString());
        }
    }
...