+++
title = "Solidworks on Linux"
date = 2024-10-29
+++

{% note() %}
If you don't care about the context, you can just [skip to the guide](#instructions).
{% end %}

The title is somewhat disingenuous, it's less "SolidWorks on Linux" and more "SolidWorks in a Windows VM without Pissing Off The License Server" but that's not as good of a title.

# Context
- I need SolidWorks for school.
- I finally built a PC capable of running it.
- I use Linux (~~arch btw~~).

See the problem yet?
{% note() %}
I know it's supposed to be styled SOLIDWORKS, but that's both annoying to type and to look at, and [Wikipedia just calls it SolidWorks](https://en.wikipedia.org/wiki/SolidWorks).
I'm just going to go with that.
{% end %}

## Wine
My first thought was "well, will it just work with [Wine](https://winehq.org)?"

{{ image(src="/assets/solidworks/wine-installer.png", alt="SolidWorks installer under Wine", caption="So far so good") }}

No, [of course not](https://appdb.winehq.org/objectManager.php?sClass=application&iId=318).  
It's never that easy, is it.

{{ image(src="/assets/solidworks/wine-installer-broken.png", alt="Broken (blank) SolidWorks popup", caption="Should have seen that coming...") }}

There is [an existing script](https://github.com/cryinkfly/SOLIDWORKS-for-Linux) to get SolidWorks to run under [Wine](https://www.winehq.org/),
but even after dissecting it and trying various things with [winetricks](https://github.com/Winetricks/winetricks), I never got the installer
to work properly.

I got stuck at the following error:
```log
03e8:fixme:ieframe:navigate_url Unsupported args (Flags 1470F138 {VT_I4: 0}; TargetFrameName 1470F128 {VT_BSTR: (null)})
03e8:fixme:mshtml:load_gecko Gecko can only be used from one thread.
03e8:err:mshtml:create_document_object Failed to init Gecko, returning CLASS_E_CLASSNOTAVAILABLE
```

I'm not a Wine expert, I have no idea how to work around this (if it's even possible).  
At this point I was getting fairly frustrated and decided to spin up a VM instead.

## VM
Using [virt-manager](https://github.com/virt-manager/virt-manager) I set up a quick Windows 10 VM, but quickly hit a wall.

{{ image(src="/assets/solidworks/installer-license.png", alt="SolidWorks license error", caption="Great...") }}

I'm not paying for my own license. I only use SolidWorks for school projects, and therefore use my school's license, and,
well, I'm not exactly interested in spending [around $3000 per year](https://www.solidworks.com/how-to-buy/solidworks-plans-pricing)
just to do my homework (I know it's much cheaper for hobbyists, but still).

Additionally, I'm a little scared of trying to boot Windows on bare metal, and don't have a sacrificial drive for that.

I don't really want to try to find a way to crack it. I have no doubt people have done it, but I'm not interested, except as an absolute last resort.

Soo... I guess that means it's time to trick SolidWorks into thinking it *isn't* in a VM?

{% note() %}
It seems like SolidWorks [supports *some* VMs](https://www.solidworks.com/sw/support/11168_enu_html.htm), but not QEMU/KVM.
A friend of mine uses a Mac, and it Just Worked(tm) through [Parallels](https://www.parallels.com/), with the same license and everything.  
Figures.
{% end %}

(*Cue montage of spending too many hours of messing around and getting absolutely nowhere*)

Eventually though, I managed to get something to work, starting from [this reddit post](https://www.reddit.com/r/qemu_kvm/comments/dq2nki/how_to_completely_hide_virtualization_from_guest/),
this [proxmox forum post](https://forum.proxmox.com/threads/solidworks-license-server.58312/) and a bunch of other Random Clueless Googling.

I'm not sure if what I did is optimal, there might be better ways to get around the check.
However, it *does* work, and that's enough for my purposes.

# Instructions

{% important() %}
I have no idea whether bypassing the VM check violates some part of the terms of use.  
Do this at your own risk.
{% end %}

Start by starting up a new Windows VM (I used 10, but 11 should work too) using `virt-manager`.

Don't go through the Windows installer setup, and instead edit the machine details.

## Virtual SCSI Drives
Make sure the virtual storage is set to use `SCSI`, not `SATA`.
The XML should look something like this:
```xml
<disk type="file" device="disk">
  <driver name="qemu" type="qcow2" discard="unmap"/>
  <source file="/var/lib/libvirt/images/solidworks-vm.qcow2" index="2"/>
  <backingStore/>
  <target dev="sda" bus="scsi"/>
  <address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>
```
(The important part is `bus="scsi"`)

Also ensure the SCSI controller model is set to be `virtio-scsi` (it defaulted to `lsilogic` for me).
The XML should be something like:
```xml
<controller type="scsi" index="0" model="virtio-scsi">
    <address type="pci" domain="0x0000" bus="0x10" slot="0x01" function="0x0"/>
</controller>
```

Next you'll need the VirtIO SCSI guest drivers.
[This page](https://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers) links to
[here](https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md), which is where I found them.
Grab the ISO, and add it as a virtual CDROM.

{{ image(src="/assets/solidworks/add-driver-cdrom.png", alt="Adding the virtio driver iso as a CDROM", caption="") }}

Next, go to **Boot Options** and ensure the SCSI disk and the Windows installer are both selected.

{{ image(src="/assets/solidworks/boot-options.png", alt="Both devices selected in virt-manager's boot device order", caption="") }}

Now start the VM, and go through the normal Windows install process until it inevitably complains about not finding any drive to install on.

{{ image(src="/assets/solidworks/windows-no-drives.png", alt="Windows finds no drives to install on", caption="") }}

Select "Load driver," and select the appropriate driver for the architecture and Windows version.

{{ image(src="/assets/solidworks/windows-install-driver.png", alt="Installing the VirtIO SCSI controller driver", caption="") }}

Now the device should appear, and you can continue installing Windows as normal.

Once it tries to reboot, remove both virtual SATA CDROMs, and boot into the new installation to finish setup.

After that, the installer should just work! SolidWorks no longer thinks it's in a VM, and installs normally!

{{ image(src="/assets/solidworks/victory.png", alt="SolidWorks open in a Windows 10 VM", caption="Finally! It works!!!") }}

## Other Things

Interestingly, *Windows itself* still knows it's virtualized.

{{ image(src="/assets/solidworks/task-manager.png", alt="Task Manager showing that Windows is virtualized", caption="Virtual machine: Yes") }}

You can fix this by [disabling the "hypervisor" feature](https://forum.level1techs.com/t/hiding-hypervisor-from-vm-guest/132755).
```xml 
<cpu mode="host-passthrough" check="none" migratable="on">
    <feature policy="disable" name="hypervisor"/>
</cpu>
```
Doing so might have a significant performance impact, and since SolidWorks works fine without it, I wouldn't bother.

At one point while experimenting, I tried SMBIOS host mode, which made no difference to SolidWorks.
Apparently that used to be [all you had to do](https://www.reddit.com/r/qemu_kvm/comments/dq2nki/comment/faawvxt/) to get around the check.
```xml
<os>
    <type arch="x86_64" machine="pc-q35-9.1">hvm</type>
    <smbios mode="host"/>
</os>
```

# Conclusion
I have no idea why SolidWorks doesn't flag the VirtIO SCSI drivers.
The SATA controller just seems like a really weird way to check if you're in a VM.
Why does it *not* care about the hypervisor flag? You'd think that would be the easiest way to tell, but I guess not...?

I don't really know enough to say *why* this workaround works, all I know is that it *does*, and that's good enough for now.

It's just *annoying* that companies doing things like this is normalized.
It's not like I'm trying to distribute their software or deploy it in hundreds of VMs, I'm literally *just trying to do homework*.
It doesn't *have* to be like this. You shouldn't have to find cursed workarounds for checks like this, because *checks like this shouldn't exist in the first place*.
Who does it even benefit? Do they really sell that many more copies of SolidWorks by doing this?
Surely there's a better way to scrape more profit than *flagging VMs by their SATA devices?*

Maybe they do have a valid reason, but what it could possibly be is beyond me.

It's rare that I find something that's actually worth writing a post about.
Since I didn't see any guides on what to do (or, well, any guides that *worked*) I figured I might as well write this up.

Hopefully someone else finds it helpful, and if not, I know I will when I inevitably forget the steps.
