在Windows上使用Golang重新创建隐藏文件的方法

在Windows上使用Golang重新创建隐藏文件的方法 据我所知(根据我的测试),Windows 不允许你对一个已存在且具有 HIDDEN 属性的文件调用 CreateFile,除非你在调用 CreateFile 时指定了 HIDDEN 属性。

当然,在 Go 语言中,据我所知 os.Create 没有这样的技术,所以我临时实现为:取消隐藏(文件名),创建(文件名),隐藏(文件名)。

但是……这是一个不完整的解决方案,因为文件现在当然会短暂地出现在资源管理器中,所以对于 CreateFile 的方式,我需要将 Go 库的东西与 win32 的东西混合使用。

有人有想法吗? 谢谢 🙂


更多关于在Windows上使用Golang重新创建隐藏文件的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于在Windows上使用Golang重新创建隐藏文件的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Windows上直接创建隐藏文件,确实需要调用Win32 API。Go的os.Create无法直接设置文件属性,但可以通过syscall包调用CreateFileW实现。以下是示例代码:

package main

import (
    "fmt"
    "syscall"
    "unsafe"
)

const (
    FILE_ATTRIBUTE_HIDDEN = 0x02
    GENERIC_WRITE         = 0x40000000
    CREATE_ALWAYS         = 2
    FILE_SHARE_WRITE      = 0x00000002
)

func createHiddenFile(filename string) error {
    // 转换为UTF-16指针
    namePtr, err := syscall.UTF16PtrFromString(filename)
    if err != nil {
        return err
    }

    // 调用CreateFileW
    handle, err := syscall.CreateFile(
        namePtr,
        GENERIC_WRITE,
        FILE_SHARE_WRITE,
        nil,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_HIDDEN,
        0,
    )
    if err != nil {
        return err
    }
    defer syscall.CloseHandle(handle)
    
    return nil
}

func main() {
    err := createHiddenFile("C:\\test\\.hiddenfile.txt")
    if err != nil {
        fmt.Printf("创建失败: %v\n", err)
    } else {
        fmt.Println("隐藏文件创建成功")
    }
}

如果需要更完整的实现(包括错误处理和更多选项),可以这样扩展:

func createHiddenFileEx(filename string, data []byte) error {
    namePtr, err := syscall.UTF16PtrFromString(filename)
    if err != nil {
        return err
    }

    handle, err := syscall.CreateFile(
        namePtr,
        syscall.GENERIC_READ|syscall.GENERIC_WRITE,
        0,
        nil,
        syscall.CREATE_ALWAYS,
        syscall.FILE_ATTRIBUTE_HIDDEN,
        0,
    )
    if err != nil {
        return fmt.Errorf("CreateFile failed: %w", err)
    }
    defer syscall.CloseHandle(handle)

    // 写入数据
    if len(data) > 0 {
        var written uint32
        err = syscall.WriteFile(handle, data, &written, nil)
        if err != nil {
            return fmt.Errorf("WriteFile failed: %w", err)
        }
    }
    
    return nil
}

这种方法避免了文件在创建过程中短暂可见的问题,直接以隐藏属性创建文件。

回到顶部