-
Notifications
You must be signed in to change notification settings - Fork 33
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
Include build number when renaming hotfix releases of Unity #274
Comments
It would be useful if u3d looked for some kind of overrideVersion.txt file in a Unity installation, in case two copies of the same version are installed for other reasons. But that is less critical than the hotfix releases. |
Hello @JensRestemeier Thanks for the feedback. This sounds like a feature for u3d. We'll look into it. |
I googled a bit and here are some findings/links. Here's the full native version of a function we could use https://www.conedogers.com/2012/08/06/retrieving-windows-vs_versioninfo-struct-from-a-binary/ to retrieve the Windows Exe information Various ruby wrappers that implement part of this: |
This code works for me: require "Win32API"
GetFileVersionInfoSize = Win32API.new('version.dll', 'GetFileVersionInfoSize','PP','L')
GetFileVersionInfo = Win32API.new('version.dll', 'GetFileVersionInfo','PIIP','I')
VerQueryValue = Win32API.new('version.dll', 'VerQueryValue','PPPP','I')
RtlMoveMemory = Win32API.new('kernel32.dll', 'RtlMoveMemory', 'PLL', 'I')
def string_file_info(info, path)
begin
file = path.gsub(/\//,"\\")
buf = [0].pack('L')
version_size = GetFileVersionInfoSize.call(file + "\0", buf)
raise Exception.new if version_size == 0 # TODO use GetLastError
version_info = 0.chr * version_size
version_ok = GetFileVersionInfo.call(file, 0, version_size, version_info)
raise Exception.new if version_ok == 0 # TODO use GetLastError
# hardcoding lang codepage
struct_path = "\\StringFileInfo\\040904b0\\#{info}"
addr = [0].pack('L')
size = [0].pack('L')
query_ok = VerQueryValue.call(version_info, struct_path + "\0", addr, size)
raise Exception.new if query_ok == 0
raddr = addr.unpack('L')[0]
rsize = size.unpack('L')[0]
info = Array.new(rsize,0).pack('L*')
RtlMoveMemory.call(info, raddr, info.length)
info.strip
rescue Exception => e
#puts e
#puts e.backtrace
"N/A"
end
end
FILENAME = "C:/Program Files/Unity/Editor/Unity.exe"
infos = ["CompanyName","LegalCopyright","ProductVersion","FileDescription","LegalTrademarks","PrivateBuild","FileVersion","OriginalFilename","SpecialBuild", # predefined VerQueryValue string-names
"Unity Version", "FileVersion", "ProductName"] # Unity specific?
infos.each { |info| r = string_file_info(info, FILENAME); puts "#{info}: #{r}" }
# gives
%Q(
CompanyName: Unity Technologies ApS
LegalCopyright: (c) 2018 Unity Technologies ApS. All rights reserved.
ProductVersion: 2017.4.1.9581049
FileDescription: Unity Editor
LegalTrademarks: N/A
PrivateBuild: N/A
FileVersion: 2017.4.1.9581049
OriginalFilename: N/A
SpecialBuild: N/A
Unity Version: 2017.4.1f1_9231f953d9d3
FileVersion: 2017.4.1.9581049
ProductName: Unity
) |
I just tested it locally, and it gave me the following:
|
And I was looking at the release notes for 2017.2.2 and found reference to this: So some version of Unity don't have version information... This is going to be fun. |
That is the player executable, isn't it? That is the executable that is copied into the player folder to create a stand alone game, not the editor executable. |
I think Linux is going to need a custom solution, as there is no standard way to embed resources into a binary. There is the option to add custom sections to an elf file through the linker, but I have not idea if Unity does that, or which section they use... If you have a Linux version of the editor around you could use objdump or readelf to look for any custom sections. Otherwise you'd have to grep for the string in the .rodata section. |
@JensRestemeier ah yes, it was the Player. Good. For Linux we could go
So this works
I could use readelf to make it more efficient. |
@JensRestemeier I've added (as a PR) the foundation for detecting the build number. It will part of next release, feel free to test it. Then will remain to design the feature set for using this. I'll make a proposal later. |
I don't have a proposal. I have too many questions! To properly support this in all the features we need to look at the consequences / potential features:
|
u3d/list: display full revision number (prepares for #274)
I added a section on build numbers: https://github.com/DragonBox/u3d#unity-build-numbers We will release 1.0.20 now and think about the proper full support for hotfixes in the coming weeks. Please test 1.0.20 when it is out! Thanks |
list:
install:
internals:
u3d run/install: For me both a runtime argument and a separate manifest file in the project folder would work. |
@JensRestemeier question: are your hot fixes distributed through a hidden URL similar to this: I.e. if I was feeding that URL to u3d install, would u3d be able to deal with it in the same way it deals with the official releases? (i.e. find the modules, etc). Or are those URLs hidden behind some user/password mechanism. If the download URL is just hidden, we could do something like that
When it comes to channels, I had code for supporting alpha releases as well. I haven't published it because it requires to manage credentials and wasn't sure many people would use it. |
It is a non-standard url scheme and password, at least for the ones we received. I am not sure if Unity would be happy if I went into more detail, and details may depend on which team handles the ticket. |
@JensRestemeier understood. So here's a proposal:
u3d mv VERSION|DIR_PATH DIR_NAME/DIR_PATH u3d mv -f|--force -l|--long VERSION|DIR_PATH --long uses full path Unity_$version_$buildnumber confirm y/n except if -f added or if a existing directory exists
for all the installed unities Does that sound good? |
Yes, that sounds great! |
By the way, I just had a thought how I'd implement version resources on Linux for a program, as there is no standard to do that. You can add custom sections to an ELF, but they are not standardised. I don't have Linux running right now, or the Linux editor, or access to elf tools. It would be interesting to see if there is a symbol left to point at the start of the version string. That may be faster and safer to use than a general string search. |
@JensRestemeier the implementation I made on Linux searches for the string in different places where Unity adds the string we are looking for. I found a few very small files and it takes a negliegeable amount of time (think 0.040s). I fall back on the Editor. $ u3d console
>> require 'benchmark'
true
>> puts Benchmark.measure { U3d::LinuxInstallationHelper.new.find_build_number('/opt/unity-editor-2017.3.0f1') }
0.020000 0.000000 0.040000 ( 0.041639)
nil |
@JensRestemeier I added a PR and briefly tested it. I will need to clean it up quite a bit, but it shows the general idea. It looks like it worked. For now I only support:
|
Thank you, I'll have a look. |
u3d/move command, renaming install dirs. Support long version names. Fixes #274
Issue Checklist
u3d --help
Issue Description
We sometimes have hotfix releases installed in parallel to official releases. They'll have the same version, but they'll have a different revision code. Renaming them to the plain version number will not be possible because of the conflict to the official release.
When I install them manually I usually use the Unity_<version>_<revision> pattern.
Suggestion:
The official revision seems to be used as part of the download url, i.e.:
This revision is displayed in Unity in Help/About after pressing "Alt" on the keyboard.
At the start of the log file:
Unfortunately I haven't found a good way to find this without running Unity, yet. On OSX it is in the UnityBuildNumber plist key. On Windows there seems to be a special "Unity Version" resource in the exe:
This can be seen in "Resource Hacker". I am not a Ruby hacker, so I have no idea if there is a package to open .exe version resources...
The text was updated successfully, but these errors were encountered: