public static string GetVersion(string libFolderPath, string libAssembly)
        {
            switch (GetVersionType(libFolderPath, libAssembly))
            {
            case VersionType.Unknown:
                return("");

            case VersionType.V1:
            case VersionType.V2:
            {
                using var fs       = File.OpenRead(Path.Combine(libFolderPath, libAssembly));
                using var peReader = new System.Reflection.PortableExecutable.PEReader(fs);
                var mdReader = peReader.GetMetadataReader(MetadataReaderOptions.None);
                var versionVirtualFileAttribute = GetVirtualFileAttribute(mdReader);
                var attributeReader             = mdReader.GetBlobReader(versionVirtualFileAttribute.Value);
                attributeReader.ReadByte();
                attributeReader.ReadByte();
                attributeReader.ReadSerializedString();
                var xml = attributeReader.ReadSerializedString();
                using var xmlReader = new XmlTextReader(new StringReader(xml));
                xmlReader.Read();
                xmlReader.MoveToAttribute("Value");
                return(xmlReader.Value);
            }

            case VersionType.V3:
            {
                using var fs       = File.OpenRead(Path.Combine(libFolderPath, libAssembly));
                using var peReader = new System.Reflection.PortableExecutable.PEReader(fs);
                var mdReader = peReader.GetMetadataReader(MetadataReaderOptions.None);
                var versionVirtualFileAttribute = GetVirtualFileAttribute(mdReader);
                var attributeReader             = mdReader.GetBlobReader(versionVirtualFileAttribute.Value);
                attributeReader.ReadByte();
                attributeReader.ReadByte();
                attributeReader.ReadSerializedString();
                var xml = attributeReader.ReadSerializedString();
                using var xmlReader = new XmlTextReader(new StringReader(xml));
                xmlReader.Read();
                xmlReader.ReadToDescendant("Singleplayer");
                xmlReader.MoveToAttribute("Value");
                return(xmlReader.Value);
            }

            case VersionType.V4:
            {
                using var fs     = File.OpenRead(Path.Combine(libFolderPath, "Version.xml"));
                using var reader = new StreamReader(fs);
                var xml = reader.ReadToEnd();
                using var xmlReader = new XmlTextReader(new StringReader(xml));
                xmlReader.Read();
                xmlReader.ReadToDescendant("Singleplayer");
                xmlReader.MoveToAttribute("Value");
                var split = xmlReader.Value.Split('.', StringSplitOptions.RemoveEmptyEntries);
                return(string.Join('.', split.Take(split.Length - 1)));
            }

            default:
                return("");
            }
        }
示例#2
0
            public SharedTestState()
            {
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    // COM activation is only supported on Windows
                    return;
                }

                ComLibraryFixture = new TestProjectFixture("ComLibrary", RepoDirectories)
                                    .EnsureRestored(RepoDirectories.CorehostPackages)
                                    .BuildProject();

                // Create a .clsidmap from the assembly
                string clsidMapPath = Path.Combine(BaseDirectory, $"{ ComLibraryFixture.TestProject.AssemblyName }.clsidmap");

                using (var assemblyStream = new FileStream(ComLibraryFixture.TestProject.AppDll, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))
                    using (var peReader = new System.Reflection.PortableExecutable.PEReader(assemblyStream))
                    {
                        if (peReader.HasMetadata)
                        {
                            MetadataReader reader = peReader.GetMetadataReader();
                            ClsidMap.Create(reader, clsidMapPath);
                        }
                    }

                // Use the locally built comhost to create a comhost with the embedded .clsidmap
                ComHostPath = Path.Combine(
                    ComLibraryFixture.TestProject.BuiltApp.Location,
                    $"{ ComLibraryFixture.TestProject.AssemblyName }.comhost.dll");
                ComHost.Create(
                    Path.Combine(RepoDirectories.CorehostPackages, "comhost.dll"),
                    ComHostPath,
                    clsidMapPath);
            }
            public SharedTestState()
            {
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    // COM activation is only supported on Windows
                    return;
                }

                using (var assemblyStream = new FileStream(ComLibraryFixture.TestProject.AppDll, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))
                    using (var peReader = new System.Reflection.PortableExecutable.PEReader(assemblyStream))
                    {
                        if (peReader.HasMetadata)
                        {
                            string regFreeManifestPath = Path.Combine(BaseDirectory, $"{ ComLibraryFixture.TestProject.AssemblyName }.X.manifest");

                            MetadataReader reader = peReader.GetMetadataReader();
                            RegFreeComManifest.CreateManifestFromClsidmap(
                                ComLibraryFixture.TestProject.AssemblyName,
                                Path.GetFileName(ComHostPath),
                                reader.GetAssemblyDefinition().Version.ToString(),
                                ClsidMapPath,
                                regFreeManifestPath,
                                TypeLibraries
                                );
                        }
                    }

                string testDirectoryPath = Path.GetDirectoryName(NativeHostPath);
                string comsxsName        = RuntimeInformationExtensions.GetExeFileNameForCurrentPlatform("comsxs");

                ComSxsPath = Path.Combine(testDirectoryPath, comsxsName);
                File.Copy(
                    Path.Combine(RepoDirectories.Artifacts, "corehost_test", comsxsName),
                    ComSxsPath);
                File.Copy(
                    ComHostPath,
                    Path.Combine(testDirectoryPath, Path.GetFileName(ComHostPath)));
                File.Copy(
                    ComLibraryFixture.TestProject.AppDll,
                    Path.Combine(testDirectoryPath, Path.GetFileName(ComLibraryFixture.TestProject.AppDll)));
                File.Copy(
                    ComLibraryFixture.TestProject.DepsJson,
                    Path.Combine(testDirectoryPath, Path.GetFileName(ComLibraryFixture.TestProject.DepsJson)));
                File.Copy(
                    ComLibraryFixture.TestProject.RuntimeConfigJson,
                    Path.Combine(testDirectoryPath, Path.GetFileName(ComLibraryFixture.TestProject.RuntimeConfigJson)));
            }
示例#4
0
            public SharedTestState()
            {
                if (!OperatingSystem.IsWindows())
                {
                    // COM activation is only supported on Windows
                    return;
                }

                ComLibraryFixture = new TestProjectFixture("ComLibrary", RepoDirectories)
                                    .EnsureRestored()
                                    .BuildProject();

                // Create a .clsidmap from the assembly
                ClsidMapPath = Path.Combine(BaseDirectory, $"{ ComLibraryFixture.TestProject.AssemblyName }.clsidmap");
                using (var assemblyStream = new FileStream(ComLibraryFixture.TestProject.AppDll, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))
                    using (var peReader = new System.Reflection.PortableExecutable.PEReader(assemblyStream))
                    {
                        if (peReader.HasMetadata)
                        {
                            MetadataReader reader = peReader.GetMetadataReader();
                            ClsidMap.Create(reader, ClsidMapPath);
                        }
                    }

                // Use the locally built comhost to create a comhost with the embedded .clsidmap
                ComHostPath = Path.Combine(
                    ComLibraryFixture.TestProject.BuiltApp.Location,
                    $"{ ComLibraryFixture.TestProject.AssemblyName }.comhost.dll");

                // Include the test type libraries in the ComHost tests.
                TypeLibraries = new Dictionary <int, string>
                {
                    { 1, Path.Combine(RepoDirectories.Artifacts, "corehost_test", "Server.tlb") },
                    { 2, Path.Combine(RepoDirectories.Artifacts, "corehost_test", "Nested.tlb") }
                };

                ComHost.Create(
                    Path.Combine(RepoDirectories.HostArtifacts, "comhost.dll"),
                    ComHostPath,
                    ClsidMapPath,
                    TypeLibraries);
            }
        public static int GetChangeSet(string libFolderPath, string libAssembly)
        {
            switch (GetVersionType(libFolderPath, libAssembly))
            {
            case VersionType.Unknown:
                return(0);

            case VersionType.V1:
                return(0);

            case VersionType.V2:
            case VersionType.V3:
            {
                using var fs       = File.OpenRead(Path.Combine(libFolderPath, libAssembly));
                using var peReader = new System.Reflection.PortableExecutable.PEReader(fs);
                var mdReader        = peReader.GetMetadataReader(MetadataReaderOptions.None);
                var changeSetHandle = mdReader.TypeDefinitions
                                      .GetType(mdReader, "TaleWorlds.Library", "ApplicationVersion")
                                      .GetField(mdReader, "DefaultChangeSet")
                                      .GetDefaultValue();
                var changeSetBlob = mdReader.GetConstant(changeSetHandle).Value;

                return(mdReader.GetBlobReader(changeSetBlob).ReadInt32());
            }

            case VersionType.V4:
            {
                using var fs     = File.OpenRead(Path.Combine(libFolderPath, "Version.xml"));
                using var reader = new StreamReader(fs);
                var xml = reader.ReadToEnd();
                using var xmlReader = new XmlTextReader(new StringReader(xml));
                xmlReader.Read();
                xmlReader.ReadToDescendant("Singleplayer");
                xmlReader.MoveToAttribute("Value");
                var split = xmlReader.Value.Split('.', StringSplitOptions.RemoveEmptyEntries);
                return(int.Parse(split.Last()));
            }

            default:
                return(0);
            }
        }
示例#6
0
            public SharedTestState()
            {
                if (!OperatingSystem.IsWindows())
                {
                    // COM activation is only supported on Windows
                    return;
                }

                string comsxsDirectory     = BaseDirectory;
                string regFreeManifestName = $"{ ComLibraryFixture.TestProject.AssemblyName }.X.manifest";
                string regFreeManifestPath = Path.Combine(comsxsDirectory, regFreeManifestName);

                using (var assemblyStream = new FileStream(ComLibraryFixture.TestProject.AppDll, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))
                    using (var peReader = new System.Reflection.PortableExecutable.PEReader(assemblyStream))
                    {
                        if (peReader.HasMetadata)
                        {
                            MetadataReader reader = peReader.GetMetadataReader();
                            RegFreeComManifest.CreateManifestFromClsidmap(
                                ComLibraryFixture.TestProject.AssemblyName,
                                Path.GetFileName(ComHostPath),
                                reader.GetAssemblyDefinition().Version.ToString(),
                                ClsidMapPath,
                                regFreeManifestPath,
                                TypeLibraries
                                );
                        }
                    }

                string comsxsName = RuntimeInformationExtensions.GetExeFileNameForCurrentPlatform("comsxs");

                ComSxsPath = Path.Combine(comsxsDirectory, comsxsName);
                File.Copy(
                    Path.Combine(RepoDirectories.Artifacts, "corehost_test", comsxsName),
                    ComSxsPath);

                ManagedHostFixture_FrameworkDependent = new TestProjectFixture("ManagedHost", RepoDirectories)
                                                        .EnsureRestored()
                                                        .PublishProject(selfContained: false, extraArgs: "/p:RegFreeCom=true");
                File.Copy(regFreeManifestPath, Path.Combine(ManagedHostFixture_FrameworkDependent.TestProject.BuiltApp.Location, regFreeManifestName));

                ManagedHostFixture_SelfContained = new TestProjectFixture("ManagedHost", RepoDirectories)
                                                   .EnsureRestored()
                                                   .PublishProject(selfContained: true, extraArgs: "/p:RegFreeCom=true");
                File.Copy(regFreeManifestPath, Path.Combine(ManagedHostFixture_SelfContained.TestProject.BuiltApp.Location, regFreeManifestName));

                // Copy the ComLibrary output and comhost to the ComSxS and ManagedHost directories
                string[] toCopy =
                {
                    ComLibraryFixture.TestProject.AppDll,
                    ComLibraryFixture.TestProject.DepsJson,
                    ComLibraryFixture.TestProject.RuntimeConfigJson,
                    ComHostPath,
                };
                foreach (string filePath in toCopy)
                {
                    File.Copy(filePath, Path.Combine(comsxsDirectory, Path.GetFileName(filePath)));
                    File.Copy(filePath, Path.Combine(ManagedHostFixture_FrameworkDependent.TestProject.BuiltApp.Location, Path.GetFileName(filePath)));
                    File.Copy(filePath, Path.Combine(ManagedHostFixture_SelfContained.TestProject.BuiltApp.Location, Path.GetFileName(filePath)));
                }
            }
        public static VersionType GetVersionType(string libFolderPath, string libAssembly)
        {
            if (File.Exists(Path.Combine(libFolderPath, "Version.xml")))
            {
                return(VersionType.V4);
            }

            using var fs       = File.OpenRead(Path.Combine(libFolderPath, libAssembly));
            using var peReader = new System.Reflection.PortableExecutable.PEReader(fs);
            var mdReader = peReader.GetMetadataReader(MetadataReaderOptions.None);


            var applicationVersionDef = mdReader.TypeDefinitions
                                        .GetType(mdReader, "TaleWorlds.Library", "ApplicationVersion");
            var hasChangeSet = applicationVersionDef.GetFields()
                               .Any(f => mdReader.GetString(mdReader.GetFieldDefinition(f).Name) == "DefaultChangeSet");


            var versionVirtualFileAttribute = GetVirtualFileAttribute(mdReader);

            var attributeReader = mdReader.GetBlobReader(versionVirtualFileAttribute.Value);

            if (attributeReader.ReadByte() != 0x01 || attributeReader.ReadByte() != 0x00)
            {
                throw new NotImplementedException("Custom Attribute prolog is invalid.");
            }

            var fn = attributeReader.ReadSerializedString();

            if (fn != "Version.xml")
            {
                throw new NotImplementedException("Version field doesn't have Version.xml attribute.");
            }

            var xml = attributeReader.ReadSerializedString();

            using var xmlReader = new XmlTextReader(new StringReader(xml));

            if (!xmlReader.Read())
            {
                throw new NotImplementedException("Can't parse XML content of Version.xml");
            }

            if (hasChangeSet)
            {
                if (!xmlReader.MoveToAttribute("Value"))
                {
                    if (!xmlReader.ReadToDescendant("Singleplayer"))
                    {
                        return(VersionType.Unknown);
                    }
                    return(VersionType.V3);
                }
                return(VersionType.V2);
            }
            else
            {
                if (!xmlReader.MoveToAttribute("Value"))
                {
                    return(VersionType.Unknown);
                }
                return(VersionType.V1);
            }
        }