您的位置:

Goembed:嵌入文件和dll

Goembed是一个Go编程语言中用于将文件和其他资源直接嵌入到代码中的工具。在使用过程中,Goembed可将文件如图片、CSS文件以及其他文本文件和DLL嵌入应用程序中,这样可以大大简化应用程序的部署和管理。接下来,我们将从不同的方面来详细阐述Goembed的嵌入文件和DLL功能。

一、Goembed嵌入DLL

1、嵌入单个DLL

Go语言本身是跨平台支持的,但是,为了实现相应的功能,还需要诸如动态链接库(DLL)之类的资源添加到应用程序中。如果您想在应用程序中嵌入一个简单的DLL文件,Goembed将为您提供具有以下文件内容的DLL文件:
//go:embed sample.dll
var d []byte
我们可以使用go generate命令来生成将DLL嵌入应用程序中的文件。因此,我们需要更新go.mod文件:
module demo

go 1.16

require (
    github.com/lxn/walk v0.0.0-20210809111303-dbed2ece652c
)

//go:generate go run ./tools/embeddll.go
该代码往go.mod文件添加了嵌入代码的进程。接下来,我们需要添加一个名为embeddll.go的新文件,并将如下内容添加到其中:
package main

import (
    "io/ioutil"
    "log"
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    out, err := os.Create("demo.rc")
    if err != nil {
        log.Fatal(err)
    }
    defer out.Close()

    // Write .rsrc file header
    out.WriteString("1 24 \"demo.exe.manifest\";\n")
    out.WriteString(`1 14 "MICROSOFT_D2D" {`);
    out.WriteString("FONT ");
    out.WriteString("DEFAULT_GUI_FONT");
    out.WriteString(" {\n");
    out.WriteString("  DIALOGEX 8, 8, 161, 36\n");
    out.WriteString("  STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\n")
    out.WriteString("  CAPTION \"\"\n");
    out.WriteString("  FONT 9, \"MS Shell Dlg\", 0, 0, 0x1\n");
    out.WriteString("}\n");
    out.WriteString("}\n");

    // Write command to embed the DLL
    out.WriteString("1 24 \"sample.dll\" {\n");
    out.WriteString("  RCDATA sample.dll\n");
    out.WriteString("}\n");

    out.Sync()

    // use rc.exe to compile .rc file to .syso
    cmd := exec.Command("cmd", "/c", "rc.exe", "/fo", "demo.syso", "demo.rc")
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    err = cmd.Run()
    if err != nil {
        log.Fatal(err)
    }

    err = os.Remove("demo.rc")
    if err != nil {
        log.Fatal(err)
    }
}
这个示例代码演示了如何将单个DLL文件嵌入应用程序中并在Windows上运行该应用程序。

2、嵌入多个DLL

如果您需要嵌入多个DLL文件,可以使用以下两种不同的方法来完成: 第一种方法:在每个DLL文件上使用相同的名称,即将每个DLL文件重命名为template.dll并运行以下命令:
go generate
golibrsrc -o myresource.syso *.dll
第二种方法:使用以下命令将每个DLL文件分别转换为.SYSO文件,并在应用程序代码中嵌入这些文件:
//go:embed sample1.dll sample2.dll sample3.dll
var d []byte

二、Goembed嵌入文件夹选取

如果您想将文件夹中的所有文件嵌入到应用程序中,则可以使用以下代码:
//go:embed mydirectory/*
var embeddedFS embed.FS

f, err := embeddedFS.Open("mydirectory/myfile.txt")
if err != nil {
  log.Fatal(err)
}

b, err := ioutil.ReadAll(f)
if err != nil {
  log.Fatal(err)
}

fmt.Println(string(b))
使用此代码,将在示例文件夹中的所有文件(包括子文件夹)嵌入到名称为d的[]byte变量中,我们可以使用此[]byte变量访问所有文件。

3、Goembed选择文件夹

如果您只想嵌入文件夹中的一些文件,则可以在路径中指定嵌入的文件。例如,假设我们只想嵌入文件夹中的文件.txt和file2.txt,我们可以使用以下代码:
//go:embed mydirectory/file.txt mydirectory/file2.txt
var embeddedFS embed.FS

f, err := embeddedFS.Open("mydirectory/file.txt")
if err != nil {
  log.Fatal(err)
}

b, err := ioutil.ReadAll(f)
if err != nil {
  log.Fatal(err)
}

fmt.Println(string(b))
使用此代码,只有文件夹中file.txt和file2.txt文件将嵌入到名称为d的[]byte变量中。我们可以使用此[]byte变量访问两个文件。

总结

通过使用Goembed,我们可以轻松地将文件和其他资源嵌入到Go应用程序中,避免了将文件保存在磁盘上并需要相应的文件位置的繁琐过程。无论是嵌入单个DLL还是文件夹,Goembed都能简化您的代码,并让您的应用程序更易于部署和管理。