diff --git a/templates/winrt/scripts/newcertificate.ps1 b/templates/winrt/scripts/newcertificate.ps1 new file mode 100644 index 000000000..e7f13e7ba --- /dev/null +++ b/templates/winrt/scripts/newcertificate.ps1 @@ -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 diff --git a/templates/winrt/temp/embed.resfiles b/templates/winrt/temp/embed.resfiles new file mode 100644 index 000000000..e69de29bb diff --git a/templates/winrt/temp/layout.resfiles b/templates/winrt/temp/layout.resfiles new file mode 100644 index 000000000..67abc9c88 --- /dev/null +++ b/templates/winrt/temp/layout.resfiles @@ -0,0 +1 @@ +//generate this file diff --git a/templates/winrt/temp/pri.resfiles b/templates/winrt/temp/pri.resfiles new file mode 100644 index 000000000..e69de29bb diff --git a/templates/winrt/temp/priconfig.xml b/templates/winrt/temp/priconfig.xml new file mode 100644 index 000000000..1c6c21c81 --- /dev/null +++ b/templates/winrt/temp/priconfig.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/winrt/temp/resources.resfiles b/templates/winrt/temp/resources.resfiles new file mode 100644 index 000000000..e69de29bb diff --git a/tools/platforms/WindowsPlatform.hx b/tools/platforms/WindowsPlatform.hx index 3d038af4b..682a55357 100644 --- a/tools/platforms/WindowsPlatform.hx +++ b/tools/platforms/WindowsPlatform.hx @@ -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):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(); + } + } + } }