Reading an Application's Manifest File

reading an application's manifest file?

Windows manifest files are Win32 resources. In other words, they're embedded towards the end of the EXE or DLL. You can use LoadLibraryEx, FindResource, LoadResource and LockResource to load the embedded resource.

Here's a simple example that extracts its own manifest...

BOOL CALLBACK EnumResourceNameCallback(HMODULE hModule, LPCTSTR lpType,
LPWSTR lpName, LONG_PTR lParam)
{
HRSRC hResInfo = FindResource(hModule, lpName, lpType);
DWORD cbResource = SizeofResource(hModule, hResInfo);

HGLOBAL hResData = LoadResource(hModule, hResInfo);
const BYTE *pResource = (const BYTE *)LockResource(hResData);

TCHAR filename[MAX_PATH];
if (IS_INTRESOURCE(lpName))
_stprintf_s(filename, _T("#%d.manifest"), lpName);
else
_stprintf_s(filename, _T("%s.manifest"), lpName);

FILE *f = _tfopen(filename, _T("wb"));
fwrite(pResource, cbResource, 1, f);
fclose(f);

UnlockResource(hResData);
FreeResource(hResData);

return TRUE; // Keep going
}

int _tmain(int argc, _TCHAR* argv[])
{
const TCHAR *pszFileName = argv[0];

HMODULE hModule = LoadLibraryEx(pszFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
EnumResourceNames(hModule, RT_MANIFEST, EnumResourceNameCallback, NULL);
FreeLibrary(hModule);
return 0;
}

Alternatively, you can use MT.EXE from the Windows SDK:

>mt -inputresource:dll_with_manifest.dll;#1 -out:extracted.manifest

Read Manifest file in Spring boot application

I found two ways to solve this problem:

  1. We can use maven-dependency-plugin to unpack the child jar while
    executing the phase prepare-package. This plug in will extract the
    class file from my platform-boot jar to my Service-1.

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.0.2</version>
    <executions>
    <execution>
    <id>unpack</id>
    <phase>prepare-package</phase>
    <goals>
    <goal>unpack</goal>
    </goals>
    <configuration>
    <artifactItems>
    <artifactItem>
    <groupId>my.platform</groupId>
    <artifactId>platform-boot</artifactId>
    <type>jar</type>
    <overWrite>false</overWrite>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <includes>**/*.class,**/*.xml,**/*.text</includes>
    <excludes>**/*test.class</excludes>
    </artifactItem>
    </artifactItems>
    <includes>**/*.java, **/*.text</includes>
    <excludes>**/*.properties</excludes>
    <overWriteReleases>false</overWriteReleases>
    <overWriteSnapshots>true</overWriteSnapshots>
    </configuration>
    </execution>
    </executions>
    </plugin>
  2. Second approach is much simpler, in spring-boot-maven-plugin add a goal
    build-info. This will write a file build-info.properties in your META-INF folder and is accessible in code as below.

    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
    <execution>
    <goals>
    <goal>build-info</goal>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>

    In your main method you can get this information using the BuildProperties
    bean already registered in ApplicationContext.

    ApplicationContext ctx = SpringApplication.run(Application.class, args);
    BuildProperties properties = ctx.getBean(BuildProperties.class);

    In fact, Spring-actuator also uses this BuildProperties to get the build
    information which is helpful in monitoring.

Reading my own Jar's Manifest

You can do one of two things:

  1. Call getResources() and iterate through the returned collection of URLs, reading them as manifests until you find yours:

    Enumeration<URL> resources = getClass().getClassLoader()
    .getResources("META-INF/MANIFEST.MF");
    while (resources.hasMoreElements()) {
    try {
    Manifest manifest = new Manifest(resources.nextElement().openStream());
    // check that this is your manifest and do what you need or get the next one
    ...
    } catch (IOException E) {
    // handle
    }
    }
  2. You can try checking whether getClass().getClassLoader() is an instance of java.net.URLClassLoader. Majority of Sun classloaders are, including AppletClassLoader.
    You can then cast it and call findResource() which has been known - for applets, at least - to return the needed manifest directly:

    URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
    try {
    URL url = cl.findResource("META-INF/MANIFEST.MF");
    Manifest manifest = new Manifest(url.openStream());
    // do stuff with it
    ...
    } catch (IOException E) {
    // handle
    }

Reading the manifest of an EXE or DLL without loading it

You can also get an HMODULE from LoadLibraryEx(file, 0, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE).

Reading an EAR's manifest

You need to locate where the ear file is and then get the manifest by:

new java.util.jar.JarFile(file).getManifest();

read the office add-in manifest file from the react app which is inside the Outlook task pane

If the manifest file is hosted anywhere and the URL is clearly defined on the web server you can use the XMLHttpRequest Web API to get the data programmatically. Otherwise, there is no way - OfficeJS doesn't provide anything for that.



Related Topics



Leave a reply



Submit