Skip to content

Feature request: fallback to in-process extraction when cmdunzip.exe is blocked by OS policy #135

@scschwa

Description

@scschwa

On corporate Windows machines with AppLocker or Software Restriction Policies (SRP), zip::unzip_process() fails because the OS blocks execution of cmdunzip.exe:

! create process 'C:/Users/.../pak/library/zip/bin/x64/cmdunzip.exe'
  (system error 1260, This program is blocked by group policy.
  For more information, contact your system administrator.)
  @win/processx.c:1040 (processx_exec)

In my case, executables embedded inside R package libraries are flagged and blocked. As a user without admin rights, I cannot whitelist the path without Corprate IT intervention, which is often slow or unavailable and costly.

This was previously reported in (#49 2020) and closed. I'm reopening the discussion because:

  • Corporate security policies have become more restrictive since 2020, not less
  • The impact is severe for pak users — pak depends on zip::unzip_process() for all Windows binary package extraction, and there is no configuration to change this (I had tar available on my windows corporate pc but couldn't figure out a way to repoint)
  • A clean fallback exists within the zip package itself

Proposed solution

zip::unzip_process() could catch the process spawn failure and automatically fall back to zip::unzip() (the in-process C extraction via miniz). Alternatively, expose an option to let callers choose:

# Option A: automatic fallback on spawn failure
# In unzip_process$initialize(), wrap the processx::process$new() call
# in tryCatch. If it fails with a "blocked by group policy" or similar
# process creation error, fall back to zip::unzip() and return a
# pre-completed process object.

# Option B: explicit opt-in
zip::unzip_process(..., method = "internal")
# Uses zip::unzip() instead of spawning cmdunzip.exe

Trade-off acknowledged

unzip_process() exists for async/non-blocking extraction. The in-process unzip() is synchronous. For a fallback, this is an acceptable trade-off as a synchronous extraction that works reliably is better than async extraction that crashes and makes a user resort to slow install.package(".."). Callers like pak would lose some install-phase parallelism but retain download parallelism, which is where the majority of the speed benefit comes from.

Workaround

I confirmed a working patch that overrides pkgdepends:::make_install_process inside pak's subprocess to call zip::unzip() for .zip files and return a real (already-finished) processx::process object. This has been tested successfully installing 100+ packages on a locked-down corporate Windows machine. Details in the linked pak issue r-lib/pak#849, which has the work around in it.

Environment

  • Windows 11 Enterprise with AppLocker/SRP
  • R 4.4.x
  • pak 0.8.0+ (bundles zip in its private library)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions