Several user questions are from people getting a message “CFileException 0” when trying to save a .skp file, and the file is not saved (instead a new file is created, with an extra number). I found out that this problem can be triggered by Ruby extensions that use “Process.spawn()”. This Ruby function causes some handles from the parent process (SketchUp) to be inherited by the child process. It has got an optional argument “close_others”, supposed to prevent that—and the default value should be true—but it doesn’t seem to work on Windows, at least in the version of Ruby within SketchUp 2018. If you don’t know what “inheriting handles” mean, in short, it means that whatever files are currently opened in SketchUp won’t be closed until the child process also closes them (or finishes running). That’s why, on Windows, SketchUp cannot overwrite the file it had opened.
As a workaround, the following (Windows-only) code creates a new process using directly the Windows API, passing it the correct flag “don’t inherit the handles” (it’s one of the zeroes).
require 'fiddle' require 'fiddle/types' require 'fiddle/import' module Kernel32 extend Fiddle::Importer dlload 'kernel32.dll' include Fiddle::Win32Types PROCESS_INFORMATION = struct [ "HANDLE hProcess", "HANDLE hThread", "DWORD dwProcessId", "DWORD dwThreadId" ] extern 'BOOL CreateProcessA(LPCSTR, PVOID, PVOID, PVOID, BOOL, DWORD, PVOID, PVOID, const char *, struct PROCESS_INFORMATION *)' extern 'BOOL CloseHandle(HANDLE)' end def launch_my_process(cmd) startinfo = ( * 18).pack('Q' * 18) procinfo = Kernel32::PROCESS_INFORMATION.malloc procinfo.hProcess = 0 procinfo.hThread = 0 procinfo.dwProcessId = 0 procinfo.dwThreadId = 0 result = Kernel32.CreateProcessA(cmd, nil, nil, nil, 0, 0, nil, nil, startinfo, procinfo) if result == 0 # failed! else Kernel32.CloseHandle(procinfo.hThread) Kernel32.CloseHandle(procinfo.hProcess) end end