【Windows 10 IoT】为Win10 IoT镜像添加默认应用(树莓派)

Leeway213 UID.76829
2016-06-20 发表

本帖最后由 Leeway213 于 2016-6-20 21:14 编辑

在Windows 10 IoT应用程序开发好之后,一般通过IoT WebManagement或者直接用vs将应用部署上去。并且执行命令iotstartup.exe add headed/headless AppxID,将应用设置为开机启动。
但是,如果想基于一个开发板,量产某种硬件设备,这种方式肯定是不可行的。
我们会想到,是否可以将我们的应用直接打包到镜像中,并设置成为开机自启的默认应用呢?当然可以。
基本原理是这样的:IoT设备第一次启动时,会执行一个OEMCustomization.cmd脚本,安装指定目录下的appx应用并执行iotstartup.exe将其设置为startup应用。 参考:[Add an app to your image][1]
用到的工具:
1. Windows Assessment and Deployment Kit (Windows ADK) [***链接停止解析***][2]
2. Windows Driver Kit (WDK) [***链接停止解析***][3]
3. IoT Core ADK Add-Ons [***链接停止解析***][4]
4. Windows 10 IoT Core Dashboard [***链接停止解析***][5][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]
上面这些工具,主要修改的是 IoT Core ADK Add-Ons。这个工具包中包含了用于打包一个ffu镜像的一系列脚本和xml模板。Tools文件夹下是一些打包boot相关、驱动、应用以及生成FFU的一些脚本。在Source-arm和Source-x86下的Products文件夹中,包含了一些设备样本。
[/font][/backcolor]
[/p][indent][p=25, null, left]例:
iot-adk-addonkit\Source-arm\Products\SampleA是树莓派2的sample;
iot-adk-addonkit\Source-arm\Products\SampleB是可以添加自定义驱动的树莓派2的sample;
iot-adk-addonkit\Source-x86\Products\SampleA是intel MBM的sample;
iot-adk-addonkit\Source-x86\Products\SampleB是可以添加自定义驱动的intel MBM的sample。[/p][/indent]
主要步骤:
1. 先后先当然是先build并打包你的应用程序。注意只生成对应平台的appx就可以了,不要生成appxbundle。
2. 将应用打包成cab包:[indent][list=1]
[*]以管理员身份运行IoT Core ADK Add-Ons中的脚本:IoT-ADK-AddonKit\IoTCoreShell.cmd。选择对应的CPU平台:arm或者x86.
[*]执行buildpkg all,这个命令会将IoT-ADK-AddonKit\Common和Source-arm(x86)\Packages目录下已有的Package文件夹打包成cab包。build成功后,我们可以在IoT-ADK-AddonKit\arm(x86)\pkgs目录下看到生成的cab包。
[*]使用newappxpkg命令,为你的应用生成一个预打包的工作目录:
newAppxPkg "..\HelloWorld\AppPackages\HelloWorld_1.0.0.0_ARM_Debug_Test\HelloWorld_1.0.0.0_ARM_Debug.appx" Appx.HelloWorld
PS:不要把appx拷贝出来,因为newappxpkg命令会扫面appx所在目录下是否有dependency appx,如果有,会一同拷贝到工作目录与你的appx应用一起打包。一般是Microsoft.NET.Native.Framework、Microsoft.NET.Native.Runtime和Microsoft.VCLibs.ARM这三个依赖。
[*]执行buildpkg Appx.HelloWorld命令,就可以将应用打包成cab包了。执行成功后,我们可以在IoT-ADK-AddonKit\arm(x86)\pkgs目录下找到OEM_NAME.Appx.HelloWorld.cab这个包(OEM_NAME是在setoem.cmd脚本中指定的)。
[/list][/indent]
3. 修改feature manifest(以下简称FM): IoT-ADK-AddonKit\Source-\Packages\OEMFM.xml[p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]将appx应用打包成的cab包,添加到feature manifest中声明。格式如下:[/font][/backcolor][/p]
[list=1]
[*]<?xml version="1.0" encoding="utf-8"?>
[*]<FeatureManifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/embedded/2004/10/ImageUpdate">
[*] <BasePackages/>
[*] <Features>
[*] <OEM>
[*] <!-- Feature definitions below -->
[*] <PackageFile Path="%PKGBLD_DIR%" Name="%OEM_NAME%.Appx.Main.cab">
[*] <FeatureIDs>
[*] <FeatureID>OEM_AppxMain</FeatureID>
[*] </FeatureIDs>
[*] </PackageFile>
[*] <PackageFile Path="%PKGBLD_DIR%" Name="%OEM_NAME%.Appx.HelloWorld.cab">
[*] <FeatureIDs>
[*] <FeatureID>OEM_AppxHelloWorld</FeatureID>
[*] </FeatureIDs>
[*] </PackageFile>
[*] </OEM>
[*] <OEMFeatureGroups/>
[*] </Features>
[*]</FeatureManifest>
[/list]
4. 更新配置文件 IoT-ADK-AddonKit\Source-\Products\ProductA\TestOEMInput.xml[p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]添加步骤3中修改的feature manifest到AdditionalFM标签下:[/font][/backcolor][/p]
[list=1]
[*]<AdditionalFMs>
[*] <AdditionalFM>%AKROOT%\FMFiles\arm\IoTUAPNonProductionPartnerShareFM.xml</AdditionalFM>
[*] <AdditionalFM>%AKROOT%\FMFiles\arm\IoTUAPRPi2FM.xml</AdditionalFM>
[*] <AdditionalFM>%AKROOT%\FMFiles\arm\RPi2FM.xml</AdditionalFM>
[*] <!--步骤3中修改的feature manifest-->
[*] <AdditionalFM>%SRC_DIR%\Packages\OEMFM.xml</AdditionalFM>
[*] <AdditionalFM>%COMMON_DIR%\Packages\OEMCommonFM.xml</AdditionalFM>
[*] </AdditionalFMs>
[/list][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]然后,将你的应用的featureID添加到标签下:[/font][/backcolor][/p]
[list=1]
[*]<OEM>
[*]<Feature>RPI2_DRIVERS</Feature>
[*]<Feature>RPI2_DEVICE_TARGETINGINFO</Feature>
[*]<Feature>PRODUCTION</Feature>
[*]<Feature>OEM_CustomCmd</Feature>
[*]<Feature>OEM_AppxHelloWorld</Feature>
[*]</OEM>
[/list][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]注意:一个镜像中只能有一个默认的前台应用(startup headed app),所以我们需要注释掉之前的默认app:IOT_BERTHA[/font][/backcolor][/p]
[list=1]
[*] <Feature>IOT_ENABLE_TESTSIGNING</Feature>
[*] <Feature>IOT_DISABLE_UMCI</Feature>
[*] <Feature>IOT_CRT140</Feature>
[*]<!-- <Feature>IOT_BERTHA</Feature> -->
[*] <Feature>IOT_APP_TOOLKIT</Feature>
[*] <Feature>IOT_CP210x_MAKERDRIVER</Feature>
[*] <Feature>IOT_FTSER2K_MAKERDRIVER</Feature>
[/list][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]步骤3中的FM文件,相当于app cab包的声明,标识某个featureID所对应的cab包;只有在步骤4中的OEMInput文件中添加后相应的featureID后,打包程序才会将对应的cab包打包到镜像中。[/font][/backcolor][/p]
5. 设置自动安装脚本[p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]自动安装脚本位于:IoT-ADK-AddonKit\Source-\Products\SampleX\OEMCustomization.cmd,代码如下:[/font][/backcolor][/p]
[list=1]
[*]@echo off
[*]REM OEM Customization Script file
[*]REM This script if included in the image, is called everytime the system boots.
[*]
[*]
[*]REM Enable Administrator User
[*]net user Administrator p@ssw0rd /active:yes
[*]
[*]if exist C:\AppInstall\AppInstall.cmd (
[*] REM Enable Application Installation for onetime only, after this the files are deleted.
[*] call C:\Appinstall\AppInstall.cmd > %temp%\AppInstallLog.txt
[*]
[*] REM Cleanup Application Installation Files. Change dir to root so that the dirs can be deleted
[*] cd \
[*] rmdir /S /Q C:\AppInstall
[*])
[/list][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]可以看到,脚本执行时,会判断C:\下是否存在AppInstall\AppInstall.cmd脚本(实际上这个AppInstall目录,就是从步骤2.appx打包成的cab包中提取出来的所有文件),如果有,则执行。而AppInstall.cmd脚本,就会将AppInstall目录下的appx应用程序安装并且设置为startup app。[/font][/backcolor][/p][indent][p=25, null, left]PS: 自动安装脚本OEMCustomization.cmd,同样以cab包的形式打包进ffu镜像的。在步骤4中的OEMInput.xml文件中,OEM_CustomCmd这个feature就是自动安装脚本的cab。OEM_CustomCmd的声明在iot-adk-addonkit\Common\Packages\OEMCommonFM.xml中可以找到。[/p][/indent]
6. 最后,打包ffu镜像[p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]执行createimage.cmd SampleA Test打包镜像。SampleA就是树莓派的sample。
生成的ffu位于:IoT-ADK-AddonKit\Build\\ProductA\Flash.FFU
[/font][/backcolor]
[/p][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]大功告成!赶紧烧写到sd卡里测试一下吧![/font][/backcolor][/p]

标签: Windows

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
Leeway213 UID.76829
2016-06-20 回复

可能会遇到的小问题[p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]如果系统启动后,一直无法启动默认应用,一定是哪里出了问题(这是废话)。
可以到SD卡的Data\Users\DefaultAccount\AppData\Local\Temp目录下,看是否有你的应用的安装log(名字是****_result.txt)。
如果没有,可能是OEMCustomization.cmd脚本没有成功执行,需要检查下OEM_CustomCmd这个cab包是不是成功生成并打包到ffu中了;
如果有,就打开看一下log,应该会有错误原因。
我遇到的一个蛋疼的问题是:
安装appx时,找不到某个依赖(就是上面说的Microsoft.NET.Native.Framework、Microsoft.NET.Native.Runtime和Microsoft.VCLibs.ARM这三个appx),可是三个依赖包明明都在我的应用cab包中啊!这个时候用文本编辑器打开应用cab包中的AppxConfig.cmd这个脚本看了一下:
[/font][/backcolor]
[/p]
[list=1]
[*]set AppxName=IoTCoreMediaPlayer_1.0.4.0_ARM
[*]set certslist=IoTCoreMediaPlayer_1.0.4.0_ARM
[*]set dependencylist=Microsoft.NET.Native.Framework.1.3Microsoft.NET.Native.Runtime.1.3Microsoft.VCLibs.ARM.14.00
[/list][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]第三行,注意到没有,三个依赖包的名字之间没有空格!!!再继续查找原因,根源在newappxpkg.cmd这个脚本。查看代码:[/font][/backcolor][/p]
[list=1]
[*]:: Run setenv before running this script
[*]:: This script creates the folder structure and copies the template files for a new package
[*]@echo off
[*]
[*]goto START
[*]
[*]:Usage
[*]echo Usage: newappxpkg filename.appx [CompName.SubCompName
[*]echo filename.appx........... Required, Input appx package. Expects dependencies in a sub folder
[*]echo CompName.SubCompName.... Optional, default is Appx.filename
[*]echo ............ Displays this usage string.
[*]echo Example:
[*]echo newappxpkg C:\test\MainAppx_1.0.0.0_arm.appx Appx.Main
[*]echo Existing packages are
[*]dir /b /AD %SRC_DIR%\Packages
[*]
[*]exit /b 1
[*]
[*]:START
[*]setlocal ENABLEDELAYEDEXPANSION
[*]
[*]if [%1 == goto Usage
[*]if [%1 == [-?] goto Usage
[*]if [%1 == [] goto Usage
[*]
[*]set FILE_TYPE=%~x1
[*]set FILE_NAME=%~n1
[*]set "FILE_PATH=%~dp1"
[*]
[*]if [%FILE_TYPE == [.appx (
[*] set COMP_NAME=Appx
[*] for /f "tokens=1 delims=_" %%i in ("%FILE_NAME%") do (
[*] set SUB_NAME=%%i
[*] )
[*]) else (
[*] echo. Unsupported filetype.
[*] goto Usage
[*])
[*]if not [%2 == [] (
[*] for /f "tokens=1,2 delims=." %%i in ("%2") do (
[*] set COMP_NAME=%%i
[*] set SUB_NAME=%%j
[*] )
[*])
[*]
[*]if NOT DEFINED SRC_DIR (
[*] echo Environment not defined. Call setenv
[*] goto End
[*])
[*]SET "NEWPKG_DIR=%SRC_DIR%\Packages\%COMP_NAME%.%SUB_NAME%"
[*]
[*]:: Error Checks
[*]if /i EXIST %NEWPKG_DIR% (
[*] echo Error : %COMP_NAME%.%SUB_NAME% already exists
[*] rmdir /s /q %NEWPKG_DIR%
[*] echo Delete old %NEWPKG_DIR%
[*])
[*]
[*]:: Start processing command
[*]echo Creating %COMP_NAME%.%SUB_NAME% package
[*]
[*]mkdir "%NEWPKG_DIR%"
[*]
[*]if [%FILE_TYPE == [.appx (
[*] :: Create Appx Package using template files
[*] mkdir "%NEWPKG_DIR%\AppInstall"
[*] echo. Creating package xml file
[*] call appx2pkg.cmd %1 %COMP_NAME%.%SUB_NAME%
[*] REM Copy the files to the package directory
[*] move "%FILE_PATH%\%COMP_NAME%.%SUB_NAME%.pkg.xml" "%NEWPKG_DIR%\%COMP_NAME%.%SUB_NAME%.pkg.xml" >nul
[*] if exist "%FILE_PATH%\Dependencies\%ARCH%" (
[*] copy "%FILE_PATH%\Dependencies\%ARCH%\*.appx" "%NEWPKG_DIR%\AppInstall\" >nul
[*] ) else (
[*] copy "%FILE_PATH%\Dependencies\*.appx" "%NEWPKG_DIR%\AppInstall\" >nul
[*] )
[*]
[*] copy "%FILE_PATH%\*.cer" "%NEWPKG_DIR%\AppInstall\" >nul
[*] copy "%FILE_PATH%\%FILE_NAME%.appx" "%NEWPKG_DIR%\AppInstall\%FILE_NAME%.appx" >nul
[*] copy "%IOTADK_ROOT%\Templates\AppInstall\*.cmd" "%NEWPKG_DIR%\AppInstall" >nul
[*] REM Update AppxConfig.cmd
[*] echo set AppxName=%FILE_NAME%> %NEWPKG_DIR%\AppInstall\AppxConfig.cmd
[*] for /f "useback delims=" %%i in ("%FILE_PATH%\appx_cerlist.txt") do (
[*] set certslist=!certslist!%%~ni
[*] )
[*] echo set certslist=!certslist! >> %NEWPKG_DIR%\AppInstall\AppxConfig.cmd
[*] for /f "useback delims=" %%i in ("%FILE_PATH%\appx_deplist.txt") do (
[*] set dependencylist=!dependencylist!%%~ni
[*] )
[*] echo set dependencylist=!dependencylist! >> %NEWPKG_DIR%\AppInstall\AppxConfig.cmd
[*] del "%FILE_PATH%\appx_cerlist.txt"
[*] del "%FILE_PATH%\appx_deplist.txt"
[*])
[*]
[*]echo %NEWPKG_DIR% ready
[*]goto End
[*]
[*]:Error
[*]endlocal
[*]echo "newappxpkg %1 %2" failed with error %ERRORLEVEL%
[*]exit /b 1
[*]
[*]:End
[*]endlocal
[*]exit /b 0
[/list][p=27, null, left][backcolor=rgb(249, 249, 245)][font=&quot]注意第87行:set certslist=!certslist!%%~ni,这行代码最后需要有一个空格!!这样生成的AppxConfig.cmd脚本就是这样的(每个依赖包后面有一个空格):[/font][/backcolor][/p]
[list=1]
[*]set AppxName=IoTCoreMediaPlayer_1.0.4.0_ARM
[*]set certslist=IoTCoreMediaPlayer_1.0.4.0_ARM
[*]set dependencylist=Microsoft.NET.Native.Framework.1.3 Microsoft.NET.Native.Runtime.1.3 Microsoft.VCLibs.ARM.14.00
[/list]

xyangtian UID.832923
2016-06-20 回复

只能看懂一点点

Leeway213 UID.76829
2016-06-20 回复

Quote***链接停止解析***
只能看懂一点点


我看下来也挺困难的 会dos脚本的话会容易些
这个是官方文档的链接 我好像没写上去
***链接停止解析***

pa****er UID.53194
2016-06-24 回复

headed/headless 分别是什么模式呀?

Leeway213 UID.76829
2016-06-26 回复

Quote***链接停止解析***
headed/headless 分别是什么模式呀?


IoT里的应用分两种,
headed是指前台应用,headless是指没有UI的纯后台应用

pa****er UID.53194
2016-07-03 回复

Quote***链接停止解析***
IoT里的应用分两种,
headed是指前台应用,headless是指没有UI的纯后台应用


headless , 怎么设置 键盘响应 或者 XBOX 响应呢?

Leeway213 UID.76829
2016-07-04 回复

Quote***链接停止解析***
headless , 怎么设置 键盘响应 或者 XBOX 响应呢?


不太明白你的意思 你是要实现什么需求哇

士****长 UID.1308736
2016-07-04 回复

哈哈哈,感谢楼主分享

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报