Code Monkey home page Code Monkey logo

Comments (5)

MonsterArtur1 avatar MonsterArtur1 commented on September 23, 2024 1

Alternative solution:
I know its closed and tweaked, but I'm using older version, so I use this Shell script for making GDK build on our Jenkins:

  • just build standard PC x64 build with plugins enabled
  • run this as next build step to generate package
copy %WORKSPACE%\Assets\GDK-Tools\ProjectMetadata\MicrosoftGame.Config D:\OutputDir\Jenkins\ProjectName\StandaloneWindows64_GDK\
copy %WORKSPACE%\Assets\GDK-Tools\ProjectMetadata\*.png D:\OutputDir\Jenkins\ProjectName\StandaloneWindows64_GDK\

rmdir D:\OutputDir\Jenkins\ProjectName\PC_GDK\ /s /q 
mkdir D:\OutputDir\Jenkins\ProjectName\PC_GDK
rmdir D:\OutputDir\Jenkins\ProjectName\StandaloneWindows64_GDK\ProjectName_BackUpThisFolder_ButDontShipItWithYourGame /s /q 
move D:\OutputDir\Jenkins\ProjectName\StandaloneWindows64_GDK D:\OutputDir\Jenkins\ProjectName\PC_GDK\Win32

"C:\Program Files (x86)\Microsoft GDK\bin\makepkg.exe" genmap /f D:\OutputDir\Jenkins\ProjectName\PC_GDK\Win32\layout.xml /d D:\OutputDir\Jenkins\ProjectName\PC_GDK\Win32\

mkdir D:\OutputDir\Jenkins\ProjectName\PC_GDK\GDK

"C:\Program Files (x86)\Microsoft GDK\bin\makepkg.exe" pack /f D:\OutputDir\Jenkins\ProjectName\PC_GDK\Win32\layout.xml /d D:\OutputDir\Jenkins\ProjectName\PC_GDK\Win32\ /pd D:\OutputDir\Jenkins\ProjectName\PC_GDK\GDK /pc /CorrelationId Unity /l

maybe this could help someone

from gdk-unity-package.

payzer avatar payzer commented on September 23, 2024

Thank you for the suggestion! That makes sense. We'll look into doing the change.

from gdk-unity-package.

payzer avatar payzer commented on September 23, 2024

This change will go out in our next release, but if you want it sooner you can pull from the repo. Thank you again for the suggestion!

from gdk-unity-package.

payzer avatar payzer commented on September 23, 2024

Thank you so much for posting that script! I'm sure many others will absolutely benefit from it.

from gdk-unity-package.

Warhammer4000 avatar Warhammer4000 commented on September 23, 2024

I've actually gone ahead and wrote prebuild & postbuild script for Automation. This is basically code copied out from existing GDKBuild.cs

I'm sure this can be more cleaner with having scriptable object to store some of the configuration

PreBuild.cs

using Microsoft.GameCore.Utilities;
using System.Collections.Generic;
using System.Xml.Linq;
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;


public class PreBuild : IPreprocessBuildWithReport
{

    public static string contentIdOverride;
    public static string originalSquare150x150LogoPath;
    public static string originalSquare44x44LogoPath;
    public static string originalSquare480x480LogoPath;
    public static string originalSplashScreenImagePath;
    public static string originalStoreLogoPath;


    public int callbackOrder => 0;
    public void OnPreprocessBuild(BuildReport report)
    {
        Setup(Path.GetDirectoryName(report.summary.outputPath));
    }


    private void Setup(string pcStandaloneBuildPath)
    {

        PlayerSettings.forceSingleInstance = true;

        GdkUtilities.PullGdkDlls();

        CopyManifestFiles(pcStandaloneBuildPath);

   
    }

    private void CopyManifestFiles(string buildWin32OutputFolderPath)
    {
        string square150x150LogoPath = string.Empty;
        string square44x44LogoPath = string.Empty;
        string square480x480LogoPath = string.Empty;
        string splashScreenImagePath = string.Empty;
        string storeLogoPath = string.Empty;

        string gameConfigFilePath = GdkUtilities.GameConfigPath;


        XDocument gameConfigXmlDoc = XDocument.Load(gameConfigFilePath);
        try
        {
            string imagesPath = gameConfigFilePath.Replace("MicrosoftGame.Config", string.Empty);
            XElement executableEl = (from executable in gameConfigXmlDoc.Descendants("Executable")
                                     select executable).First();
            executableEl.SetAttributeValue("Name", PlayerSettings.productName + ".exe");

            // Find the images
            XElement shellVisualsEl = (from shellVisual in gameConfigXmlDoc.Descendants("ShellVisuals")
                                       select shellVisual).First();

            XAttribute square150x150LogoAttribute = shellVisualsEl.Attribute("Square150x150Logo");
            originalSquare150x150LogoPath = square150x150LogoAttribute.Value;
            square150x150LogoPath = (imagesPath + originalSquare150x150LogoPath).Replace("/", "\\");

            XAttribute square44x44LogoAttribute = shellVisualsEl.Attribute("Square44x44Logo");
            originalSquare44x44LogoPath = square44x44LogoAttribute.Value;
            square44x44LogoPath = (imagesPath + originalSquare44x44LogoPath).Replace("/", "\\");

            XAttribute square480x480LogoAttribute = shellVisualsEl.Attribute("Square480x480Logo");
            originalSquare480x480LogoPath = square480x480LogoAttribute.Value;
            square480x480LogoPath = (imagesPath + originalSquare480x480LogoPath).Replace("/", "\\");

            XAttribute splashScreenImageAttribute = shellVisualsEl.Attribute("SplashScreenImage");
            originalSplashScreenImagePath = splashScreenImageAttribute.Value;
            splashScreenImagePath = (imagesPath + originalSplashScreenImagePath).Replace("/", "\\");

            XAttribute storeLogoAttribute = shellVisualsEl.Attribute("StoreLogo");
            originalStoreLogoPath = storeLogoAttribute.Value;
            storeLogoPath = (imagesPath + originalStoreLogoPath).Replace("/", "\\");

            // Check for a Content ID override
            XElement contentIdOverrideEl = (from contentIdOverride in gameConfigXmlDoc.Descendants("ContentIdOverride")
                                            select contentIdOverride).First();
            contentIdOverride = contentIdOverrideEl.Value;

            gameConfigXmlDoc.Save(gameConfigFilePath);
        }
        catch (Exception)
        {
            Debug.LogError("Invalid or corrupt MicrosoftGame.Config.");
            return;
        }

        List<string> storeAssetsToCopy = new List<string>
        {
            gameConfigFilePath,
            square150x150LogoPath,
            square44x44LogoPath,
            square480x480LogoPath,
            splashScreenImagePath,
            storeLogoPath
        };

        foreach (string storeAssetToCopy in storeAssetsToCopy)
        {
            string fileName = Path.GetFileName(storeAssetToCopy);
            string fullSourcePath = storeAssetToCopy;
            string destinationPath = buildWin32OutputFolderPath + "\\" + fileName;
            File.Copy(fullSourcePath, destinationPath, true);
        }

    }

}

PostBuild.cs

using Microsoft.GameCore.Tools;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using Debug = UnityEngine.Debug;


public class PostBuild : IPostprocessBuildWithReport
{

    private string buildWin32OutputFolderPath;
    private string buildMsixvcOutputFolderPath;

    private const string MsixvcOutputDirectory = "MSIXVC";

    public int callbackOrder => 0;

    public void OnPostprocessBuild(BuildReport report)
    {

        string standaloneBuildPath = Path.GetDirectoryName(report.summary.outputPath);

        string gdkBuildOutputPath = Path.Combine(Directory.GetParent(standaloneBuildPath).FullName, MsixvcOutputDirectory).Replace('/','\\');

        Debug.Log($"GDK Build Path:{gdkBuildOutputPath}");

        Setup(standaloneBuildPath, gdkBuildOutputPath);
        OpenBuildOutputFolder();
    }

    private  bool Setup(string pcStandaloneBuildPath, string gdkBuildOutputFolderPath, bool createPackageForStoreUpload=true)
    {
        try
        {
            if (!Directory.Exists(gdkBuildOutputFolderPath))
            {
                Directory.CreateDirectory(gdkBuildOutputFolderPath);
            }
        }
        catch (Exception)
        {
            Debug.LogError("Could not find or create GDK Build output directory: " + gdkBuildOutputFolderPath);
        }

        buildWin32OutputFolderPath = pcStandaloneBuildPath;
        buildMsixvcOutputFolderPath = gdkBuildOutputFolderPath;

        bool succeeded = PostWin32BuildCleanup();
        if (succeeded)
        {
            succeeded = CreateAndConfigureLayoutFile();
        }
        if (succeeded)
        {
            succeeded = MakePackage(createPackageForStoreUpload);
        }

        return succeeded;
    }


    private  bool PostWin32BuildCleanup()
    {
        bool succeeded = true;

        string gameConfigFilePath = Path.Combine(buildWin32OutputFolderPath, "MicrosoftGame.Config");
        string cleanedGameConfigFilePath = gameConfigFilePath.Replace("/", "\\");

        XDocument gameConfigXmlDoc = XDocument.Load(cleanedGameConfigFilePath);
        XElement shellVisualsEl = (from shellVisual in gameConfigXmlDoc.Descendants("ShellVisuals")
            select shellVisual).First();

        // We need to rewrite the manifest to point at where the images will be placed
        // in the build directory.
        shellVisualsEl.SetAttributeValue("Square150x150Logo", Path.GetFileName(PreBuild.originalSquare150x150LogoPath));
        shellVisualsEl.SetAttributeValue("Square44x44Logo", Path.GetFileName(PreBuild.originalSquare44x44LogoPath));
        shellVisualsEl.SetAttributeValue("Square480x480Logo", Path.GetFileName(PreBuild.originalSquare480x480LogoPath));
        shellVisualsEl.SetAttributeValue("SplashScreenImage", Path.GetFileName(PreBuild.originalSplashScreenImagePath));
        shellVisualsEl.SetAttributeValue("StoreLogo", Path.GetFileName(PreBuild.originalStoreLogoPath));

        gameConfigXmlDoc.Save(cleanedGameConfigFilePath);

        return succeeded;
    }


    private bool CreateAndConfigureLayoutFile()
    {
        string arguments = string.Format("/c makepkg.exe genmap /f \"{0}\\layout.xml\" /d \"{0}\"", buildWin32OutputFolderPath);

        if (!GdkEditorHelpers.StartCmdProcess(arguments))
        {
            return false;
        }

        string layoutPath = buildWin32OutputFolderPath + @"\layout.xml";

        var doc = XDocument.Load(layoutPath);
        var ignoredNodes = (from node in doc.Descendants()
            where node.Name == "FileGroup" && node.Attribute("SourcePath").Value.Contains("Package_BackUpThisFolder_ButDontShipItWithYourGame")
            select node).ToArray();

        for (int i = 0; i < ignoredNodes.Length; ++i)
        {
            ignoredNodes[i].Remove();
        }

        doc.Save(layoutPath);

        return true;
    }

    private bool MakePackage(bool createForStoreUpload=true)
    {
        string makePkgExtraArgs = string.Empty;
        if (!string.IsNullOrEmpty(PreBuild.contentIdOverride))
        {
            makePkgExtraArgs = "/contentid " + PreBuild.contentIdOverride;
        }

        string arguments = string.Format("/c makepkg.exe pack /f \"{0}\\layout.xml\" /d \"{0}\" /pd \"{1}\" /pc /CorrelationId Unity " + makePkgExtraArgs, buildWin32OutputFolderPath, buildMsixvcOutputFolderPath);
        if (createForStoreUpload)
        {
            arguments += " /l";
        }

        return GdkEditorHelpers.StartCmdProcess(arguments);
    }


    private  bool OpenBuildOutputFolder()
    {
        bool succeeded = true;
        Process.Start("explorer.exe", buildMsixvcOutputFolderPath);
        return succeeded;
    }


}

from gdk-unity-package.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.