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都能简化您的代码,并让您的应用程序更易于部署和管理。