Unpacking Software Livestream

Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!

Learn More

Chocolatey Product Spotlight

Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You'll have a chance to have your questions answered in a live Ask Me Anything format.

Learn More

Chocolatey Coding Livestream

Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don't miss this opportunity to engage with our team and contribute to the future of Chocolatey!

Learn More

Calling All Chocolatiers! Whipping Up Windows Automation with Chocolatey Central Management

Webinar from
Wednesday, 17 January 2024

We are delighted to announce the release of Chocolatey Central Management v0.12.0, featuring seamless Deployment Plan creation, time-saving duplications, insightful Group Details, an upgraded Dashboard, bug fixes, user interface polishing, and refined documentation. As an added bonus we'll have members of our Solutions Engineering team on-hand to dive into some interesting ways you can leverage the new features available!

Watch On-Demand
Chocolatey Community Coffee Break

Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.

Watch The Replays
Chocolatey and Intune Overview

Webinar Replay from
Wednesday, 30 March 2022

At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!

Watch On-Demand
Chocolatey For Business. In Azure. In One Click.

Livestream from
Thursday, 9 June 2022

Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.

Watch On-Demand
The Future of Chocolatey CLI

Livestream from
Thursday, 04 August 2022

Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We'll talk about some cool new features, long term asks from Customers and Community and how you can get involved!

Watch On-Demand
Hacktoberfest Tuesdays 2022

Livestreams from
October 2022

For Hacktoberfest, Chocolatey ran a livestream every Tuesday! Re-watch Cory, James, Gary, and Rain as they share knowledge on how to contribute to open-source projects such as Chocolatey CLI.

Watch On-Demand

flips (Portable)

  • 1
  • 2
  • 3

183.0.0 | Updated: 11 Sep 2024

Downloads:

101

Downloads of v 183.0.0:

53

Maintainer(s):

Software Author(s):

  • Alcaro

flips (Portable) 183.0.0

Legal Disclaimer: Neither this package nor Chocolatey Software, Inc. are affiliated with or endorsed by Alcaro. The inclusion of Alcaro trademark(s), if any, upon this webpage is solely to identify Alcaro goods or services and not for commercial purposes.

  • 1
  • 2
  • 3

All Checks are Passing

3 Passing Tests


Validation Testing Passed


Verification Testing Passed

Details

Scan Testing Successful:

No detections found in any package files

Details
Learn More

Deployment Method: Individual Install, Upgrade, & Uninstall

To install flips (Portable), run the following command from the command line or from PowerShell:

>

To upgrade flips (Portable), run the following command from the command line or from PowerShell:

>

To uninstall flips (Portable), run the following command from the command line or from PowerShell:

>

Deployment Method:

NOTE

This applies to both open source and commercial editions of Chocolatey.

1. Enter Your Internal Repository Url

(this should look similar to https://community.chocolatey.org/api/v2/)


2. Setup Your Environment

1. Ensure you are set for organizational deployment

Please see the organizational deployment guide

2. Get the package into your environment

  • Open Source or Commercial:
    • Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://community.chocolatey.org/api/v2/. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
    • You can also just download the package and push it to a repository Download

3. Copy Your Script

choco upgrade flips -y --source="'INTERNAL REPO URL'" [other options]

See options you can pass to upgrade.

See best practices for scripting.

Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.

If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:


choco upgrade flips -y --source="'INTERNAL REPO URL'" 
$exitCode = $LASTEXITCODE

Write-Verbose "Exit code was $exitCode"
$validExitCodes = @(0, 1605, 1614, 1641, 3010)
if ($validExitCodes -contains $exitCode) {
  Exit 0
}

Exit $exitCode

- name: Install flips
  win_chocolatey:
    name: flips
    version: '183.0.0'
    source: INTERNAL REPO URL
    state: present

See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.


chocolatey_package 'flips' do
  action    :install
  source   'INTERNAL REPO URL'
  version  '183.0.0'
end

See docs at https://docs.chef.io/resource_chocolatey_package.html.


cChocoPackageInstaller flips
{
    Name     = "flips"
    Version  = "183.0.0"
    Source   = "INTERNAL REPO URL"
}

Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.


package { 'flips':
  ensure   => '183.0.0',
  provider => 'chocolatey',
  source   => 'INTERNAL REPO URL',
}

Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.


4. If applicable - Chocolatey configuration/installation

See infrastructure management matrix for Chocolatey configuration elements and examples.

Package Approved

This package was approved by moderator gep13 on 21 Sep 2024.

Description

Floating IPS (Flips) is a fully featured GUI program for applying IPS and BPS patches.

IPS and BPS patches are common ways to distribute rom hacks.


tools\chocolateybeforemodify.ps1
Remove-Process "flips"
tools\chocolateyinstall.ps1
$ErrorActionPreference = 'Stop' # stop on all errors
$toolsDir = "$(Split-Path -Parent $MyInvocation.MyCommand.Definition)"
$zipArchive = Join-Path $toolsDir -ChildPath 'flips-windows.zip'
$unzipDir = Join-Path $toolsDir -ChildPath 'flips-windows'
$executableDir = Join-Path $unzipDir -ChildPath 'builds\windows-x64-gui.zip'
$exe = "flips.exe"
$executable = Join-Path $executableDir -ChildPath $exe

$unzipArgs = @{
  FileFullPath = $zipArchive
  Destination  = $unzipDir
}

## Unzips file to the specified location - auto overwrites existing content
Get-ChocolateyUnzip @unzipArgs

# Add friendly app name (default is 'flips.exe')
# for current user only, because... I don't know, then I won't have to rewrite a function in removeregistrykeys.ps1 and make it more complicated.
$friendlyAppName = "Floating IPS"
$keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache"
$valueName = Join-Path $executableDir -ChildPath "$exe.FriendlyAppName"
$valueData = $friendlyAppName
$pathOk = [bool](Test-Path -Path $keyPath) # key exists
$valueOk = [bool](Get-ItemProperty -Path $keyPath -Name $valueName -ea 0) # value exists
if ($pathOk) {
  if ($valueOk) {
    Set-ItemProperty -Path $keyPath -Name $valueName -Value $valueData -Type STRING
  } else {
    New-ItemProperty -Path $keyPath -Name $valueName -Value $valueData -Type STRING
  }
}

## Add desktop shortcut
Install-ChocolateyShortcut -shortcutFilePath "$env:UserProfile\Desktop\Floating IPS.lnk" -targetPath $executable -workingDirectory $executableDir -description "Apply IPS and BPS patches."

## Add start menu shortcut
Install-ChocolateyShortcut -ShortcutFilePath "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Floating IPS.lnk" -targetPath $executable -WorkingDirectory $executableDir -description "Apply IPS and BPS patches."
tools\chocolateyuninstall.ps1
$ErrorActionPreference = 'Stop' # stop on all errors
$toolsDir = "$(Split-Path -Parent $MyInvocation.MyCommand.Definition)"
# $toolsDir = "C:\ProgramData\chocolatey\lib\flips\tools"
# $zipArchive = Join-Path $toolsDir -ChildPath 'flips-windows.zip'
$unzipDir = Join-Path $toolsDir -ChildPath 'flips-windows'
$executableDir = Join-Path $unzipDir -ChildPath 'builds\windows-x64-gui.zip'
$removeRegistryKeys = Join-Path $toolsDir -ChildPath 'removeregistrykeys.ps1'

# Check if running in administrative shell
function Test-Administrator {  
    [OutputType([bool])]
    param()
    process {
        [Security.Principal.WindowsPrincipal]$user = [Security.Principal.WindowsIdentity]::GetCurrent();
        return $user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
    }
}

# Until the following feature is implemented, I prefer to remove process in both chocolateyuninstall and chocolateybeforemodify:
# https://github.com/chocolatey/choco/issues/1731
Remove-Process "flips"

Uninstall-ChocolateyZipPackage -Packagename $env:ChocolateyPackageName -ZipFileName '$zipArchive' # Only necessary if you did not unpack to package directory - see https://docs.chocolatey.org/en-us/create/functions/uninstall-chocolateyzippackage

# Uninstall-ChocolateyZipPackage will remove the FILES from the archive.
# This removes the DIRECTORY they were extracted too.
Remove-Item $unzipDir -Recurse -Force

# Remove desktop shortcut if it exists (it's plausible the user might have removed it)
$exists = [bool](Test-Path -Path "$env:UserProfile\Desktop\Floating IPS.lnk")
if ($exists) {
    Remove-Item "$env:UserProfile\Desktop\Floating IPS.lnk"
}

# Check if start menu shortcut exists (it's plausible the user might have removed it)
$exists = [bool](Test-Path -Path "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Floating IPS.lnk")
# If administrative shell
if (Test-Administrator) {
    # Remove start menu shortcut if it exists
    if ($exists) {
        Remove-Item "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Floating IPS.lnk"
    }
} else {
    # Untested in real non-admin Choco scenario
    if ($exists) {
        Write-Warning "You are not running from an elevated shell. Start menu shortcut will not be removed.";
    }
}

# Remove registry keys (mostly file associations)
& $removeRegistryKeys $executableDir
tools\COPYING.gpl3
 
tools\flips-windows.zip
md5: 430B1D3E17A1D341A7116BA0CD1833A3 | sha1: F74A13319076F36DC2ED86C78F6C2A0E735D2638 | sha256: 28FC420904C6DD084B91A732AA55720904C4F561B18857FCDFF534C90DF5B8C9 | sha512: 559F50C10921ACBA5BFF03F80D9BA30F069E987D65D9E1D6F1D2F1A9F3FBF9C39B53E585F384AC2860DF3FF7FD2812FE32AA9F4F9B5E544BC792F470E86F08DB
tools\flips-windows\builds\windows-x64-gui.zip\flips.exe.gui
 
tools\LICENSE.txt
From: <https://github.com/Alcaro/Flips/blob/master/COPYING>

LICENSE

Floating IPS is licensed under GNU General Public License, version 3.0 or higher. The full legal
  text can be found in COPYING.gpl3; a rough interpretation (for non-lawyers only) follows:

- You must credit the author. Don't claim it as your own. You may modify it and take credit for your
  modifications, but the author (Alcaro) must be credited for the original software.
- If you modify this software, it must clearly be labeled as a modification.
- Any applications containing any part of this software must provide the full source code needed to
  modify and rebuild this application, under the same license. (This COPYING file is not part of the
  license; you may, if you wish, remove it and keep only the GPL.)
- The author claims no copyright or other rights over input, output, or error messages generated by
  this tool. Use it however you want.
  
tools\removeregistrykeys.ps1
param ($executableDir)
$ErrorActionPreference = 'Stop' # stop on all errors

function Remove-RegistryValueByValueData($keyPath, $targetValueData) {
    # IMPROVE Can this be done better with Select-Object?
    $key = Get-Item -Path $keyPath
    $keyValues = $key.Property # easier to understand (for me at least)
    $found = $false
    foreach ($value in $keyValues) {
        $data = Get-ItemPropertyValue -Path $keyPath -Name $value # Get the data of the value

        if ($data -eq $targetValueData) {
            # Check if the data matches $targetValueData

            # Remove the value
            try {
                Remove-ItemProperty -Path $keyPath -Name $value # PowerShell bug causes error if name is '(default)' 
                Write-VerboseRemovedValueData $keyPath $value $targetValueData
                $found = $true
                return # In this script, we don't expect multiple values with the same data, so we can return as soon as we find the data. 
            } catch {
                if ($_.Exception.Message -match 'Property \(default\) does not exist at path*') {
                    $(Get-Item -Path $keyPath).OpenSubKey('', $true).DeleteValue('') # "(default)" actually just means empty string (Remove-ItemProperty does not accept empty string).
                    Write-VerboseRemovedValueData $keyPath $value $targetValueData
                    $found = $true
                    return # In this script, we don't expect multiple values with the same data, so we can return as soon as we find the data. 
                } else {
                    Write-Error "An ItemNotFoundException occurred: $_"
                }
            }
        }
    }
    if (-Not ($found)) {
        Write-VerboseValueDataNotFound $keyPath $targetValueData
    }
}

# path
function Test-PathBool($p) {
    return [bool](Test-Path -Path $p)
}

# path, value
function Test-ValueNameBool($p, $n) {
    return [bool](Get-ItemProperty -Path $p -Name $n -ea 0)
}

function Get-ValueData($p, $n) {
    return Get-ItemPropertyValue -Path $p -Name $n
}

function Test-ValueDataBool($p, $n, $d) {
    $vD = Get-ValueData $p $n
    return ($vD -eq $d)
}

# path, extra
Function Write-VerboseRemovedKey($p, $e) {
    Write-Verbose "REMOVED: key '$p'.$e".Replace("REGISTRY::", "")
}

#path, value name, extension, extra
Function Write-VerboseRemovedValueName($p, $n, $e) {
    $msg = "REMOVED: value '$n' in key '$p'.$e".Replace("REGISTRY::", "")
    Write-Verbose $msg
}

Function Write-VerboseRemovedValueData($p, $n, $d) {
    Write-Verbose "REMOVED: value '$n' with data '$d' in key '$p'.".Replace("REGISTRY::", "")
}

Function Write-VerboseKeyNotFound($p, $e) {
    $msg = "NOT FOUND: key '$p'.$e".Replace("REGISTRY::", "")
    Write-Verbose $msg
}

Function Write-VerboseValueNameNotFound($p, $n, $e) {
    $msg = "NOT FOUND: value '$n' in key '$p'.$e".Replace("REGISTRY::", "")
    Write-Verbose $msg
}
Function Write-VerboseValueDataNotFound($p, $d, $e) {
    $msg = "NOT FOUND: value with data '$d' in key '$p'.$e".Replace("REGISTRY::", "")
}

# For when you looked for a value with a specifc name and specific data. Unused.
Function Write-VerboseValueNameDataNotFound($p, $d, $e) {
    $msg = "NOT FOUND: value with data '$d' in key '$p'.$e".Replace("REGISTRY::", "")
    Write-Verbose $msg
}


function Get-ValueCount($p) {
    return $(Get-Item -Path $p).Property.Count
}
function Get-SubkeyCount($p) {
    return $(Get-ChildItem -Path $p).Name.Count
}

function Write-VerboseNoFileHandlersRemaining($p) {
    Write-Verbose "No file handlers remaining in '$p'. Will attempt to remove empty key.".Replace("REGISTRY::", "")
}
function Write-VerboseFileHandlersStillRemaining($p) {
    Write-Verbose "File handlers remaining in key '$p'. Will NOT remove the key.".Replace("REGISTRY::", "")
}

function Test-PathPermission ($p) {
    # The UserChoice key usually has weird permissions, which will likely
    # prevent us from removing it, which is okay.
    # The original idea was to just try Remove-Item, but Remove-Item gives
    # misleading error message, "subkey does not exist"
    # (this seems like a bug in PowerShell.) New-ItemProperty gives
    # a correct message.
    # Test permission
    try {
        New-ItemProperty -Path $p -Name "PermissionTestRemoveMe" -Value "" -PropertyType String -Force | Out-Null
        Remove-ItemProperty -Path $p -Name "PermissionTestRemoveMe"
        return $true # Permission was granted!
    } catch {
        if ($_.Exception.Message -match "Requested registry access is not allowed.") {
            return $false
        } else {
            Write-Warning "Unexpected error occurred: $_"
        }
    }
}

# See if executable matches 
function Test-AutoFileProgram($executable) {
    $p = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\$executable" + "_auto_file\shell\open\command"
    $pathOk = Test-PathBool($keyPath)
    $match = $false # initialize variable
    if ($pathOk) {
        $targetDataTrailEnd = $executable + '" "%1"'
        $firstValue = $(Get-Item -Path $keyPath).Property[0] # there should only be one value though
        $data = $(Get-ItemPropertyValue -Path $keyPath -Name $firstValue)
        $match = $data.EndsWith($targetDataTrailEnd)
    } else {
        Write-VerboseKeyNotFound $p
    }
    return $match
}

function Remove-AAToast($n) {
    # file association values in `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts`
    $p = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts"
    $valueOk = Test-ValueNameBool $p $n
    if ($valueOk) {
        Remove-ItemProperty -Path $p -Name $n
        Write-VerboseRemovedValueName $p $n
    } else {
        Write-VerboseValueNameNotFound $p $n
    }
}

function Remove-FileAssocInClasses ($extension, $progId) {
    # Does not include the key in `HKEY_CURRENT_USER\Software\Classes\Applications`

    # IMPROVE Possibly a potiential improvement: Make a separate function to clean up empty keys, run it at the end of the end of the script, instead of cleaning as we go. However, cleaning up and check for subkeys was a practical way to check if handlers remaining.
    
    $extensionU = $extension.ToUpper()
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\.$extension"
    $pathOk = Test-PathBool($keyPath)
    if ($pathOk) {
        Remove-RegistryValueByValueData $keyPath $progId
        $valueCount = Get-ValueCount $keyPath
        $subKeyCount = Get-SubkeyCount $keyPath
        if (($valueCount -eq 0) -And ($subKeyCount -eq 0)) {
            Write-VerboseNoFileHandlersRemaining $keyPath
            Remove-Item -Path $keyPath -Force
            Write-VerboseRemovedKey $keyPath
        } else {
            Write-VerboseFileHandlersStillRemaining $keyPath
        }
    } else {
        Write-VerboseKeyNotFound $keyPath
    }

    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\$progId"
    $pathOk = Test-PathBool $keyPath
    if ($pathOk) {
        Remove-Item -Path $keyPath -Recurse -Force
        Write-VerboseRemovedKey $keyPath
    } else {
        Write-VerboseKeyNotFound $keyPath
    }
}

# Remove items in `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts`
function Remove-FileAssocInFileExts ($extension, $exe, $id) {
    $extensionU = $extension.ToUpper() # upper-case

    # Don't continue if this parent key doesn't exist
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$extension"
    $pathOk = Test-PathBool $keyPath # Test if path exists
    if (-not $pathOk) {
        Write-VerboseKeyNotFound $keyPath
        return
    }
    
    # This key holds programs on the "Open with" context menu and the order in which each application was most recently used.
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$extension\OpenWithList"
    $targetValueData = $exe
    $pathOk = Test-PathBool $keyPath # Test if path exists
    if ($pathOk) {
        Remove-RegistryValueByValueData $keyPath $targetValueData
        $valueCount = Get-ValueCount $keyPath
        $subkeyCount = Get-SubkeyCount $keyPath
        
        # le = "less than or equal to"; this key having subkeys would be an edge case
        if (($valueCount -le 1) -And ($subkeyCount -eq 0)) {
            # only values left: MRUList value, and plausibly the Default value (the latter is not counted by .Count)
            Write-VerboseNoFileHandlersRemaining $keyPath
            Remove-Item -Path $keyPath
            Write-VerboseRemovedKey $keyPath
        } else {
            $handlersRemaining = $true
            Write-VerboseFileHandlersStillRemaining $keyPath
        }
    } else {
        Write-VerboseKeyNotFound $keyPath
    }

    # This key also holds handlers.
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$extension\OpenWithProgids"
    $targetValueName = $id
    $pathOk = Test-PathBool $keyPath # Test if path exists
    $valueOk = Test-ValueNameBool $keyPath $targetValueName # Test value name exists
    if ($pathOk) {
        if ($valueOk) {
            Remove-ItemProperty -Path $keyPath -Name $targetValueName
            Write-VerboseRemovedValueName $keyPath $targetValueName
        } else {
            Write-VerboseValueNameNotFound $keyPath $targetValueName
        }
        $valueCount = Get-ValueCount $keyPath
        $subkeyCount = Get-SubkeyCount $keyPath
        
        # Again, the (Default) value isn't counted
        if (($valueCount -eq 0) -And ($subkeyCount -eq 0)) {
            Write-VerboseNoFileHandlersRemaining $keyPath
            Remove-Item -Path $keyPath
            Write-VerboseRemovedKey $keyPath
        } else {
            Write-VerboseFileHandlersStillRemaining $keyPath
        }
    } else {
        Write-VerboseKeyNotFound $keyPath
    }
}

function Remove-FileAssocInFileExtsFinal($extension, $id) {
    $extensionU = $extension.ToUpper() # upper-case
    # Don't continue if this parent key doesn't exist

    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$extension"
    $pathOk = Test-PathBool $keyPath # Test if path exists
    if (-not $pathOk) {
        Write-VerboseKeyNotFound $keyPath
        return
    }

    # This key holds says which program to always be used for .$ext. This may also be controlled with keys in Classes.
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$extension\UserChoice"
    $targetValueName = "ProgId"
    $targetValueData = $id
    $pathOk = Test-PathBool $keyPath # Test if path exists
    $permissionOk = $true # Initialize the variable
    if ($pathok) {
        $permissionOk = Test-PathPermission $keyPath
        $valueNameOk = Test-ValueNameBool $keyPath $targetValueName # Test value name exists
        if ($valueNameOk) {
            # $valueData = Get-ValueData
            $valueDataOk = Test-ValueDataBool $keyPath $targetValueName $targetValueData # Test if value data equals the target data
        } else {
            # Weird edge case; key exists but not the "ProgId" value
            Write-VerboseValueNameNotFound $keyPath $targetValueName
            $valueDataOk = $false # If the value didn't even exist, then we did not find the value data we were looking for
        }
        if ($valueDataOk) {
            Write-Verbose "The default handler for $extensionU is set to '$id' in $keyPath. Will attempt to remove the key.".Replace("REGISTRY::", "")
        } else {
            Write-Verbose "The default handler for $extensionU is NOT set to '$id' in $keyPath. Will NOT attempt to remove the key.".Replace("REGISTRY::", "")
        }
        if (($valueDataOk) -Or ($valueNameOk -eq $false)) { 
            # We don't need to remove the value, since this key only holds one handler.
            # Instead, we would rather just to delete the key (if it has the target data).
            # The value name is just the generic "ProgId", it would be
            # weird if this value name was gone but not the key, but
            # let's remove the key in that edge case.
            if ($permissionOk) {
                Remove-Item -Path $keyPath -Force
            } else {
                # If Test-PathPermission gives "Unexpected error occured", the below output may be incorrect.
                Write-Verbose "Lacking permission to remove key '$keyPath'. That is normal for this key. It prevents complete cleanup in registry, but it is not an issue as it makes no difference to user experience.".Replace("REGISTRY::", "")
            }
        }
    } else {
        Write-VerboseKeyNotFound $keyPath
    }

    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$ext"
    $pathOk = Test-PathBool $keyPath
    if ($pathOk) {
        $subkeyNamesRemaining = (Get-ChildItem -Path $keyPath).Name
        $subkeyCount = Get-SubkeyCount $keyPath
        $valueCount = Get-ValueCount $keyPath
        if (($valueCount -gt 0) -or (($subKeyCount -gt 1))) {
            Write-VerboseFileHandlersStillRemaining $keyPath
        } elseif (($subkeyCount -eq 0) -and ($valueCount -eq 0)) {
            # empty key
            Write-VerboseNoFileHandlersRemaining $keyPath
            Remove-Item -Path $keyPath -Recurse -Force
            Write-VerboseRemovedKey $keyPath
        } elseif ($permissionOk -eq $true) {
            # Re-using $pemissionOk value from UserChoice, no neet to test again.
            Write-VerboseNoFileHandlersRemaining $keyPath
            Remove-Item -Path $keyPath -Recurse -Force
            Write-VerboseRemovedKey $keyPath
        } else {
            Write-VerboseNoFileHandlersRemaining $keyPath # message is lying, the attempt has already been made
            # If Test-PathPermission gives "Unexpected error occured", the below output may be incorrect.
            Write-Verbose "Lacking permission to remove key '$keyPath'. That is normal for this key. It prevents complete cleanup, but it's not a real issue, as it does not affect user experience.".Replace("REGISTRY::", "")
        }
    } else {
        Write-VerboseKeyNotFound $keyPath
    }
}

function Remove-FileAssocSetByProgram($ext) {
    $extU = $ext.ToUpper() # upper-case
    
    Write-Verbose "Extension: $extU"

    $progId = "FloatingIPSFile$extU"
    Remove-FileAssocInClasses $ext $progId

    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts"
    $valueName = "Applications\flips.exe_.$ext"
    $targetValueName = "FloatingIPSFile$extU" + "_.$ext"
    Remove-AAToast $targetValueName # Only added if opened a file with the file type at least once
    
    $exe = "flips.exe"
    $id = "FloatingIPSFile$extU"
    Remove-FileAssocInFileExts $ext $exe $id # Only added if opened a file with the file type at least once

    # HACK Mystery: Why does the permission problem occur sometimes and sometimes not?
    # Answer: No. It's still HKCU.

    # The ProgId value here is added if file association is set up through program, then the user manually selects to use the program "Always" for the application.
    Remove-FileAssocInFileExtsFinal $ext $progId
}

function Remove-FileAssocSetByUser($ext) {
    $extU = $ext.ToUpper()
    Write-Verbose "Extension: $extU."
    $exe = "flips.exe"
    $fileExtsExtPath = "REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.$ext"

    # Added when you add a program to the "Select an app to open this .[ext] file" popup window
    # IMPROVE It isn't necesssary to try to remove this every time the function is run. See if you can find an elegant solution.
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\Applications\flips.exe"
    $pathOk = Test-PathBool $keyPath
    if ($pathOk) {
        Remove-Item -Path $keyPath -Recurse -Force
        Write-VerboseRemovedKey $keyPath
    } else {
        Write-VerboseKeyNotFound $keyPath
    }

    # Added when you select to use the program "Just once" or "Always" for the file type
    $targetValueName = "Applications\" + $exe + "_.$extU"
    Remove-AAToast $targetValueName

    # Added when you select to use the program "Just once" or "Always" for the file type
    $exe = $exe
    $id = "Applications\" + $exe + "_.$extU"
    Remove-FileAssocInFileExts $ext $exe $id

    # We determine if the [ext]_auto_file is set to our program, and if true, we remove [ext]_auto_file in Classes, FilExts, and AAToasts.
    $ext_auto_file = $ext + "_auto_file"
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\$ext_auto_file\shell\open\command"
    $autoFileMatch = $false # initialize variable
    $pathOk = Test-PathBool($keyPath)
    if ($pathok) {
        $autoFileMatch = Test-AutoFileProgram($exe) # true if matches the exe
    } else {
        Write-VerboseKeyNotFound $keyPath
        Write-Verbose "Will attempt to remove '$ext_auto_file' in other places if found.".Replace("REGISTRY::", "") # It serves no purpose if this key doesn't exist, so we might as well clean up mentions of it it we find any.
    }
    if ($pathok -And -Not $autoFileMatch) {
        Write-Verbose "The value data in $keyPath does NOT point to $exe. Will NOT attempt to remove $ext_auto_file.".Replace("REGISTRY::", "")
    } elseif ($pathOk -And $autoFileMatch) {
        Write-Verbose "The value data in $keyPath does point to $exe. Will attempt to remove $ext_auto_file.".Replace("REGISTRY::", "")
    }
    if ($autoFileMatch -Or (-Not $pathOk)) {
        # Added when you select to "Always" use the program for the file type
        $progId = $ext_auto_file
        Remove-FileAssocInClasses $ext $progId
        
        # Added when you select to "Always" use the program for the file type
        # (And maybe a file needs to opened as well. I don't know because I have
        # only tried setting this trough the "Open with" context menu, which opens the
        # file immediately afterwards.)
        $targetValueName = $ext + "_auto_file_." + $ext
        Remove-AAToast $targetValueName
        
        $exe = $exe
        $id = $ext_auto_file
        Remove-FileAssocInFileExts $ext $exe $id
        
        # We check if this path exists in order to avoid the same "NOT FOUND" verbose message being shown again (we ran this function recently).
        $pathOk = Test-PathBool $fileExtsExtPath # Test if path exists
        if ($pathOk) {
            # Added if [ext]_auto_file is manually modified, or perhaps if you set up file association in Windows XP and copied the key over to current Windows.
            $progId = $ext_auto_file
            Remove-FileAssocInFileExtsFinal $ext $progId
        }
    }

    # We check if this path exists in order to avoid the same "NOT FOUND" verbose message being shown again (we ran this function recently).
    $pathOk = Test-PathBool $fileExtsExtPath # Test if path exists
    if ($pathOk) {
        # We need to do this after removing keys and values for both `[ext]_auto_file` and `Applications\[executable].exe`. If we try to bake the code from Remove-FileAssocInFileExtsFinal into Remove-FileAssociInFileExts, there will be issues, (unless we do some convoluted or perhaps clever coding). It might say that there are other file handlers left (either of the ones mentioned) and that it won't attempt to remove.
        # For normal cases on modern Windows, we could solve this by just removing `Applications\[executable].exe` last. But, theoretically, you can set default program in `HKEY_CURRENT_USER\Software\Classes\[ext]_auto_file\shell\open\command`, then UserChoice will be set to [ext]_auto_file, and then, I think, we would need to remove [ext]_auto_file last.
        # Or we could bake it into Remove-FileAssociInFileExts and run it that whole function three times (e.g. first with `[ext]_auto_file`, then `Applications\[executable].exe`., then `[ext]_auto_file` again), which would account for both scenarios. Splitting it up seems most reasonable.
        $progId = "Applications\" + $exe
        Remove-FileAssocInFileExtsFinal $ext $progId
    }
    
}

function Remove-MuiCacheEntry($n) {
    # IMPROVE Either look just for the executable part of the string, or look for the value data. This way, it will work even if the program is installed in another location.
    Write-Verbose "Will attempt to remove MUI cache entry."
    $keyPath = "REGISTRY::HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache"
    $targetValueName = $n
    $valueNameOk = Test-ValueNameBool $keyPath $targetValueName
    if ($valueNameOk) {
        Remove-ItemProperty -Path $keyPath -Name $targetValueName
        Write-VerboseRemovedValueName $keyPath $targetValueName
    } else {
        Write-VerboseValueNameNotFound $keyPath $targetValueName
    }

}

Write-Verbose 'You may safetly ignore "NOT FOUND" verbose messages from this uninstallation script.'; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."

Write-Verbose "Will attempt to remove file associations that may have been added through the application." # There is an option in the settings to add file extensions.
Remove-FileAssocSetByProgram "bps"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByProgram "ips"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."

Write-Verbose "Will attempt to remove file associations that may have been manually added." # e.g. right-click and "Open with"
Remove-FileAssocSetByUser "bps"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "ips"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."

# File extensions that are often used with IPS and BPS patches.
Remove-FileAssocSetByUser "nes"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "sfc"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "smc"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "n64"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "z64"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "gb"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "gbc"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "gba"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "bin"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "md"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."
Remove-FileAssocSetByUser "gen"; Write-Verbose "..."; Write-Verbose "..."; Write-Verbose "..."

$exe = "flips.exe"
$targetValueName = Join-Path $executableDir -ChildPath "$exe.FriendlyAppName"
Remove-MuiCacheEntry $targetValueName
tools\VERIFICATION.txt
VERIFICATION
Verification is intended to assist the Chocolatey moderators and community
in verifying that this package's contents are trustworthy.

The zip archive has been downloaded from the official GitHub repository <https://github.com/Alcaro/Flips>
and can be verified like this:

1. Download flips-windows.zip from this page:
<https://github.com/Alcaro/Flips/releases/tag/v183>
2. You can use one of the following methods to obtain checksums:
  - Use powershell function 'Get-Filehash'
  - Use chocolatey utility 'checksum.exe'
  
  flips-windows.zip:
  checksum type: sha256
  checksum64: 28FC420904C6DD084B91A732AA55720904C4F561B18857FCDFF534C90DF5B8C9

3. Obtain the checksum of the zip archive you downloaded in step 1, and of the zip archive that came with this package (in the same folder as VERIFICATION.txt). If they have the same hash, you have successfully verified this package.
4. You can also have a look at the scripts, chocolateyinstall.ps1 and chocolateyuninstall.ps1. Open a file in a text editor or IDE and see if it looks clean. If you want to learn more about this, check out the Chocolatey docs on creating packages <https://docs.chocolatey.org/en-us/create/create-packages/>

The license in 'LICENSE.txt' is obtained from <https://github.com/Alcaro/Flips/blob/master/COPYING>, and 'COPYING.gpl3' is obtained from <https://github.com/Alcaro/Flips/blob/master/COPYING.gpl3>.

Log in or click on link to see number of positives.

In cases where actual malware is found, the packages are subject to removal. Software sometimes has false positives. Moderators do not necessarily validate the safety of the underlying software, only that a package retrieves software from the official distribution point and/or validate embedded software against official distribution point (where distribution rights allow redistribution).

Chocolatey Pro provides runtime protection from possible malware.

Add to Builder Version Downloads Last Updated Status
flips (Portable) 181.0.0 48 Wednesday, August 28, 2024 Approved
Discussion for the flips (Portable) Package

Ground Rules:

  • This discussion is only about flips (Portable) and the flips (Portable) package. If you have feedback for Chocolatey, please contact the Google Group.
  • This discussion will carry over multiple versions. If you have a comment about a particular version, please note that in your comments.
  • The maintainers of this Chocolatey Package will be notified about new comments that are posted to this Disqus thread, however, it is NOT a guarantee that you will get a response. If you do not hear back from the maintainers after posting a message below, please follow up by using the link on the left side of this page or follow this link to contact maintainers. If you still hear nothing back, please follow the package triage process.
  • Tell us what you love about the package or flips (Portable), or tell us what needs improvement.
  • Share your experiences with the package, or extra configuration or gotchas that you've found.
  • If you use a url, the comment will be flagged for moderation until you've been whitelisted. Disqus moderated comments are approved on a weekly schedule if not sooner. It could take between 1-5 days for your comment to show up.
comments powered by Disqus