开发者

Get version of a .pkg file?

I have a Java application for MAC OSX that I have coded and made a .pkg of it. While creating the .pkg I gave it a version number also. Now I need to get the version number of this application in my java code so that i can check for updates when the application runs. When I right-click on my app file it doesn't show me the version I entered while creating the pac开发者_StackOverflowkage.

Do I need to set the version of my app file that I created using the jar bundler for building the pkg???

Please suggest me how I could accomplish this.


The version number you set while creating the package (in the PackageMaker Project) is the version of the installer, not the version of your .app-File. It is needed, so that another installer can see if he downgrades the current installation or not. The installer will never ever look at the contents it is installing to the system.

To set the version of your your .app-Bundle, right-click your .app-file and select "Show Package Contents" from the appearing menu. Open the folder "Contents", there you will find a file called "Info.plist". You have to edit this file and have to set your version-info for your application there. You can do this by using Property List Editor (included in the Apple Developer Tools) or another tool like BBEdit for example.

To read from your .plist in your application, you need a special library. I recommend the Java property list library from Daniel Dreibrodt (more information about the .plist-Format you'll find in this post on my blog).

Generelly, you should set the version-info of your app-bundle, anyway you use it for updating-purposes or not. If it is not set, the user has no chance to get information about the version he has installed without launching your software.

What you need is not the version of your .pkg file, you need the version of your .app-Bundle. Anyway - the version of your .pkg-file is handled the same way as your .app-file. There is also the Info.plist, where you find the informations. It can also be parsed with the same library.


The pkg is a zip file containing a.o. a file called PackageInfo. PackageInfo is an XML file looking like this:

<pkg-info format-version="2" identifier="com.mycompany.pkg.MyApp" version="1.2.0" overwrite-permissions="false" install-location="/" auth="root">
<payload installKBytes="4717" numberOfFiles="146"/>
<scripts>
    <preinstall file="./preinstall"/>
    <postinstall file="./postinstall"/>
</scripts>
<bundle-version>
    <bundle path="./Applications/MyApp.app" CFBundleShortVersionString="1.2.0" CFBundleVersion="166" id="com.mycompany.MyApp" CFBundleIdentifier="com.mycompany.MyApp">
        <bundle path="./Contents/Library/LoginItems/HelperApp.app" CFBundleShortVersionString="1.0" CFBundleVersion="1" id="com.mycompany.HelperApp" CFBundleIdentifier="com.mycompany.HelperApp"/>
    </bundle>
</bundle-version>
</pkg-info>

To get the package version, you could use the following XPath:

pkg-info/@version

To get the application version:

pkg-info/bundle-version/bundle/@CFBundleShortVersionString

And the build number is here:

pkg-info/bundle-version/bundle/@CFBundleVersion


I know it is a quite old question but the answers are not satisfying. Here is my solution: A MacOS .pkg file is an archive in XAR format. So any XAR archive reader can read its contents. I found an XAR reader for Java from Sprylab here. This library has Apache 2.0 license so it is free to use also for commercial products. It is quite old but it works. The file "Distribution" in the archive is in XML format and gives details about the installer bundle, e.g. the version ;)

I am using JSON so I did not want to add an XML reader for reading just one value. So the following code uses the XAR library and a custom XML reader to extract the version of the bundle in the .pkg installer.

public static void main(String [ ] args) throws XarException  {
  XarSource xar = new FileXarSource(new File("PathToPkgFile/PkgFilename.pkg"));

  XarEntry entry = xar.getEntry("Distribution");
    
  String distributionStr = new String(entry.getBytes());
    
  String bundleVersionXml = getSubstringByStr(distributionStr, "<bundle-version>", "</bundle-version>");
  String bundleAttrStr = getSubstringByStr(bundleVersionXml, "<bundle", "/>");
    
  String version = getAttributeValue(bundleAttrStr, "CFBundleVersion");
    
  System.out.println(bundleVersionXml);
  System.out.println(bundleAttrStr);
  System.out.println(version);
}
  
private static String getSubstringByStr(String xmlString, String start, String end) {
  int startIdx = xmlString.indexOf(start);
  int endIdx = xmlString.indexOf(end);
   
  return xmlString.substring(startIdx + start.length(), endIdx);
}
  
private static String getAttributeValue(String tagContentString, String attribute) {
  int startIdx = tagContentString.indexOf(attribute) + attribute.length() + "=\"".length();
  int endIdx = startIdx + tagContentString.substring(startIdx).indexOf("\"");
    
  return tagContentString.substring(startIdx, endIdx);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜