Jump to content

Recommended Posts

Posted

I have two different PowerShell scripts that achieve the same thing. Either one can be used as an example. But essentially I need to create a function in AutoIt that does the same thing. The problem is that I don't even understand the math operations involved. I tried playing around with BitShift and BitAND for about an hour but I was completely unsuccessful.

Script1:

# example
$packed = 2814749767106561

# decoding
$major = $packed -shr 48
$minor = $packed -shr 32 -band 0xffff
$build = $packed -shr 16 -band 0xffff
$revision = $packed -band 0xffff

"$major.$minor.$build.$revision"

Script2:

$exampleversion = "2814749767106561"
$binexampleversion = [Convert]::ToString($exampleversion,2)
$patch = [Convert]::ToInt32($binexampleversion.Substring($binexampleversion.Length-16),2)
$build = [Convert]::ToInt32($binexampleversion.Substring($binexampleversion.Length-32, 16),2)
$minor = [Convert]::ToInt32($binexampleversion.Substring($binexampleversion.Length-48, 16),2)
$major = [Convert]::ToInt32($binexampleversion.Substring(0, $binexampleversion.Length -64 +16),2)
"$major.$minor.$build.$patch"

 

Both scripts take in the number 2814749767106561 and spits out a version string: 10.0.0.1

That initial number will vary, of course. It's just used as an example.

If someone is able to help me create a function for AutoIt, my next step will be to create a loop to go through a column in an array or listview. I can do that part. But I really don't understand the math involved above to create the function in the first place.

The function can be based off of either script because they both do the exact same thing.

Thank you for your time. I appreciate it.

  • Solution
Posted (edited)

I would do something like this:

#include <Constants.au3>

MsgBox($MB_ICONINFORMATION, "Info", "Version = " & get_version_number(2814749767106561))

Func get_version_number($iVersion)
    Local $tUInt64  = DllStructCreate("uint64 value;"), _
          $tVersion = DllStructCreate("word revision; word build; word minor; word major", DllStructGetPtr($tUInt64))

    $tUInt64.value = $iVersion

    Return StringFormat('%i.%i.%i.%i', $tVersion.major, $tVersion.minor, $tVersion.build, $tVersion.revision)
EndFunc

 

Edited by TheXman
Posted (edited)

What a great community! Thank you all for your help. Without a doubt, having multiple code snippets to play with really helps to understand how certain things work and opens up the mind for someone like myself who is still learning. I appreciate it.

@TheXman and @pixelsearch

Both of your examples worked in 100% of the use cases that I passed to them. Not a single failure and all matched up to the expected version strings. Performance was great as well.

Now I just have to create the loop to swap (up to 32) version numbers in an array. So I will just have to see which example suits the functionality of the loop. I should be able to do this part by myself.

@Nine

You're right. That also explains why my results were coming out wrong even when I was sure that I had at least some of it done right.

I tried with your UDF and sure enough, it did work. I can technically use your UDF and have a much smaller sized function in the end. The only thing that I am hesitant about is bundling the DLL with it. I could FileInstall it. But my goal is to have a single, portable executable for my app. I am still on the fence about it.

Edited by WildByDesign
spelling
Posted (edited)

@WildByDesign

Just in case you need to generate a version number from the version string parts, I added a function that shows the inverse conversion. 

Although the inverse conversion may be obvious to me, it might not be so obvious to others how simple it is, especially for those who are not familiar with structs and how values are stored in memory. ;)

#include <Constants.au3>

MsgBox($MB_ICONINFORMATION, "Info", _
       "Version string = " & get_version_string(2814749767106561) & @CRLF & _
       "Version number = " & get_version_number(10, 0, 0, 1) _
       )

Func get_version_string($iVersion)
    Local $tVerNum  = DllStructCreate("uint64 value;"), _
          $tVersion = DllStructCreate("word revision; word build; word minor; word major", DllStructGetPtr($tVerNum))

    ;Load integer into struct
    $tVerNum.value = $iVersion

    ;Return version string
    Return StringFormat('%i.%i.%i.%i', $tVersion.major, $tVersion.minor, $tVersion.build, $tVersion.revision)
EndFunc

Func get_version_number($iMajor, $iMinor = 0, $iBuild = 0, $iRevision = 0)
    Local $tVerNum       = DllStructCreate("uint64 value;"), _
          $tVersion      = DllStructCreate("word revision; word build; word minor; word major", DllStructGetPtr($tVerNum))

    ;Load version parts into struct
    $tVersion.major    = $iMajor
    $tVersion.minor    = $iMinor
    $tVersion.build    = $iBuild
    $tVersion.revision = $iRevision

    ;Return version number
    Return $tVerNum.value
EndFunc

 

Edited by TheXman
Posted
Posted

I just wanted to thank everyone again for helping. I learned a lot from this experience too.

The loop ended up working great and I am able to convert all of the integers into version strings for the whole array column which gets fed into a listview shortly after. Cheers!

 

4 hours ago, TheXman said:

Just in case you need to generate a version number from the version string parts, I added a function that shows the inverse conversion.

Thank you so much. I can probably use the inverse conversion also.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...