命令行导入证书和 Provision

在部署构建机的时候,需要给每台构建机都导入 iOS 的 provisionp12证书,如果每个都要打开一遍编辑器,纯粹是重复劳动,翻了下代码,UE 编辑器中导入证书是通过调用 IPhonePackager.exe 来实现的,而且是以命令行的方式执行,这样就好办了,按照它的参数自己实现脚本即可。
具体看引擎中的相关代码:IOSTargetSettingsCustomization.cpp#L1312

Certificate

导入证书的命令为:

1
Engine\Binaries\DotNET\IOS\IPhonePackager.exe Install Engine -project "D:\Client\FGame.uproject" -certificate "D:\IOS_DEVELOPMENT.p12" -bundlename "com.tencent.xxxx.xx"

证书是导入到系统中的,可以在 certmgr.msc 中查看导入的证书:

注意:因为 iPhonePackager.exe 在导入证书时会让弹框输入证书的密码:

这导致不能用在自动化流程里,但是我怎么可能会老老实实每台电脑都输一次密码呢,看了一下 iPhonePackager 的代码,找到了弹窗让输入密码的地方Programs/IOS/iPhonePackager/ToolsHub.cs#L263,我给它加了个从命令行参数读取密码的选项,如果有该参数就不会弹框:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Load the certificate
string CertificatePassword = "";
string[] arguments = Environment.GetCommandLineArgs();

for (int index = 0;index<arguments.Length;++index)
{
if (arguments[index] == "-cerpassword" && index != (arguments.Length-1))
{
CertificatePassword = arguments[index + 1];
Console.WriteLine("Usage -cerpasseord argument");
}
}

X509Certificate2 Cert = null;
try
{
Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
}
catch (System.Security.Cryptography.CryptographicException ex)
{
// Try once with a password
if (CertificatePassword.Length > 0 || PasswordDialog.RequestPassword(out CertificatePassword))
{
Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
}
else
{
// User cancelled dialog, rethrow
throw ex;
}
}

把上面的代码替换掉 Programs/IOS/iPhonePackager/ToolsHub.cs#L263 这里的部分,重新编译 iPhonePackager 即可。

Provision

导入 Provision 的命令为:

1
Engine\Binaries\DotNET\IOS\IPhonePackager.exe Install Engine -project "D:\Client\FGame.uproject" -provision "D:\com.tencent.xxxx.xx_Development_SignProvision.mobileprovision" -bundlename "com.tencent.xxxx.xx"

Provision 文件导入后会放在用户目录下:

1
2
3
4
5
6
7
8
9
10
11
12
13
/// <summary>
/// The shared provision library directory (on PC)
/// </summary>
public static string ProvisionDirectory
{
get {
if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix) {
return Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/";
} else {
return Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/";
}
}
}

Win 上就为:C:\Users\USER_NAME\AppData\Local\Apple Computer\MobileDevice\Provisioning Profiles.