8.1 dev preview 发布以来 Cortana 很受关注

前一段看到有视频演示用 Cortana 来启动 PC

看视频也是启动第三方应用实现的,简单来弄其实就是个语音启动应用 + 网络唤醒么…

也动手山寨一个简单的出来

 

首先先介绍下啥是网络唤醒:

详细去参考维基百科:http://zh.wikipedia.org/wiki/Wake-on-LAN

基本要求就是网卡支持(现代的PC一般是支持的,不过有的需要设置下,开启这个功能)

然后利用UDP往计算机网段广播地址发送一个包含要唤醒计算机的 mac 地址的 Magic Packet,来唤醒计算机。

魔法封包(Magic Packet)是一个广播性的帧(frame),透过埠7或埠9进行发送,且可以用无连接(Connectionless protocol)的通讯协定(如UDPIPX)来传递,不过一般而言多是用UDP,原因是Novell公司Netware网络操作系统的IPX协定已经愈来愈少机会被使用。

在魔法封包内,每次都会先有连续6个"FF"(十六进制,换算成二进制即:11111111)的资料,即:FF FF FF FF FF FF,在连续6个"FF"后则开始带出MAC位址资讯,有时还会带出4字节或6字节的密码,一旦经由网络卡侦测、解读、研判(广播)魔法封包的内容,内容中的MAC位址、密码若与电脑自身的位址、密码吻合,就会启动唤醒、开机的程序。

 

基本原理介绍完了,下面我们动手实现下吧

首先是计算机设置,我找了一台老机器,貌似板子是G31还是G43来着,先进BIOS里设置下支持远程唤醒

 

这个板子是设置允许 wake up by PCIE Card 就行了,不同板子设置不一样,自己看看设置吧

 

 

设置好了之后,我们的 PC 应该就支持网络唤醒了,先要验证下是否好用,找个程序试试,之前那篇维基百科里介绍了很多工具

这里我用的是Magic Packet Utility (http://1drv.ms/1gYESk2),远程唤醒下试试效果

 

验证没问题后我们开始编写程序,首先新建一个wp工程(其实WP从7.1起就支持UDP,不过为了显得高大上我们建立一个8.1的工程吧,当然为了方便改成其他版本的,我们还是继续用silverlight)

 

选择版本为8.1

 

简单画个UI,要远程唤醒我们需要知道两个信息,1是目标计算机的 MAC 地址,2就是目标计算机所处网段的广播地址(啥是广播地址继续参见百科:http://zh.wikipedia.org/wiki/IPv4 中的广播地址  ,基本上说就是把IP 地址最后一位改成 255…)

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel HorizontalAlignment="Left" Height="607" VerticalAlignment="Top" Width="432" Margin="12,0,0,0">
                <TextBlock TextWrapping="Wrap" Text="MAC地址:"/>
                <TextBox x:Name="mac" Height="72" TextWrapping="Wrap" Text="FFFFFFFFFFFF" FontFamily="Portable User Interface"/>
                <TextBlock TextWrapping="Wrap" Text="广播地址:"/>
                <TextBox x:Name="bip" Height="72" TextWrapping="Wrap" Text="192.168.1.255" FontFamily="Portable User Interface"/>
                <Button Content="启  动" Margin="0,50,0,0" Click="Button_Click"/>
            </StackPanel>
        </Grid>

 

我们前面已经看百科的介绍了解的 Magic Packet 的组成(102个字节组成,最前面六个字节为0xFF,其他字节为目的主机的MAC地址(6个字节为一组,共16组))

下面我们需要自己构建 Magic Packet:

                byte[] sendBytes = new byte[102];
                for (int i = 0; i < 6; i++)
                {
                    sendBytes[i] = 0xFF;
                }
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 6; j++)
                    {
                        sendBytes[(i + 1) * 6 + j] = byte.Parse(macAddress.Substring(j * 2, 2), System.Globalization.NumberStyles.HexNumber);
                    }
                }

 

然后发送UDP包的代码就很简单了,主要摘自MSDN:http://msdn.microsoft.com/zh-cn/library/hh202864(v=vs.92).aspx

        public string Send(string BroadcastIP, string macAddress)
        {
            string response = "Operation Timeout";
 
            // We are re-using the _socket object that was initialized in the Connect method
            if (_socket != null)
            {
                // Create SocketAsyncEventArgs context object
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
 
                // Set properties on context object
                socketEventArg.RemoteEndPoint = new DnsEndPoint(BroadcastIP, 7);
 
                // Inline event handler for the Completed event.
                // Note: This event handler was implemented inline in order to make this method self-contained.
                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                {
                    response = e.SocketError.ToString();
 
                    // Unblock the UI thread
                    _clientDone.Set();
                });
 
 
                byte[] sendBytes = new byte[102];
                for (int i = 0; i < 6; i++)
                {
                    sendBytes[i] = 0xFF;
                }
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 6; j++)
                    {
                        sendBytes[(i + 1) * 6 + j] = byte.Parse(macAddress.Substring(j * 2, 2), System.Globalization.NumberStyles.HexNumber);
                    }
                }
 
 
 
                // Add the data to be sent into the buffer
                byte[] payload = sendBytes;
                socketEventArg.SetBuffer(payload, 0, payload.Length);
 
                // Sets the state of the event to nonsignaled, causing threads to block
                _clientDone.Reset();
 
                // Make an asynchronous Send request over the socket
                _socket.SendToAsync(socketEventArg);
 
                // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
                // If no response comes back within this time then proceed
                _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
            }
            else
            {
                response = "Socket is not initialized";
            }
 
            return response;
        }

 

程序的唤醒部分基本就完成了,下面我们要添加应用支持语音启动,首先在清单文件中设置程序支持语音:

 

然后我们在工程中添加一个“语音命令定义”,名称为:SupportedVoiceCommands.xml

 

修改下内容,我们只是为了语音启动,所以后面的内容就不用了

<?xml version="1.0" encoding="utf-8"?>
 
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.0">
  <CommandSet xml:lang="en-us">
    <CommandPrefix>start</CommandPrefix>
    <Example> open start </Example>
 
    ......    
 
  </CommandSet>
</VoiceCommands>

 

 

然后修改 App.xaml.cs ,加入对该语音指令文件的注册,函数命名为 InitializeVoiceCommands

        async private static void InitializeVoiceCommands()
        {
            var filename = "SupportedVoiceCommands.xml";
            try
            {
                var location = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
                var fileUriString = String.Format("file://{0}/{1}", location, filename);
                await Windows.Phone.Speech.VoiceCommands.VoiceCommandService.InstallCommandSetsFromFileAsync(new Uri(fileUriString));    
            }
            catch (Exception ex)
            {
               System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }

然后修改 App.xaml.cs 里的构造函数,加入InitializeVoiceCommands()

        public App()
        {
            // 未捕获的异常的全局处理程序。
            UnhandledException += Application_UnhandledException;
 
            // 标准 XAML 初始化
            InitializeComponent();
 
            // 特定于电话的初始化
            InitializePhoneApplication();
 
            // 语言显示初始化
            InitializeLanguage();
 
            //语音初始化

InitializeVoiceCommands();

 
            // 调试时显示图形分析信息。
            if (Debugger.IsAttached)

 

完成收工,运行下试试效果。

 

  

 

 

最后源码:

 

 

参考:

山寨版 WP8.1 Cortana 启动 PC的更多相关文章

  1. WP8.1 添加启动画面

    1.新建WP8.1工程,将需要设置为启动画面的图片添加到工程中,并且重命名为splash-Phone-sdk.png(必须命名为该名字). 2.在工程中有Package.appxmanifest,双击 ...

  2. WP8.1StoreApp(WP8.1RT)---第三方启动

    8.1的协议和wp8是相互通用的 被启动: 相比较wp8而言,基本变化不大,但添加方式更直观了 1:打开Package.appxmanifest 2:切换到"声明"选项卡 3:左侧 ...

  3. 【WP8】Uri关联启动第三方App

    在WP8中支持启动第三方应用程序,比如在App1中可以打开App2,你可以在你的应用程序中直接打开QQ,也可以让其他开发者调用你的APP,例如:软件盒子 下面演示被调用方和调用方的使用方法,新建两个项 ...

  4. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  5. STM32F10XXX 启动设置

    在STMF103XXX 里,可以通过Boot[1:0]引脚选择3种不同的启动模式:       启动模式选择引脚      启动模式                 说明   BOOT1   BOOT ...

  6. 重装助手教你如何禁用Windows 10快速启动

    快速启动是首先在Windows 8中实现并延续到Windows 10的功能,可在启动PC时提供更快的启动时间.它是一个方便的功能,也是大多数人在不知情的情况下使用的功能,但还有一些功能会在他们掌握新P ...

  7. 轻松制作X86 OPENWRT USB启动盘

    本文介绍了一个x86 live USBi启动盘的制作方法. 该方法有如下特点: 1.  可在winXP/win 7/win vista上制作, U盘采用fat格式, 即使对于linux经验较少者, 也 ...

  8. Windows phone 8.1应用集成cortana语音命令

    微软推出小娜已经有一段时间了,最近恰好在研究其用法,就随便写点记录一下自己的心得. 在研究时参考了@王博_Nick的博客:http://www.cnblogs.com/sonic1abc/p/3868 ...

  9. HoloLens shell overview(Translation)

    HoloLens shell 概述 使用HoloLens时,shell是由你周围的世界和来自系统的全息图构成.我们可以称这个空间叫做混合现实(mixed world). 此shell由在你的世界里能让 ...

随机推荐

  1. 注解 java.lang.annotation.Inherited 介绍

    在Spring Boot中大量使用了@Inherited注解.我们来了解一下这个注解的用法,注解的源码: package java.lang.annotation; /** * Indicates t ...

  2. BIM 3D 数据交换格式 ----张建平(清华女)

    1.collada   EXPORTER 2.FBX    3D MAX 3.DAE 4.3D中的OBJ文件格式详解 (  http://www.cnblogs.com/slysky/p/408130 ...

  3. HAProxy详解(一):HAProxy介绍【转】

    一.高性能负载均衡软件HAProxy介绍: 随着互联网业务的迅猛发展,大型电商平台和门户网站对系统的可用性和可靠性要求越来越高,高可用集群.负载均衡集群成为一种热门的系统架构解决方案.在众多的负载均衡 ...

  4. 修改主机IP地址

    IP:由192.168.1.1~192.168.1.254. 先使用电脑以动态IP的方式自动获取ip地址联网,然后通过以下方法查询子网掩码和默认网关地址:

  5. SharePoint 2013 报错 异常来自 HRESULT:0X80131904

    直接上传文件,报错:该Url xxxx无效.它可能指向不存在的文件或文件夹,或者是执行不再当前网站中的有效文件或文件夹. 直接新建文件夹,报错:异常来自 HRESULT:0X80131904 以系统账 ...

  6. RF运行脚本报错:WebDriverException: Message: unknown error: call function result missing

    原因:浏览器驱动与浏览器版本不对应

  7. Python 生产者与消费者模型

    定义: 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度.     为什么要使用生产者和消费者模式 在线程世界里,生 ...

  8. 大数据python词频统计之hdfs分发-cacheFile

    -cacheFile 分发,文件事先上传至Hdfs上,分发的是一个文件 1.找一篇文章The_Man_of_Property.txt: He was proud of him! He could no ...

  9. swift 学习- 14 -- 继承

    // 一个类可以继承另一个 类的方法, 属性和其他特征, 当一个类继承其他类时, 继承类叫子类, 被继承类叫父类 或 (超类), 在 Swift 中, 继承是区分 [类] 和其他类型的 一个基本特征 ...

  10. Markdown 简介及基础语法

    一.Markdown 简介 Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. 二.Markdown 基础语法 1. Markdown ...