Initial Winrt -appx

Outputs Appx file, needs 2 manual steps:
Modify sdkVersion variable in WindowsPlatform.hx to the one you want to use for bin tools in C:\Program Files (x86)\Windows Kits\10\\bin\ and do openfl rebuild tools

For creating the certificate, Powershell command fails but the command lets you know which command you need to execute (copy and past in the cmd prompt)
This commit is contained in:
Carlos Madrazo
2019-03-31 22:20:15 -05:00
committed by Joshua Granick
parent dbe6846df0
commit e1a0f3a473
7 changed files with 245 additions and 17 deletions

View File

@@ -0,0 +1,6 @@
Get-ChildItem cert:\LocalMachine\My | Where-Object { $_.Subject -match "CN=::if APP_COMPANYID::APP_COMPANYID::else::NME_Example::end::" } | Remove-Item
New-SelfSignedCertificate -Type Custom -Subject "CN=::if APP_COMPANYID::APP_COMPANYID::else::NME_Example::end::" -KeyUsage DigitalSignature -FriendlyName NMEDisplayingCert -CertStoreLocation "Cert:\LocalMachine\My"
#Get-ChildItem cert:\LocalMachine\My | Where-Object { $_.Subject -match "CN=::if APP_COMPANYID::APP_COMPANYID::else::NME_Example::end::" }
$pwd = ConvertTo-SecureString -String ::if APP_CERTIFICATE_PWD::APP_CERTIFICATE_PWD::else::"nmeexample"::end:: -Force -AsPlainText
$thumbprint=(dir cert:\localmachine\My -recurse | where {$_.Subject -match "CN=::if APP_COMPANYID::APP_COMPANYID::else::NME_Example::end::"} ).Thumbprint;
Export-PfxCertificate -cert "Cert:\LocalMachine\My\$thumbprint" -FilePath ::APP_FILE::.pfx -Password $pwd

View File

View File

@@ -0,0 +1 @@
//generate this file

View File

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<resources targetOsVersion="10.0.0" majorVersion="1">
<index root="\" startIndexAt="layout.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="resources.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="RESW" convertDotsToSlashes="true" />
<indexer-config type="RESJSON" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="pri.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="PRI" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="embed.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="RESFILES" qualifierDelimiter="." />
<indexer-config type="EMBEDFILES" />
</index>
</resources>

View File

View File

@@ -709,6 +709,8 @@ class WindowsPlatform extends PlatformTarget
ProjectHelper.recursiveSmartCopyTemplate(project, "winrt/assetspkg", targetDirectory + "/bin/assetspkg", context, false, true);
ProjectHelper.recursiveSmartCopyTemplate(project, "winrt/appx", targetDirectory + "/bin", context, true, true);
ProjectHelper.recursiveSmartCopyTemplate(project, "winrt/static", targetDirectory + "/obj", context, true, true);
ProjectHelper.recursiveSmartCopyTemplate(project, "winrt/temp", targetDirectory + "/haxe/temp", context, false, true);
ProjectHelper.recursiveSmartCopyTemplate(project, "winrt/scripts", targetDirectory + "/scripts", context, true, true);
}
else if (targetType == "cpp" && project.targetFlags.exists("static"))
{
@@ -953,11 +955,12 @@ class WindowsPlatform extends PlatformTarget
super.install();
if (targetType == "winrt")
{
// if(project.winrtConfig.isAppx)
// {
// TODO: pack in appx
// }
// else
if(project.targetFlags.exists("appx"))
{
var context = project.templateContext;
buildWinrtPackage(context.KEY_STORE, context.KEY_STORE_PASSWORD);
}
else
{
uninstall();
Log.info("run: Register app");
@@ -982,11 +985,7 @@ class WindowsPlatform extends PlatformTarget
override public function uninstall():Void
{
super.uninstall();
if (targetType == "winrt") // if(project.winrtConfig.isAppx)
// {
// TODO
// }
// else
if (targetType == "winrt" && !project.targetFlags.exists("appx"))
{
var appxName = project.meta.packageName;
Log.info("run: Remove previous registered app");
@@ -1002,18 +1001,18 @@ class WindowsPlatform extends PlatformTarget
}
process.close();
}
//TODO if (targetType == "winrt" && project.targetFlags.exists("appx"))
}
public function winrtRun(arguments:Array<String>):Void
{
var dir = applicationDirectory;
var haxeDir = targetDirectory + "/haxe";
// if(project.winrtConfig.isAppx)
// {
// Log.info("\n***Double click on "+project.app.file + ".Appx to install Appx");
// }
// else
if (project.targetFlags.exists("appx"))
{
Log.info("\n***Double click on "+project.app.file + ".Appx to install Appx");
}
else
{
var appxName = project.meta.packageName;
var appxId = "App";
@@ -1024,7 +1023,7 @@ class WindowsPlatform extends PlatformTarget
// get PackageFamilyappxName and set appxAUMID
// write app info in a file
var cmd = 'Get-AppxPackage ' + appxName + ' | Out-File ' + appxInfoFile + ' -Encoding ASCII';
trace("powershell " + cmd);
Log.info("powershell " + cmd);
var process3 = new sys.io.Process('powershell', [cmd]);
if (process3.exitCode() != 0)
{
@@ -1067,4 +1066,159 @@ class WindowsPlatform extends PlatformTarget
+ 'App Certification Kit\\microsoft.windows.softwarelogo.appxlauncher.exe', [appxAUMID]);
}
}
public function buildWinrtPackage(pfxPath:String, certificatePwd:String):Void
{
if (project.targetFlags.exists("appx"))
{
var kitsRoot10 = "C:\\Program Files (x86)\\Windows Kits\\10\\"; //%WindowsSdkDir%
var haxeDir = targetDirectory + "/haxe";
//TODO! Get latest sdkVersion path automatically
var sdkVersion = '10.0.17763.0';
var makepriPath = kitsRoot10+'\\bin\\'+sdkVersion+'\\x86\\MakePri.exe';
var makeappxPath = kitsRoot10+'\\bin\\'+sdkVersion+'\\x86\\MakeAppx.exe';
var signToolPath = kitsRoot10+'\\bin\\'+sdkVersion+'\\x64\\SignTool.exe';
var resultFilePath = haxeDir +"\\temp";
var resultFileName = resultFilePath +"/layout.resfiles";
Log.info("make pri");
var outputDirectory = Path.combine(FileSystem.fullPath(targetDirectory), "appx");
var binPath = Path.combine(FileSystem.fullPath(targetDirectory), "bin");
pfxPath = Path.combine(outputDirectory, pfxPath);
//prepare file to make pri
try
{
var from = outputDirectory;
var buf = new StringBuf();
//todo
var outputFiles = FileSystem.readDirectory(binPath);
for (filename in outputFiles)
{
if (!(StringTools.endsWith(filename,".exe") ||
StringTools.endsWith(filename,".pri") )
&& filename!="AppxManifest.xml")
{
buf.add(filename);
buf.addChar(10);
}
}
if(sys.FileSystem.exists(resultFileName))
sys.FileSystem.deleteFile(sys.FileSystem.absolutePath(resultFileName));
sys.io.File.saveContent(resultFileName, buf.toString());
Log.info("Created layout.resfiles : " + resultFileName);
}
catch(e:Dynamic)
{
Log.error("Error creating layout.resfiles " + e);
}
var makepriParams = ["new", "/ProjectRoot", resultFilePath, "/ConfigXml", resultFilePath + "\\priconfig.xml", "/Manifest", applicationDirectory + "/"+'AppxManifest.xml', "/OutputFile", applicationDirectory +"resources.pri"];
Log.info( makepriPath+ " " + makepriParams);
var process = new sys.io.Process(makepriPath, makepriParams);
//needs to wait make pri
var retry:Int = 10;
while (retry>0 && !sys.FileSystem.exists(applicationDirectory + "/"+"resources.pri"))
{
Sys.sleep(1);
Log.info("waiting pri..");
retry--;
}
if (retry<=0)
Log.error("Error on MakePri");
var appxDir = applicationDirectory+"../";
Log.info("make "+project.app.file+".Appx");
var makeappParams = ["pack", "/d", applicationDirectory, "/p", appxDir+project.app.file+".Appx" ];
var process2 = new sys.io.Process(makeappxPath, makeappParams);
Log.info(makeappParams.toString());
process.close();
process2.close();
var pfxFileName = project.app.file+".pfx";
if (pfxPath!=null && pfxPath.length>0)
{
if (sys.FileSystem.exists(appxDir+"scripts/"+pfxFileName))
{
//apply certificate
Log.info("Pfx cert found: path: " +appxDir+"scripts/"+pfxFileName+", pwd:"+certificatePwd);
}
else
{
//create certificate
Log.warn("Warn: certificate " +pfxPath+" not found, run the following command to create a new one:");
//copyTemplateDir( "winrt/scripts", applicationDirectory+"/.." );
//New certificate, calls powershell script on elevated mode
// var cmd = "Start-Process powershell \"-ExecutionPolicy Bypass -Command `\"cd `\""+sys.FileSystem.absolutePath(applicationDirectory)+"/.."+"`\"; & `\".\\newcertificate.ps1`\"`\"\" -Verb RunAs";
// var cmd = "Start-Process powershell \"-Command `\"cd `\""+sys.FileSystem.absolutePath(applicationDirectory)+"/.."+"`\"; & `\".\\newcertificate.ps1`\"`\"\" -Verb RunAs";
//var cmd = "\"cd "+sys.FileSystem.absolutePath(applicationDirectory)+"/../scripts;Start-Process powershell -verb runas -ArgumentList \'-file .\\newcertificate.ps1\'\"";
var cmd = "-Command \"Start-Process powershell \\\"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\\\"cd \\`\\\"E:/openfl/BunnyMark/Export/winrt/bin/../scripts\\`\\\"; & \\`\\\".\\newcertificate.ps1\\`\\\"`\\\"\\\" -Verb RunAs\"";
Log.info("powershell "+cmd);
#if 0
var process3 = new sys.io.Process("powershell", [cmd]);
if (process3.exitCode() != 0) {
var message = process3.stderr.readAll().toString();
Log.error("Error newcertificate. " + message);
}
process3.close();
//check pfx
retry = 10;
while (retry>0 && !sys.FileSystem.exists(appxDir+"scripts/"+pfxFileName)){
Log.info("waiting "+appxDir+"scripts/"+pfxFileName);
Sys.sleep(6);
retry--;
}
if (retry<=0)
Log.error("Error creating certificate");
#else
return;
#end
}
if(appxDir+"scripts/"+pfxFileName != pfxPath)
{
System.copyFile(appxDir+"scripts/"+pfxFileName, pfxPath);
if (!sys.FileSystem.exists(pfxPath))
{
Log.error("could not copy "+appxDir+pfxFileName+" to "+pfxPath);
}
}
}
if (pfxPath!=null && certificatePwd!=null && pfxPath.length>0 && certificatePwd.length>0)
{
Log.info("signing "+project.app.file+".Appx with " + pfxPath);
var signParams = ["sign", "/fd", "SHA256", "/a", "/f", pfxPath, "/p", certificatePwd, appxDir+project.app.file+".Appx"];
Log.info(signToolPath+" "+signParams);
var process4 = new sys.io.Process(signToolPath, signParams);
if (process4.exitCode() != 0) {
var message = process4.stderr.readAll().toString();
Log.error("Error signing appx. " + message);
}
Log.info("\n\n***Double click "+pfxPath+" to setup certificate (Local machine, Place all certificates in the following store->Trusted People)\n");
process4.close();
}
}
}
}