For windows you can use system API: shell32.dll.ShellExecuteW. It's running at another process, so even if your main program has terminated, it will continue to run. Therefore, you only need to call it to delete the program before the program exits. To ensure that the delete command is called after the program has terminated, you can wait for a period of time before deleting it (using start-sleep).
Example
Start-Sleep 2; del "C:\xxx.exe"
package main
import (
"fmt"
"log"
"os"
"syscall"
"unicode/utf16"
"unsafe"
)
func main() {
defer func() { // delete exe
shell32dll := syscall.NewLazyDLL("Shell32.dll")
shellExecuteWProc := shell32dll.NewProc("ShellExecuteW")
const deleteExeAfterNSec = 2
const swHide = 0
const swShow = 1
log.Println(os.Args[0]) // os.Args[0] is the path of the executable file itself
_, _, _ = syscall.SyscallN(shellExecuteWProc.Addr(),
uintptr(0), // hwnd
uintptr(unsafe.Pointer(&(utf16.Encode([]rune("runas" + "\x00")))[0])),
uintptr(unsafe.Pointer(&(utf16.Encode([]rune("powershell" + "\x00")))[0])),
uintptr(unsafe.Pointer(&(utf16.Encode([]rune(fmt.Sprintf("Start-Sleep %d;del %q;", deleteExeAfterNSec, os.Args[0]) + "\x00")))[0])),
uintptr(unsafe.Pointer(&(utf16.Encode([]rune("" + "\x00"))) [0])), // wkDir
uintptr(swHide), // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
)
log.Println("done")
}()
}
powershell
for multiple command use ;
to split
command1 ; command2 ; command3
Start-Sleep 3; del "C:\xxx.exe"