From 12f6935a72130e20088fac45df1ee091092883e5 Mon Sep 17 00:00:00 2001 From: irwin Date: Mon, 12 Jan 2026 16:31:45 +0100 Subject: [PATCH 1/2] VFP Runtime: Implemented AGetFileVersion function with Unit Tests --- .../XSharp.VFP.Tests/FileVersionTests.prg | 36 ++++++++++++++++ .../XSharp.VFP.Tests/XSharp.VFP.Tests.xsproj | 1 + src/Runtime/XSharp.VFP/ArrayFunctions.prg | 43 +++++++++++++++++++ src/Runtime/XSharp.VFP/ToDo-A.prg | 7 --- 4 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg diff --git a/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg b/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg new file mode 100644 index 0000000000..1c9e0afc91 --- /dev/null +++ b/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg @@ -0,0 +1,36 @@ +USING System +USING System.Collections.Generic +USING System.Text +USING XUnit + +BEGIN NAMESPACE XSharp.VFP.Tests + CLASS FileVersionTests + [Fact, Trait("Category", "AGetFileVersion")]; + METHOD BasicSystemDllTest AS VOID + VAR cFile := typeof(System.String):Assembly:Location + + DIMENSION aVer(1) + VAR nCount := AGetFileVersion(aVer, cFile) + + Assert.Equal(15, (INT)nCount) + Assert.Equal(15, (INT)ALen(aVer)) + + // element 2: Company Name + Assert.Contains("Microsoft", (String)aVer[2]) + + // element 4: File version (should not be empty) + Assert.False(String.IsNullOrEmpty((String)aVer[4])) + + // element 10: Product Name (Microsoft® .NET Framework o similar) + Assert.False(String.IsNullOrEmpty((String)aVer[10])) + END METHOD + + [Fact, Trait("Category", "AGetFileVersion")]; + METHOD FileNotFoundTest AS VOID + DIMENSION aVer(1) + VAR nCount := AGetFileVersion(aVer, "c:\non_existent_file.exe") + Assert.Equal(0, (INT)nCount) + Assert.Equal(1, (INT)ALen(aVer)) + END METHOD + END CLASS +END NAMESPACE // XSharp.VFP.Tests diff --git a/src/Runtime/XSharp.VFP.Tests/XSharp.VFP.Tests.xsproj b/src/Runtime/XSharp.VFP.Tests/XSharp.VFP.Tests.xsproj index e77b586264..2ea8890c73 100644 --- a/src/Runtime/XSharp.VFP.Tests/XSharp.VFP.Tests.xsproj +++ b/src/Runtime/XSharp.VFP.Tests/XSharp.VFP.Tests.xsproj @@ -93,6 +93,7 @@ + diff --git a/src/Runtime/XSharp.VFP/ArrayFunctions.prg b/src/Runtime/XSharp.VFP/ArrayFunctions.prg index baa3d4268e..3917c2f02f 100644 --- a/src/Runtime/XSharp.VFP/ArrayFunctions.prg +++ b/src/Runtime/XSharp.VFP/ArrayFunctions.prg @@ -10,6 +10,8 @@ USING System.Collections.Generic USING System.Text USING System.Reflection USING System.Linq +USING System.Diagnostics +USING System.IO INTERNAL FUNCTION FoxALen(a as ARRAY) AS DWORD @@ -422,3 +424,44 @@ FUNCTION AMembers (ArrayName AS ARRAY, oObjectOrClass AS USUAL, nArrayContentsID RETURN nRows END FUNCTION + +/// +FUNCTION AGetFileVersion (ArrayName AS ARRAY, cFileName AS STRING) AS DWORD + IF String.IsNullOrEmpty(cFileName) .OR. !File.Exists(cFileName) + RETURN 0 + ENDIF + + LOCAL oInfo AS FileVersionInfo + TRY + oInfo := FileVersionInfo.GetVersionInfo(cFileName) + CATCH + RETURN 0 + END TRY + + IF String.IsNullOrEmpty(oInfo:FileVersion) + RETURN 0 + ENDIF + + ASize(ArrayName, 15) + + ArrayName[1] := oInfo:Comments ?? "" // 1. Comments + ArrayName[2] := oInfo:CompanyName ?? "" // 2. Company Name + ArrayName[3] := oInfo:FileDescription ?? "" // 3. File Description + ArrayName[4] := oInfo:FileVersion ?? "" // 4. File Version + ArrayName[5] := oInfo:InternalName ?? "" // 5. Internal Name + ArrayName[6] := oInfo:LegalCopyright ?? "" // 6. Legal Copyright + ArrayName[7] := oInfo:LegalTrademarks ?? "" // 7. Legal Trademarks + ArrayName[8] := oInfo:OriginalFilename ?? "" // 8. Original File Name + ArrayName[9] := oInfo:PrivateBuild ?? "" // 9. Private Build + ArrayName[10] := oInfo:ProductName ?? "" // 10. Product Name + ArrayName[11] := oInfo:ProductVersion ?? "" // 11. Product Version + ArrayName[12] := oInfo:SpecialBuild ?? "" // 12. Special Build + ArrayName[13] := "" // 13. OLE Self Registration (Not available in FileVersionInfo) + ArrayName[14] := oInfo:Language ?? "" // 14. Language + ArrayName[15] := "" // 15. Translation Code (this is complex and requires Win32 API) + + // TODO(irwin): Elements 13, 15 require low-level Win32 VerQueryValue API logic + // which FileVersionInfo wraps but does not expose fully. + + RETURN 15 +END FUNCTION diff --git a/src/Runtime/XSharp.VFP/ToDo-A.prg b/src/Runtime/XSharp.VFP/ToDo-A.prg index 1b47da6f16..9846041f60 100644 --- a/src/Runtime/XSharp.VFP/ToDo-A.prg +++ b/src/Runtime/XSharp.VFP/ToDo-A.prg @@ -20,13 +20,6 @@ FUNCTION ADBObjects(ArrayName, cSetting) THROW NotImplementedException{} //RETURN 0 - -/// -- todo -- -/// -FUNCTION AGetFileVersion (ArrayName, cFileName) - THROW NotImplementedException{} - //RETURN 0 - /// -- todo -- /// FUNCTION ANetResources (ArrayName, cNetworkName, nResourceType) From 146e9eb9a19d48786b67ed0ab0b987ff972bdec1 Mon Sep 17 00:00:00 2001 From: Robert van der Hulst Date: Mon, 12 Jan 2026 17:36:07 +0100 Subject: [PATCH 2/2] Update src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg b/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg index 1c9e0afc91..bd901cc142 100644 --- a/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg +++ b/src/Runtime/XSharp.VFP.Tests/FileVersionTests.prg @@ -21,7 +21,7 @@ BEGIN NAMESPACE XSharp.VFP.Tests // element 4: File version (should not be empty) Assert.False(String.IsNullOrEmpty((String)aVer[4])) - // element 10: Product Name (Microsoft® .NET Framework o similar) + // element 10: Product Name (Microsoft® .NET Framework or similar) Assert.False(String.IsNullOrEmpty((String)aVer[10])) END METHOD