-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added VersionUtil class and utility method for obtaining file version information #562
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* Copyright (c) 2015 Michael Freeman, All Rights Reserved | ||
* | ||
* This library is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 2.1 of the License, or (at your option) any later version. | ||
* | ||
* This library is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
*/ | ||
package com.sun.jna.platform.win32; | ||
|
||
import com.sun.jna.Memory; | ||
import com.sun.jna.Native; | ||
import com.sun.jna.Pointer; | ||
import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO; | ||
import com.sun.jna.platform.win32.Version; | ||
import com.sun.jna.platform.win32.Win32Exception; | ||
import com.sun.jna.ptr.IntByReference; | ||
import com.sun.jna.ptr.PointerByReference; | ||
|
||
/** | ||
* Reads Windows Version info from files (the version details you can see by | ||
* right-clicking and choosing properties) | ||
* | ||
* @author mlfreeman[at]gmail.com | ||
*/ | ||
public class VersionUtil { | ||
|
||
/** | ||
* Gets the file's version number info | ||
* | ||
* @param filePath | ||
* The path to the file | ||
* @return The VS_FIXEDFILEINFO structure read from the file.<br> | ||
* Use the getFileVersionMajor(), getFileVersionMinor(), | ||
* getFileVersionRevision(), and getFileVersionBuild() | ||
* @throws UnsupportedOperationException | ||
* if VerQueryValue fails to get version info from the file. | ||
*/ | ||
public static VS_FIXEDFILEINFO getFileVersionInfo(String filePath) { | ||
IntByReference dwDummy = new IntByReference(); | ||
|
||
int versionLength = Version.INSTANCE.GetFileVersionInfoSize(filePath, dwDummy); | ||
|
||
// Reading version info failed. | ||
// throw a Win32Exception with GetLastError() | ||
if (versionLength == 0) { | ||
throw new Win32Exception(Native.getLastError()); | ||
} | ||
|
||
// buffer to hold version info | ||
Pointer lpData = new Memory(versionLength); | ||
|
||
// pointer to pointer to location in aforementioned buffer | ||
PointerByReference lplpBuffer = new PointerByReference(); | ||
|
||
if (!Version.INSTANCE.GetFileVersionInfo(filePath, 0, versionLength, lpData)) { | ||
throw new Win32Exception(Native.getLastError()); | ||
} | ||
|
||
// here to make VerQueryValue happy. | ||
IntByReference puLen = new IntByReference(); | ||
|
||
// this does not set GetLastError, so no need to throw a Win32Exception | ||
if (!Version.INSTANCE.VerQueryValue(lpData, "\\", lplpBuffer, puLen)) { | ||
throw new UnsupportedOperationException("Unable to extract version info from the file: \"" + filePath + "\""); | ||
} | ||
|
||
VS_FIXEDFILEINFO fileInfo = new VS_FIXEDFILEINFO(lplpBuffer.getValue()); | ||
fileInfo.read(); | ||
return fileInfo; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* This library is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 2.1 of the License, or (at your option) any later version. | ||
* | ||
* This library is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
*/ | ||
package com.sun.jna.platform.win32; | ||
|
||
import java.io.File; | ||
|
||
import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO; | ||
|
||
import junit.framework.TestCase; | ||
|
||
public class VersionUtilTest extends TestCase { | ||
|
||
public static void main(String[] args) { | ||
junit.textui.TestRunner.run(VersionUtilTest.class); | ||
} | ||
|
||
public void testGetFileVersionNumbers() { | ||
String testFileName = "regedit.exe"; | ||
File file = new File(System.getenv("SystemRoot"), testFileName); | ||
assertTrue("Test file with version info in it should exist.", file.exists()); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be more specific: assertTrue("Test file not found: " + file, file.exists()); This may seem superfluous since it is "obvious" that you are looking for regedit.exe. However, what if the test system is mis-configured and SystemRoot is not defined or defined incorrectly ? The "message-less" assertion would not provide enough information to diagnose the failure. Failing assertions should provide as much information as possible to enable us to diagnose the problem. |
||
VS_FIXEDFILEINFO version = VersionUtil.getFileVersionInfo(file.getAbsolutePath()); | ||
assertNotNull("Version info should have been returned.", version); | ||
|
||
assertTrue("The major file version number should be greater than 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionMajor() > 0); | ||
assertTrue("The minor file version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionMinor() >= 0); | ||
assertTrue("The revision file version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionRevision() >= 0); | ||
assertTrue("The build file version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionBuild() > 0); | ||
|
||
assertTrue("The major product version number should be greater than 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionMajor() > 0); | ||
assertTrue("The minor product version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionMinor() >= 0); | ||
assertTrue("The revision product version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionRevision() >= 0); | ||
assertTrue("The build product version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionBuild() > 0); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of returning an int[], return a class - e.g.:
This way one does not need to remember which index in the array is the major/minor/build/revision...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this sound as an option?
getFileVersionInfo()
VS_FIXEDFILEINFO
that I already have in the function.VS_FIXEDFILEINFO
: