Skip to content

Commit 5dbaafc

Browse files
authored
Merge pull request #774 from asherber/win-zip
Use PowerShell instead of 7Zip on Windows
2 parents 0d929c7 + 65538b1 commit 5dbaafc

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

src/library/ziputils.lua

+33-10
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ Functions for unzipping files. (Future may include zipping as well.)
55
66
Dependencies:
77
8-
- Windows users must have `7z` installed. You can download it [here](https://www.7-zip.org/).
9-
- MacOS users must have `unzip` and `gunzip`, but these are usually installed with the OS.
8+
- The Windows version uses `PowerShell`.
9+
- The macOS version uses `unzip` and `gunzip`.
10+
- In both cases the necessary tools are pre-installed with a typical installation of any version
11+
of the OS that supports 64-bit Finale.
1012
1113
Pay careful attention to the comments about how strings are encoded. They are either encoded
1214
**platform** or **utf8**. On macOS, platform encoding is always utf8, but on Windows it can
1315
be any number of encodings depending on the locale settings and version of Windows. You can use
14-
`luaosutils.text` to convert them back and forth. Both `luaosutils.process.execute`
15-
requires platform encoding as do `lfs` and all built-in Lua `io` functions.
16+
`luaosutils.text` to convert them back and forth. (Use the `get_default_codepage` function to get
17+
the platform encoding.) The `luaosutils.process.execute` function requires platform encoding as do
18+
`lfs` and all built-in Lua `os` and `io` functions that take strings as input.
1619
1720
Note that many functions require later versions of RGP Lua that include `luaosutils`
1821
and/or `lfs`. But the these dependencies are embedded in each function so that any version
@@ -75,7 +78,6 @@ Returns a path that can be used as a temporary target for unzipping. The caller
7578
either as a file or a directory, because it is guaranteed not to exist when it is returned and it does
7679
not have a terminating path delimiter. Also returns a platform-dependent unzip command that can be
7780
passed to `luaosutils.process.execute` to unzip the input archive into the temporary name as a directory.
78-
The command may not be compatible with `os.execute`.
7981
8082
This function requires `luaosutils`.
8183
@@ -100,33 +102,49 @@ function ziputils.calc_temp_output_path(archive_path)
100102
if finenv.UI():IsOnMac() then
101103
zipcommand = "unzip \"" .. archive_path .. "\" -d " .. output_dir
102104
else
103-
zipcommand = "cmd /c 7z x -o" .. output_dir .. " \"" .. archive_path .. "\""
105+
zipcommand = [[
106+
$archivePath = '%s'
107+
$outputDir = '%s'
108+
$zipPath = $archivePath + '.zip'
109+
Copy-Item -Path $archivePath -Destination $zipPath
110+
Expand-Archive -Path $zipPath -DestinationPath $outputDir
111+
Remove-Item -Path $zipPath
112+
]]
113+
zipcommand = string.format(zipcommand, archive_path, output_dir)
114+
zipcommand = string.format("powershell -c & { %s }", zipcommand)
104115
end
105116
return output_dir, zipcommand
106117
end
107118

108119
--[[
109120
% calc_gunzip_command
110121
111-
Returns the platform-dependent command to gunzip a file. It can be passed
122+
Returns the platform-dependent command to gunzip a file to `stdout`. It can be passed
112123
to `luaosutils.process.execute`, which will then return the text directly.
113124
114-
115125
@ archive_path (string) platform-encoded path of source gzip archive.
116126
: (string) platform-encoded command string to execute.
117127
]]
118128
function ziputils.calc_gunzip_command(archive_path)
119129
if finenv.UI():IsOnMac() then
120130
return "gunzip -c " .. archive_path
121131
else
122-
return "7z e -so " .. archive_path
132+
local command = [[
133+
$fs = New-Object IO.Filestream('%s',([IO.FileMode]::Open),([IO.FileAccess]::Read),([IO.FileShare]::Read))
134+
$gz = New-Object IO.Compression.GzipStream($fs,[IO.Compression.CompressionMode]::Decompress)
135+
$sr = New-Object IO.StreamReader($gz)
136+
while (-not $sr.EndOfStream) { Write-Output $sr.ReadLine() }
137+
$sr.Close()
138+
]]
139+
command = string.format(command, archive_path)
140+
return string.format("powershell -c & { %s }", command)
123141
end
124142
end
125143

126144
--[[
127145
% calc_is_gzip
128146
129-
Detects if an input buffer is a gzip archive. Sometimes, Finale gzips the internal EnigmaXML document.
147+
Detects if an input buffer is a gzip archive.
130148
131149
@ buffer (string) binary data to check if it is a gzip archive
132150
: (boolean) true if the buffer is a gzip archive
@@ -183,6 +201,11 @@ function ziputils.extract_enigmaxml(filepath)
183201
error(filepath .. " is not a .musx file.", 2)
184202
end
185203

204+
-- Steps to extract:
205+
-- Unzip the `.musx` (which is `.zip` in disguise)
206+
-- Run the `score.dat` file through `crypt_enigmaxml_buffer` to get a gzip archive of the EnigmaXML file.
207+
-- Gunzip the extracted EnigmaXML gzip archive into a string and return it.
208+
186209
local text = require("luaosutils").text
187210
local process = require("luaosutils").process
188211

0 commit comments

Comments
 (0)