1
package main

import "os"

func main() {
    err := os.Remove(os.Args[1])
    if err != nil {
        panic(err)
    }
}

Compile this

GOOS=windows GOARCH=386 go build test.go

Then run on wine

Z:\tmp>test.exe test.exe
fixme:process:SetProcessPriorityBoost (0xffffffff,1): stub
panic: remove test.exe: Access denied.

goroutine 1 [running]:
panic(0x462c40, 0x5b3f9ca0)
    /usr/local/go/src/runtime/panic.go:500 +0x331
main.main()
    /tmp/test.go:8 +0x70

Z:\tmp>fixme:console:CONSOLE_DefaultHandler Terminating process 8 on event 0

I think "ok, it's wine" and run in Win XP on VirtualBox. But that's error in Windows return.

//Sorry for my english.

2 Answers2

2

Using CreateProcess function, as can be written in Go by using syscall package:

package main

import (
    "fmt"
    "syscall"
    "os"
)

func main() {
    // write your code here 
    // <----
    fmt.Println("Blah Blah Blah")
    // ---->
    var sI syscall.StartupInfo
    var pI syscall.ProcessInformation
    argv := syscall.StringToUTF16Ptr(os.Getenv("windir")+"\\system32\\cmd.exe /C del "+os.Args[0])
    err := syscall.CreateProcess(
        nil,
        argv,
        nil,
        nil,
        true,
        0,
        nil,
        nil,
        &sI,
        &pI)
    if err != nil {
        fmt.Printf("Return: %d\n", err)
    }
}
0

Another method is exec.Command In addition to completing tasks, it is also very easy to hide the window. That is, you will not see the console flash on windowless.

cmd := exec.Command("powershell", "del", os.Args[0])
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
if err := cmd.Start(); err != nil {
    panic(err)
}

Example

Since we delete the executable files, you should ensure that all programs have been appropriately processed before deleting. I recommend that you use chan to communicate.

kill.go

package main
import ("io";"log";"os";"os/exec";"syscall")
var (
    chanQuit chan bool
    logger   *log.Logger
)
func init() {
    chanQuit = make(chan bool)
}
func ListenToDeleteApp(ch chan bool) {
    select {
    case killNow, _ := <-ch:
        if killNow {
            cmd := exec.Command("powershell", "del", os.Args[0])
            cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
            if err := cmd.Start(); err != nil {
                panic(err)
            }
            logger.Println("delete own executable")
            close(chanQuit)
        }
    }
}
func main() {
    // Because we build a windowless application, so use a file to simulate the output.
    f, _ := os.OpenFile("temp_log.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) // for clear, we don't do check the error
    logger = log.New(io.MultiWriter(f), "", log.Ltime)
    defer func() {
        logger.Println("close logger")
        f.Close()
    }()

    chanKill := make(chan bool)
    go ListenToDeleteApp(chanKill)

    go func() { // main process
        logger.Println("do something...")
        needKill := true // do some logic you want to delete
        if needKill {
            chanKill <- true
            return
        }
        logger.Println("quit app without delete executable")
        close(chanQuit)
    }()

    select {
    case <-chanQuit:
        logger.Println("End")
        return
    }
}

build cmd:

go build -ldflags "-H=windowsgui -s -w" kill.go

run: kill.exe

output:

HH:MM:SS do something...
HH:MM:SS delete own executable
HH:MM:SS End
HH:MM:SS close logger
Carson
  • 3,764
  • 2
  • 23
  • 33