如何删除自己(可执行文件)在Windows?

hyrbngr7  于 2023-03-24  发布在  Windows
关注(0)|答案(2)|浏览(255)
package main

import "os"

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

编译这个
GOOS=windows GOARCH=386 go build test.go
那就喝酒吧

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

我想“好吧,这是葡萄酒”,并运行在Windows XP上的VirtualBox。但这是错误的Windows返回。
对不起,我的英语。

yiytaume

yiytaume1#

使用CreateProcess函数,可以使用syscall包在Go中编写:

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)
    }
}
ryoqjall

ryoqjall2#

对于Windows,您可以使用系统API:shell32.dll.ShellExecuteW。它在另一个进程上运行,所以即使你的主程序已经终止,它也会继续运行。因此,你只需要在程序退出之前调用它来删除程序。为了确保delete命令在程序终止之后被调用,你可以等待一段时间再删除它(使用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对于多个命令使用;进行拆分

命令1;命令2;命令3
启动-睡眠3;del“C:\xxx.exe”

相关问题