如何在Windows 10 IoT中设置系统时间?

16

在运行Windows 10 IoT Core Insider Preview的Raspberry Pi 2上,有没有一种方法可以从我的应用程序设置系统时间?

由于缺少kernel32.dll,这种方法行不通。

    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    extern static bool Win32SetSystemTime(ref SystemTime sysTime);

我没有看到任何“功能”,可以让你从沙盒内部执行该操作--https://msdn.microsoft.com/zh-cn/library/windows/apps/hh464936.aspx - Ben Voigt
除了程序代码之外,您应该能够在IOT设备上打开PowerShell并运行“Set-Date”命令。 - Dai
嗯,PowerShell 可以用,我一直都是这样做的,但是由于没有系统界面,这意味着作为独立设备,准确的时间无法得到保证。希望他们在发布时能解决这个问题。时钟似乎会显著漂移,特别是如果设备被关闭然后重新开启。(例如,过夜关闭导致近10分钟的误差) - raven-ai
树莓派没有RTC,因此每次启动都需要从NTP服务器获取时间。如果您不满意此功能,您可以购买一些RTC附件,例如这里提供的:http://thepihut.com/products/mini-rtc-module-for-raspberry-pi。 - dannykay1710
从实证测试来看,它似乎要么不会自动获取NTP数据,要么通常不会。在过去的半打或更多次启动中,它始终从一个月前的同一时间开始,并保持在那里。 - raven-ai
显示剩余4条评论
8个回答

11

首先,使用PowerShell连接您的Pi 2

使用命令set-date设置时间。例如,如果你想将日期设置为2015年10月3日星期六下午2:00,你可以输入set-date 10/3/2015 2:00PM

tzutil命令设置时区。键入tzutil /?以获取用法。


1
问题是如何从应用程序中设置它。正如评论中提到的,我知道如何从PowerShell中设置它。然而,每次打开设备时连接到PowerShell来设置时间是不切实际的。如果设备始终需要连接到计算机才能使用,那么它将变得无法使用。 - raven-ai
4
日期应该用引号括起来:set-date "10/3/2015 2:00PM" - Maxence
我使用 set-date "8/25/2017 2:32PM" 设置日期时间,但过一段时间后它会重置 / 更改。因此,需要使用 tzutil 正确设置时区,因为树莓派将自动尝试基于时间服务器更新当前日期时间。 - T.S
这个“最佳答案”已经过时了。现在只需使用Windows提供的API DateTimeSettings.SetSystemDate即可。 - Dane Bouchie

8

1-新的通用项目
2-添加引用>扩展>Windows IOT扩展程序集适用于UWP
3-在你的MainPage.xaml上放置一个按钮、日期选择器和时间选择器控件
并且

private void buttonSetSystemDatetime_Click(object sender, RoutedEventArgs e)
        {
            DateTimeOffset dto = datePicker1.Date+ timePicker1.Time;
            Windows.System.DateTimeSettings.SetSystemDateTime(dto);
        }

4- 在项目设置中> 设置您的目标版本和最低版本10.0;构建16299

5- 双击appxmanifest > Capabilities > 打开“系统管理”复选框

6- 在IOT中运行应用程序并按下按钮。 然后返回默认应用程序。 瞧!系统日期时间已更改。

注:为了不必每次都设置,我建议您购买一个廉价的RTC(实时时钟)模块。(还需要额外编码)


我使用了https://dev59.com/6HM_5IYBdhLWcg3w3nNs#33328911中的答案,以便在由于SAS令牌过期而导致与IoT Hub的连接失败时强制进行时间同步。 - Chris Schaller

4
您可以在UWP/IoT-Core系统中从C#调用任何PowerShell例程。因此,PowerShell命令始终可用于/在您的应用程序中。
例如,请参见GitHub上的ProcessLauncher示例

另一种选择是按以下方式安排启动PS脚本:

在板子上以管理员身份运行PowerShell(按Windows按钮并开始键入PowerShell,在图标上右键单击并选择“以管理员身份运行”)。
Set-ExecutionPolicy RemoteSigned
作为管理员 PuTTy 到 RPi 并:
setx PATH“%PATH%; C:\Windows\System32”
schtasks /create /tn "StartupPowerShell" /tr c:\Startup.bat /sc onstart /ru SYSTEM

Startup.bat

powershell -command "C:\IotCoreStartup.ps1"

IotCoreStartup.ps

$logFile = 'C:\StartupLog.txt'

get-date > $logFile

tzutil /s "UTC" >> $logFile

# set alternate time servers
"Setting additional time servers" >> $logFile
w32tm /config /syncfromflags:manual /manualpeerlist:"0.windows.time.com 1.pool.ntp.org" >> $logFile

如果需要,删除预定任务:

schtasks /Delete /TN "StartupPowerShell"

运行预定任务以进行测试:

schtasks /Run /tn "StartupPowerShell"


不,你不能在UWP应用程序中调用PowerShell命令。根据:https://social.msdn.microsoft.com/Forums/sqlserver/en-US/7835e702-7bff-4076-a2da-006e6828d940/uwprun-powershell-commands-inside-of-an-uwa-with-c?forum=wpdevelop - ftes
2
它通过ProcessLauncher(https://ms-iot.github.io/content/en-US/win10/samples/ProcessLauncherSample.htm)工作。只需调用一个脚本.cmd,然后使用PowerShell。有点复杂,但是可以工作。我会查看您提供的链接,谢谢。 - GGleGrand

3
目前似乎没有办法实际编辑系统时间,但我想到了一个解决方法,可以在您的应用程序中获得正确的时间。我创建了一个TimeManager类,其中重要的部分如下。
以任何方式获取正确的时间(例如NTP、其他网络时间、用户输入等),然后将其输入UpdateOffset方法。
在应用程序的其余部分中,使用TimeManager.Now而不是DateTime.Now。
    static TimeSpan _offset = new TimeSpan(0,0,0);
    public static TimeSpan CurrentOffset //Doesn't have to be public, it is for me because I'm presenting it on the UI for my information
    {
        get { return _offset; }
        private set { _offset = value; }
    }

    public static DateTime Now
    {
        get
        {
            return DateTime.Now - CurrentOffset;
        }
    }

    static void UpdateOffset(DateTime currentCorrectTime) //May need to be public if you're getting the correct time outside of this class
    {
        CurrentOffset = DateTime.UtcNow - currentCorrectTime;
        //Note that I'm getting network time which is in UTC, if you're getting local time use DateTime.Now instead of DateTime.UtcNow. 
    }

我建议添加跟踪最后更新时间和标志来指示时间是否已经更新,但不想使代码示例混乱。

3
我使用了一个RTC来设置我的树莓派的时间。虽然Windows iot没有原生支持从实时时钟初始化树莓派的软件时钟,但经过几个小时的考虑后,我找到了适合我的方法。
我制作了一个控制台程序,可以将系统时间保存到RTC,也可以将RTC中的时间读取并打印为字符串。我编写了一个Power Shell脚本,将在系统启动时运行此程序,从实时时钟获取时间并将字符串传递给set-date命令。
详情请参见:http://www.codeproject.com/Articles/1113626/Adding-the-Missing-Real-Time-Clock-to-Windows-IoT

2
使用Renci SSH shell以管理员身份重新登录设备,然后使用powershell命令设置日期和时间。
public static int SshCommand(string command, out string dataOut, out string error)
    {

        dataOut = "";
        error = "";

        try
        {

            using (var client = new SshClient("127.0.0.1", USER_NAME, PASSWORD))
            {
                client.Connect();
                //command = "powershell -Command " + "\u0022" + "set-date -date '8/10/2017 8:30:00 AM'" + "\u0022";
                //command = "netsh interface ip show config";
                var cmd = client.RunCommand(command);
                var output = cmd.Result;
                client.Disconnect();
            }

            return 1;
        }
        catch (Exception ex)
        {
            error = ex.Message;
            return 0;
        }

    }


public static int SSHSetDateTime(DateTime dateTime)
    {

        // Variables
        int returnValue = 0;
        string command;
        string error;
        string dataOut;

        // Build date
        command = String.Format("powershell -Command \u0022set-date -date '{0:M/d/yyyy H:mm:ss tt}'\u0022", dateTime);

        //Build date
        if (SystemEx.SshCommand(command, out dataOut, out error) == 1)
        {
            // Ok
            returnValue = 1;
        }

        // Return
        return returnValue;

    }

1
我知道您在询问如何以编程方式执行此操作,但以下内容应足以提供足够的信息,以创建一个在启动时运行的PS脚本。 通过PowerShell远程访问Raspberry Pi 1.) 在您的开发PC上运行Windows 10 IoT Core Watcher实用程序(C:\Program Files (x86)\Microsoft IoT\WindowsIoTCoreWatcher.exe),通过右键单击检测到的设备并选择复制IP地址来复制您的树莓派IP地址。
◦ 单击Windows“开始”按钮
◦ 键入“WindowsIoTCoreWatcher”以在搜索结果中找到它
◦ 您可能希望右键单击程序名称并选择“固定到开始屏幕”,以便轻松访问它
◦ 按Enter键运行它
◦ 您的设备应该在大约5秒钟内出现在列表中。如果没有,请关闭Windows 10 IoT Core Watcher,并再次启动它

Windows IoT Core Watcher

2.) 在本地计算机上启动管理员PowerShell控制台。最简单的方法是在Windows开始菜单附近的“搜索Web和Windows”文本框中输入“powershell”。Windows会在您的计算机上找到PowerShell。右键单击Windows PowerShell条目,然后选择以管理员身份运行。PS控制台将显示。

Running Powershell as Administrator

3.) 您可能需要在桌面上启动WinRM服务以启用远程连接。从PS控制台输入以下命令:

 net start WinRM 

4.) 在PS控制台中,键入以下命令,将''替换为先前复制的IP值:

 Set-Item WSMan:\localhost\Client\TrustedHosts -Value <machine-name or IP Address>

5. 输入 Y 并按回车键确认更改。

6. 现在,您可以使用 Windows IoT Core 设备开始会话。从管理员 PowerShell 控制台中,输入:

Enter-PSSession -ComputerName <IP Address> -Credential localhost\Administrator

7. 在凭据对话框中输入以下默认密码:

p@ssw0rd

注意:连接过程不是立即进行的,可能需要长达30秒的时间。

如果成功连接到设备,则应在提示符之前看到设备的IP地址。

Connected to the Raspberry using PS

重命名设备并设置日期和时间

1. 要更改计算机名称,请使用 setcomputername 实用程序。在 PowerShell 中,键入以下命令。

setcomputername

2. Pi 上的日期和时间必须正确,以便稍后在实验中使用的安全令牌发布到 Azure 时有效。要检查 Pi 上当前的时区设置,请键入:

tzutil /g

3. 如果报告的时区不正确,则可以使用以下命令找到有效时区列表(您可能需要增加 powershell 窗口的缓冲区大小):

tzutil /l

4. 要设置时区,请从上一步骤中找到所需时区的 ID,然后使用以下命令:

tzutil /s "Your TimeZone Name"

例如,“太平洋标准时间”:

tzutil /s "Pacific Standard Time"

5. 要检查 Raspberry Pi 上的日期,请键入

Get-Date

如果日期或时间不正确,使用 Set-Date 实用程序。
例如,如果是2016年1月3日下午12:15,则输入以下命令:
Set-Date "01/03/16 12:15 PM"
重新启动设备以使更改生效。您可以使用以下关闭命令:
shutdown /r /t 0

有趣的是,在Win IOT中,设置日期根本不起作用。 - Zen Of Kursat

1
请参考Microsoft API参考文档,在Windows.System命名空间中,您可以使用SetSystemDateTime方法来设置系统日期和时间。
但是,您必须知道它仅适用于以下版本:Windows IoT Extension SDK(引入v10.0.16225.0)及以上。您可以使用DateTimeSettings静态类。
public static class DateTimeSettings

然后调用SetSystemDateTime静态方法,并发送您的DateTimeOffset类型对象以在Windows Iot上设置日期和时间。
public static void SetSystemDateTime(DateTimeOffset utcDateTime)

https://learn.microsoft.com/en-us/uwp/api/windows.system.datetimesettings


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接