Skip to content

Instantly share code, notes, and snippets.

@santaklouse
Last active February 25, 2025 11:10
Show Gist options
  • Save santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef to your computer and use it in GitHub Desktop.
Save santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef to your computer and use it in GitHub Desktop.
unlimited CrossOver trial (MacOS)

Run it in console for permanent install :

bash -c "$(curl -fsSL https://gist.github.com/santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef/raw/install.sh?token=$(date +%s))"

After install script will fix crossover as well as expired bottles (Thanks to @djsmax).

#!/usr/bin/env bash
# checck if pidof exists
PIDOF="$(which pidof)"
# and if not - install it
(test "${PIDOF}" && test -f "${PIDOF}") || brew install pidof
# find app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || (echo 'unable to detect app path. exiting...' && exit)
PWD="${CO_PWD}"
cd "${PWD}"
PROC_NAME='CrossOver'
# get all pids of CrossOver
pids=(`pgrep "${PROC_NAME}"`, `pidof "${PROC_NAME}"`, `ps -Ac | grep -m1 "${PROC_NAME}" | awk '{print $1}'`)
pids=`echo ${pids[*]}|tr ',' ' '`
# kills CrossOver process if it is running
[ "${pids}" ] && kill -9 `echo "${pids}"` > /dev/null 2>&1
# wait until app finish
sleep 3
# make the current date RFC3339-encoded string representation in UTC time zone
DATETIME=`date -u -v -3H '+%Y-%m-%dT%TZ'`
# modify time in order to reset trial
plutil -replace FirstRunDate -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -replace SULastCheckTime -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
# show tooltip notification
/usr/bin/osascript -e "display notification \"trial fixed: date changed to ${DATETIME}\""
# reset all bottles
for file in ~/Library/Application\ Support/CrossOver/Bottles/*/.{eval,update-timestamp}; do rm -rf "${file}";done
# and after this execute original crossover
echo "${PWD}" > /tmp/co_log.log
"$($PWD/CrossOver.origin)" >> /tmp/co_log.log
#!/usr/bin/env bash
# find app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || (echo 'unable to detect app path. exiting...' && exit)
PWD="${CO_PWD}"
cd "${PWD}"
PROC_NAME='CrossOver'
# get all pids of CrossOver
pids=(`pgrep "${PROC_NAME}"`, `pidof "${PROC_NAME}"`, `ps -Ac | grep -m1 "${PROC_NAME}" | awk '{print $1}'`)
pids=`echo ${pids[*]}|tr ',' ' '`
# kills CrossOver process if it is running
[ "${pids}" ] && kill -9 `echo "${pids}"` > /dev/null 2>&1
TIMESTAMP=$(date +%s)
FIX_FILE_LINK="https://gist.github.com/santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef/raw/CrossOver.sh?token=${TIMESTAMP}"
if [ -f CrossOver.origin ]; then
echo 'already installed. update and exit.'
echo "$(curl -fsSL ${FIX_FILE_LINK})" > CrossOver
exit
fi;
test -f CrossOver.origin || mv CrossOver CrossOver.origin
echo "$(curl -fsSL ${FIX_FILE_LINK})" > CrossOver
chmod +x CrossOver
echo 'Done. Please open CrossOver '
#!/usr/bin/env bash
# find app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || (echo 'unable to detect app path. exiting...' && exit)
PWD="${CO_PWD}"
cd "${PWD}"
PROC_NAME='CrossOver'
# get all pids of CrossOver
pids=(`pgrep "${PROC_NAME}"`, `pidof "${PROC_NAME}"`, `ps -Ac | grep -m1 "${PROC_NAME}" | awk '{print $1}'`)
pids=`echo ${pids[*]}|tr ',' ' '`
# kills CrossOver process if it is running
[ "${pids}" ] && kill -9 `echo "${pids}"` > /dev/null 2>&1
if [ -f CrossOver.origin ]; then
echo 'original file found. Roll it back and exit.'
mv CrossOver.origin CrossOver
exit
fi;
echo 'original file not found.'
@handysome6
Copy link

Also, if you see warning about the expired bottle, you can delete the bottle and create new ones.

@vayron
Copy link

vayron commented Dec 23, 2024

Great. It still works

@SnowS5
Copy link

SnowS5 commented Dec 27, 2024

Hey guys, just discovered a new way for retry Crossover. Since this posted is not working for an already expired Crossover trial, I spend some time to do it.

  1. close down Crossover
  2. install Prefs Editor
  3. open ~/Library/Preferences/com.codeweavers.CrossOver.plist using Prefs Editor
  4. Delete all entries in the file using this tool.
  5. reopen corssover
  6. enjoy another 14-days trail!

PS. This might be useful for another implementation for unlimited trial

Thx bro

@quarties
Copy link

quarties commented Jan 5, 2025

Hey guys, just discovered a new way for retry Crossover. Since this posted is not working for an already expired Crossover trial, I spend some time to do it.

  1. close down Crossover
  2. install Prefs Editor
  3. open ~/Library/Preferences/com.codeweavers.CrossOver.plist using Prefs Editor
  4. Delete all entries in the file using this tool.
  5. reopen corssover
  6. enjoy another 14-days trail!

PS. This might be useful for another implementation for unlimited trial

I removed the FirstRunDate key only and it did the trick.

@quarties
Copy link

quarties commented Jan 5, 2025

Also, if you see warning about the expired bottle, you can delete the bottle and create new ones.

Actually, there is a simpler way. You can open C drive for given bottle, then go one directory up, where system.reg file is stored. Open it, and find cxoffice string there, then remove line that has this string and the next 4 lines.

image

@Nygosaki
Copy link

Nygosaki commented Jan 9, 2025

Can someone let me know if this script works on their devices as well?

@NanoG6
Copy link

NanoG6 commented Jan 18, 2025

Can someone let me know if this script works on their devices as well?

yep it works, thanks

@WavesGitGud
Copy link

Also, if you see warning about the expired bottle, you can delete the bottle and create new ones.

Actually, there is a simpler way. You can open C drive for given bottle, then go one directory up, where system.reg file is stored. Open it, and find cxoffice string there, then remove line that has this string and the next 4 lines.

image

This does not worked for me... Is there any update that im not aware of ?

@Nygosaki
Copy link

@WavesGitGud does this automated script work for you? https://github.com/Nygosaki/crossover-trial-renew

@WavesGitGud
Copy link

WavesGitGud commented Jan 24, 2025

@WavesGitGud does this automated script work for you? https://github.com/Nygosaki/crossover-trial-renew

@MacBook-Pro ~ % bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossover-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"```
bquote> 

terminal stucks at bquote and doesnt do anything after that. I think im doing something wrong but im not sure what im doing wrong...

edit: Im trying to figure something pressed command+d

[bquote> bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossov] er-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"*'• /Users/ /Library/Preferences/com.codeweavers.CrossOver.plist: Could not modify plist, error: No value to remove at key path FirstRunDate /Users/ /Library/Preferences/com. codeweavers.CrossOver.plist: Could not modify plist, error: No value to remove at key path FirstRunVersion ®MacBook-Pro ~

this happened.

edit 2:

bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossover-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"```
when i Delete last ``` and run the code, it actually runs and does something without error. But still it doest not renew expired bottles.

@quarties
Copy link

This does not worked for me... Is there any update that im not aware of ?

@WavesGitGud it should work, but sometimes CrossOver ovewrites it and puts it back. My way is to spam save button in text edit + try a few times. Always works after some time.

The script you tried will only extend CrossOver trial, but not expired bottles,

@Nygosaki
Copy link

This does not worked for me... Is there any update that im not aware of ?

@WavesGitGud it should work, but sometimes CrossOver ovewrites it and puts it back. My way is to spam save button in text edit + try a few times. Always works after some time.

The script you tried will only extend CrossOver trial, but not expired bottles,

the script I linked should extend bottles as well

@Nygosaki
Copy link

@WavesGitGud does this automated script work for you? https://github.com/Nygosaki/crossover-trial-renew

@MacBook-Pro ~ % bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossover-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"```
bquote> 

terminal stucks at bquote and doesnt do anything after that. I think im doing something wrong but im not sure what im doing wrong...

edit: Im trying to figure something pressed command+d

[bquote> bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossov] er-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"*'• /Users/ /Library/Preferences/com.codeweavers.CrossOver.plist: Could not modify plist, error: No value to remove at key path FirstRunDate /Users/ /Library/Preferences/com. codeweavers.CrossOver.plist: Could not modify plist, error: No value to remove at key path FirstRunVersion ®MacBook-Pro ~

this happened.

edit 2:

bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossover-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"``` when i Delete last ``` and run the code, it actually runs and does something without error. But still it doest not renew expired bottles.

did it show you a "Crossover Trial Updated" popup?

@WavesGitGud
Copy link

This does not worked for me... Is there any update that im not aware of ?

@WavesGitGud it should work, but sometimes CrossOver ovewrites it and puts it back. My way is to spam save button in text edit + try a few times. Always works after some time.

The script you tried will only extend CrossOver trial, but not expired bottles,

I couldnt belive but spamming save solved the problem. Thanks a lot 🙏🏻

@quarties
Copy link

@Nygosaki oh, I didn't notice, but you are right. I'll test it next time.

@WavesGitGud
Copy link

WavesGitGud commented Jan 24, 2025

@WavesGitGud does this automated script work for you? https://github.com/Nygosaki/crossover-trial-renew

@MacBook-Pro ~ % bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossover-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"```
bquote> 

terminal stucks at bquote and doesnt do anything after that. I think im doing something wrong but im not sure what im doing wrong...
edit: Im trying to figure something pressed command+d
[bquote> bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossov] er-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"*'• /Users/ /Library/Preferences/com.codeweavers.CrossOver.plist: Could not modify plist, error: No value to remove at key path FirstRunDate /Users/ /Library/Preferences/com. codeweavers.CrossOver.plist: Could not modify plist, error: No value to remove at key path FirstRunVersion ®MacBook-Pro ~
this happened.
edit 2:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Nygosaki/crossover-trial-renew/refs/heads/main/resertCrossoverTrial.sh)"``` when i Delete last ``` and run the code, it actually runs and does something without error. But still it doest not renew expired bottles.

did it show you a "Crossover Trial Updated" popup?

On top right corner? It did. But didnt restored the bottles. I manually deleted codeweavers section and spamed save. Solved the problem.

edit: confused left with right thanks to dyxlesia. Change to the right one :)

@boozybatsMain
Copy link

For ones who can't start script - fixed version:

#!/usr/bin/env bash

# Exit immediately if a command exits with a non-zero status
set -e

# Ensure pidof is installed; install via Homebrew if not present
if ! command -v pidof &>/dev/null; then
    echo "pidof not found. Installing pidof via Homebrew..."
    brew install pidof
fi

# Define the path to CrossOver
CROSSOVER_PATH="/Applications/CrossOver.app/Contents/MacOS"

# Define the process name
PROC_NAME="CrossOver"

# Get all PIDs of CrossOver using various methods
pids=($(pgrep "$PROC_NAME") $(pidof "$PROC_NAME") $(ps -Ac | grep -m1 "$PROC_NAME\$" | awk '{print $1}'))

# Remove any duplicate or empty entries
unique_pids=()
for pid in "${pids[@]}"; do
    if [[ -n "$pid" && ! " ${unique_pids[@]} " =~ " ${pid} " ]]; then
        unique_pids+=("$pid")
    fi
done

# Kill CrossOver processes if any are running
if [ ${#unique_pids[@]} -gt 0 ]; then
    echo "Killing CrossOver processes: ${unique_pids[@]}"
    kill -9 "${unique_pids[@]}" >/dev/null 2>&1
else
    echo "No CrossOver processes found."
fi

sleep 3

# Get the current UTC time in the required format
TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Modify time to reset trial
echo "Resetting FirstRunDate in plist to $TIME"
plutil -replace FirstRunDate -date "$TIME" ~/Library/Preferences/com.codeweavers.CrossOver.plist

# Reset all bottles by removing specific files
echo "Resetting all bottles..."
find ~/Library/Application\ Support/CrossOver/Bottles/ -type f \( -name ".eval" -o -name ".update-timestamp" \) -exec rm -f {} +

echo "Reset completed successfully."

@G4RR3TT-1
Copy link

thank u @WavesGitGud this works perfectly!!
(ventura 13.6.9 + crossover 24.0.5)

@Nygosaki
Copy link

Nygosaki commented Jan 27, 2025

@WavesGitGud does this automated script work for you? https://github.com/Nygosaki/crossover-trial-renew

the script should now be updated. It should both reset the crossover and bottle trials

@WavesGitGud
Copy link

@WavesGitGud does this automated script work for you? https://github.com/Nygosaki/crossover-trial-renew

the script should now be updated. It should both reset the crossover and bottle trials

image It said bottle successful but I dont know where to check if my bottle resetted or not ?

@Nygosaki
Copy link

@WavesGitGud If there isn't a record containing cxoffice in ~/Library/Application\ Support/CrossOver/Bottles/*/system.reg it should be fine.
You can just wait 14 days until the trial is over again and try it then as well :>

@bambam67max
Copy link

I fixed the one-liner code, it just needs a new timestamp to work,

bash -c "$(curl -fsSL "https://gist.github.com/santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef/raw/install.sh?token=$(date +%s)")"

@carlos-lugo
Copy link

The command "pidof" isn't available for mac, also not on brew.
I updated the script to use macos compatible version of "pidof"

create a file named CrossOver.sh, then add this code:

#!/usr/bin/env bash

# Log start of script
echo "Starting CrossOver trial extension script..."

# Find CrossOver app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS

# Validate CrossOver installation
if [ ! -d "${CO_PWD}" ]; then
  echo "❌ Error: Unable to detect CrossOver installation path. Exiting..."
  exit 1
fi

echo "✅ CrossOver found at: ${CO_PWD}"
cd "${CO_PWD}" || exit

# Define process name
PROC_NAME='CrossOver'

# Get all PIDs of CrossOver (macOS-compatible)
echo "🔍 Finding running CrossOver processes..."
pids=$(pgrep -f "${PROC_NAME}")
if [ -n "${pids}" ]; then
  echo "✅ Found CrossOver processes with PIDs: ${pids}"
else
  echo "⚠️ No running CrossOver processes found."
fi

# Kill CrossOver processes if running
if [ -n "${pids}" ]; then
  echo "🛑 Killing CrossOver processes..."
  kill -9 ${pids} > /dev/null 2>&1
  sleep 3 # Wait for processes to terminate
  echo "✅ CrossOver processes killed."
fi

# Generate RFC3339-encoded datetime string (3 hours in the past)
echo "🕒 Modifying trial timestamps..."
DATETIME=$(date -u -v -3H '+%Y-%m-%dT%TZ')
echo "✅ New trial date set to: ${DATETIME}"

# Modify trial timestamps in CrossOver preferences
plutil -replace FirstRunDate -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -replace SULastCheckTime -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
echo "✅ Updated trial timestamps in preferences."

# Show macOS notification
echo "📢 Displaying success notification..."
/usr/bin/osascript -e "display notification \"trial fixed: date changed to ${DATETIME}\""

# Reset all bottles
echo "🧹 Resetting CrossOver bottles..."
for file in ~/Library/Application\ Support/CrossOver/Bottles/*/.{eval,update-timestamp}; do
  if [ -f "${file}" ] || [ -d "${file}" ]; then
    rm -rf "${file}"
    echo "✅ Removed: ${file}"
  fi
done

# Restart CrossOver using the original executable
echo "🚀 Restarting CrossOver..."
"${PWD}/CrossOver.origin" >> /tmp/co_log.log 2>&1
echo "✅ CrossOver restarted. Logs written to /tmp/co_log.log."

# Final success message
echo "🎉 Script completed successfully! CrossOver trial extended."

Make it executable:

chmod +x CrossOver.sh

Run the script:

./CrossOver.sh

@Nygosaki
Copy link

Nygosaki commented Feb 2, 2025

@carlos-lugo appreciate the contribution, however this seems to be a local issue on your end as pidof is very clearly supported by all macs and present in brew's repositories.
Alt Text
I would also recommend reading the thread on here to see specifics of how crossover's license checks work instead of relying on AI, as your solution is flawed in many ways.
However I do acknowledge that installing an additional library, especially if there is a native alternative and the library is depreciated, is sub-optimal. I'll update the main script to not use pidof.

@Nygosaki
Copy link

Nygosaki commented Feb 2, 2025

@cfanyyx
Copy link

cfanyyx commented Feb 6, 2025

Also, if you see warning about the expired bottle, you can delete the bottle and create new ones.

Actually, there is a simpler way. You can open C drive for given bottle, then go one directory up, where system.reg file is stored. Open it, and find cxoffice string there, then remove line that has this string and the next 4 lines.

image

👍

@brettalton
Copy link

The command "pidof" isn't available for mac, also not on brew. I updated the script to use macos compatible version of "pidof"

create a file named CrossOver.sh, then add this code:

#!/usr/bin/env bash

# Log start of script
echo "Starting CrossOver trial extension script..."

# Find CrossOver app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS

# Validate CrossOver installation
if [ ! -d "${CO_PWD}" ]; then
  echo "❌ Error: Unable to detect CrossOver installation path. Exiting..."
  exit 1
fi

echo "✅ CrossOver found at: ${CO_PWD}"
cd "${CO_PWD}" || exit

# Define process name
PROC_NAME='CrossOver'

# Get all PIDs of CrossOver (macOS-compatible)
echo "🔍 Finding running CrossOver processes..."
pids=$(pgrep -f "${PROC_NAME}")
if [ -n "${pids}" ]; then
  echo "✅ Found CrossOver processes with PIDs: ${pids}"
else
  echo "⚠️ No running CrossOver processes found."
fi

# Kill CrossOver processes if running
if [ -n "${pids}" ]; then
  echo "🛑 Killing CrossOver processes..."
  kill -9 ${pids} > /dev/null 2>&1
  sleep 3 # Wait for processes to terminate
  echo "✅ CrossOver processes killed."
fi

# Generate RFC3339-encoded datetime string (3 hours in the past)
echo "🕒 Modifying trial timestamps..."
DATETIME=$(date -u -v -3H '+%Y-%m-%dT%TZ')
echo "✅ New trial date set to: ${DATETIME}"

# Modify trial timestamps in CrossOver preferences
plutil -replace FirstRunDate -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -replace SULastCheckTime -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
echo "✅ Updated trial timestamps in preferences."

# Show macOS notification
echo "📢 Displaying success notification..."
/usr/bin/osascript -e "display notification \"trial fixed: date changed to ${DATETIME}\""

# Reset all bottles
echo "🧹 Resetting CrossOver bottles..."
for file in ~/Library/Application\ Support/CrossOver/Bottles/*/.{eval,update-timestamp}; do
  if [ -f "${file}" ] || [ -d "${file}" ]; then
    rm -rf "${file}"
    echo "✅ Removed: ${file}"
  fi
done

# Restart CrossOver using the original executable
echo "🚀 Restarting CrossOver..."
"${PWD}/CrossOver.origin" >> /tmp/co_log.log 2>&1
echo "✅ CrossOver restarted. Logs written to /tmp/co_log.log."

# Final success message
echo "🎉 Script completed successfully! CrossOver trial extended."

Make it executable:

chmod +x CrossOver.sh

Run the script:

./CrossOver.sh

This looks like straight ChatGPT/LLM/chat bot code. Why would you put emojis/emoticons in a script?

repo updated

This code runs a loop that kills some pids but never exits successfully. After killing manually, it doesn't fix the issue.

@carlos-lugo
Copy link

I would also recommend reading the thread on here to see specifics of how crossover's license checks work instead of relying on AI, as your solution is flawed in many ways.

This looks like straight ChatGPT/LLM/chat bot code. Why would you put emojis/emoticons in a script?

Actually, yes, it's straight code from a chatbot. I didn't have much time to understand the specifics of how Crossover's license checks work (sorry about that), and the script was failing without any error message. I instructed the chatbot to add debug messages, and for some unknown reason, the brew install pidof command was failing. The chatbot suggested using the MacBook's native command, and I agreed. After that, the script was working fine.

By the way, the emojis appear in the debug messages in the terminal when running the script. I didn’t ask the chatbot for emojis, but it’s actually quite cool.

@xyanid2015
Copy link

repo updated

I have 2 bottles, Diablo IV and POE2. However, only Diablo IV bottle was resetted, and POE2 not.

@2011eric
Copy link

I'm using version 2.0.7. It turns out that I have to convert the binary plist to XML and then convert it back to make the script work.

# modify time in order to reset trial
plutil -convert xml1  ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -replace FirstRunDate -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -replace SULastCheckTime -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -convert binary1  ~/Library/Preferences/com.codeweavers.CrossOver.plist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment