-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
413 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ | |
|
||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 | ||
.glide/ | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,23 @@ | ||
# go-wingui | ||
本项目是golang在windows上用户图形界面gui解决方案,本项目可以不用对你的go写的网站程序做任何修改,就可以实现本地化,使用go+html+css+js写windows本地应用 | ||
# 使用说明 | ||
1.环境要求是windows,理论上xp以上32位,64位都支持。 | ||
2.下载程序[go-wingui](https://github.com/snail007/go-wingui/releases/tag/1.0) | ||
3.解压到比如D盘,D:\dist | ||
4.把你的go网站程序(假设名字是app.exe)放入D:\dist\app文件夹 | ||
5、假设你的app.exe启动之后,访问链接是http://127.0.0.1:9999/index | ||
编辑D:\dist\launcher.ini,做如下部分修改: | ||
start_exec="app\app.exe" | ||
start_url="http://127.0.0.1:9999/index" | ||
6.配置完毕,双击D:\dist\launcher.exe,即可看到效果了。 | ||
|
||
**提示:** | ||
如果是go程序,为了避免出现程序启动出现命令行黑框,编译go程序的时候加上参数:go build -ldflags="-H=windowsgui" | ||
|
||
# 原理介绍 | ||
本项目原理是写了一个本地应用,使用autoit3脚本技术把自带的谷歌浏览器嵌入到应用里面实现了一个“浏览器”,然后“浏览器”里面打开go网站,这样就实现了一个不依赖系统浏览器的独立gui本地应用程序。我们可以使用方便强大的html+css+js完成优美的应用界面,功能可以通过RPC,ajax调用后端go Web服务实现。 | ||
|
||
# 源码使用 | ||
1.克隆源码 | ||
git clone https://github.com/snail007/go-wingui.git ./ | ||
2.下载绿色版chrome浏览器,解压后把文件夹chrome,放在位置:go-wingui/cef/chrome,chrome.exe的路径应该是:go-wingui/cef/chrome/chrome.exe | ||
3.开发环境完成 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.exe | ||
chrome |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#RequireAdmin | ||
#NoTrayIcon | ||
#Region | ||
#AutoIt3Wrapper_Icon=favicon.ico | ||
#AutoIt3Wrapper_Res_Fileversion=1.0.0.11 | ||
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y | ||
#EndRegion | ||
#include <WinApi.au3> | ||
#include <GUIConstantsEx.au3> | ||
#Include <GuiToolBar.au3> | ||
#include <WindowsConstants.au3> | ||
#include <Constants.au3> | ||
#include <AutoItConstants.au3> | ||
#include <TrayConstants.au3> | ||
|
||
If UBound($CmdLine) <> 5 Then | ||
Exit(0) | ||
EndIf | ||
Local $url=$CmdLine[1] | ||
Local $title=$CmdLine[2] | ||
Local $width=$CmdLine[3] | ||
Local $height=$CmdLine[4] | ||
|
||
Local $flag="[CLASS:Chrome_WidgetWin_1]" | ||
Run("chrome/chrome.exe --chrome-frame --kiosk "&$url&"&w="&$width&"&h="&$height) | ||
WinWait($flag, "") | ||
Opt('wintitlematchmode', 4) | ||
Local $hWnd = WinGetHandle($flag) | ||
Local $pWnd = GUICreate($title,$width,$height) | ||
_WinAPI_SetParent($hWnd,$pWnd) | ||
GUISetState(@SW_SHOW,$pWnd) | ||
Opt("TrayMenuMode",11) | ||
Local $showHide = TrayCreateItem("显示/隐藏") | ||
Local $idExit = TrayCreateItem("退出") | ||
TraySetState($TRAY_ICONSTATE_SHOW) ; | ||
TraySetToolTip($title) | ||
Local Const $sCLSID_TaskbarList = "{56FDF344-FD6D-11D0-958A-006097C9A090}" | ||
Local Const $sIID_ITaskbarList = "{56FDF342-FD6D-11D0-958A-006097C9A090}" | ||
Local Const $sTagITaskbarList = "HrInit hresult(); AddTab hresult(hwnd); DeleteTab hresult(hwnd); ActivateTab hresult(hwnd); SetActiveAlt hresult(hwnd);" | ||
Local $oTaskbarList = ObjCreateInterface($sCLSID_TaskbarList, $sIID_ITaskbarList, $sTagITaskbarList) | ||
$oTaskbarList.HrInit() | ||
$oTaskbarList.DeleteTab($hWnd) | ||
While 1 | ||
$msg = GUIGetMsg() | ||
$imsg = TrayGetMsg() | ||
Select | ||
Case $msg = $GUI_EVENT_CLOSE | ||
GUISetState(@SW_HIDE,$pWnd) | ||
Case $imsg = 0 | ||
ContinueLoop | ||
Case $imsg = $idExit | ||
Exit(0) | ||
Case $imsg = $showHide | ||
Local $iState = WinGetState($hWnd) | ||
If BitAND($iState,2) Then | ||
GUISetState(@SW_HIDE,$pWnd) | ||
Else | ||
GUISetState(@SW_SHOW,$pWnd) | ||
WinActivate($pWnd) | ||
EndIf | ||
EndSelect | ||
WEnd |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.exe |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
"os" | ||
"os/exec" | ||
"os/signal" | ||
|
||
"path/filepath" | ||
"strings" | ||
"syscall" | ||
|
||
ini "github.com/go-ini/ini" | ||
) | ||
|
||
type Settings struct { | ||
SrvURL string | ||
Width int32 | ||
Height int32 | ||
Title string | ||
URL string | ||
AppPid int | ||
LauncherPid int | ||
} | ||
|
||
var ( | ||
srvPath = "" | ||
cefPath = "" | ||
cfg, err = ini.LoadSources(ini.LoadOptions{AllowBooleanKeys: true}, "launcher.ini") | ||
cmdSrv *exec.Cmd | ||
cmdApp *exec.Cmd | ||
cmdCEF *exec.Cmd | ||
wd, _ = os.Getwd() | ||
) | ||
|
||
func init() { | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
_srv, _ := cfg.Section("").GetKey("srv") | ||
_cef, _ := cfg.Section("").GetKey("cef") | ||
srvPath = _srv.String() | ||
cefPath = _cef.String() | ||
srvPath = filepath.Join(wd, filepath.Join(srvPath)) | ||
cefPath = filepath.Join(wd, filepath.Join(cefPath)) | ||
} | ||
func main() { | ||
_title, _ := cfg.Section("").GetKey("app_title") | ||
_url, _ := cfg.Section("").GetKey("start_url") | ||
_width, _ := cfg.Section("").GetKey("window_width") | ||
_height, _ := cfg.Section("").GetKey("window_height") | ||
|
||
srvURL := startSrv() | ||
//fmt.Print(srvURL) | ||
startApp() | ||
w, _ := _width.Int() | ||
h, _ := _height.Int() | ||
startCEF(srvURL, _title.String(), _url.String(), w, h) | ||
startTray() | ||
Clean() | ||
} | ||
func startTray() { | ||
|
||
} | ||
func startCEF(srvURL, title, url0 string, width, height int) { | ||
args := []string{ | ||
srvURL + "/load?url=" + url.QueryEscape(url0), | ||
title, | ||
fmt.Sprintf("%d", width), | ||
fmt.Sprintf("%d", height), | ||
} | ||
cmdCEF = exec.Command(cefPath, args...) | ||
cmdCEF.Dir = filepath.Dir(cefPath) | ||
err = cmdCEF.Start() | ||
if err != nil { | ||
fmt.Printf("ERR:%s", err) | ||
killALl() | ||
os.Exit(1) | ||
} | ||
go func() { | ||
cmdCEF.Wait() | ||
killALl() | ||
os.Exit(0) | ||
}() | ||
} | ||
func startSrv() string { | ||
buf := make([]byte, 100) | ||
cmdSrv = exec.Command(srvPath) | ||
cmdSrv.Dir = filepath.Dir(srvPath) | ||
outp, _ := cmdSrv.StdoutPipe() | ||
err := cmdSrv.Start() | ||
if err != nil { | ||
fmt.Printf("ERR:%s", err) | ||
killALl() | ||
os.Exit(1) | ||
} | ||
n, _ := outp.Read(buf) | ||
return fmt.Sprintf("%s", string(buf[:n])) | ||
} | ||
|
||
func startApp() { | ||
argsString, _ := cfg.Section("").GetKey("start_exec") | ||
if argsString.String() == "" { | ||
return | ||
} | ||
args := strings.Split(argsString.String(), " ") | ||
app, _ := filepath.Abs(args[0]) | ||
if len(args) > 1 { | ||
cmdApp = exec.Command(app, args[1:]...) | ||
} else { | ||
cmdApp = exec.Command(app) | ||
} | ||
cmdApp.Dir = filepath.Dir(app) | ||
err := cmdApp.Start() | ||
if err != nil { | ||
fmt.Printf("ERR:%s", err) | ||
killALl() | ||
os.Exit(1) | ||
} | ||
} | ||
func Clean() { | ||
signalChan := make(chan os.Signal, 1) | ||
cleanupDone := make(chan bool) | ||
signal.Notify(signalChan, | ||
os.Interrupt, | ||
syscall.SIGHUP, | ||
syscall.SIGINT, | ||
syscall.SIGTERM, | ||
syscall.SIGQUIT) | ||
go func() { | ||
for _ = range signalChan { | ||
fmt.Println("\nReceived an interrupt, stopping services...") | ||
killALl() | ||
cleanupDone <- true | ||
} | ||
}() | ||
<-cleanupDone | ||
} | ||
func killALl() { | ||
if cmdApp != nil && cmdApp.Process != nil { | ||
fmt.Printf("\nclean app process %d", cmdApp.Process.Pid) | ||
cmdApp.Process.Kill() | ||
} | ||
if cmdSrv != nil && cmdSrv.Process != nil { | ||
fmt.Printf("\nclean srv process %d", cmdSrv.Process.Pid) | ||
cmdSrv.Process.Kill() | ||
} | ||
if cmdCEF != nil && cmdCEF.Process != nil { | ||
fmt.Printf("\nclean cef process %d", cmdCEF.Process.Pid) | ||
cmdCEF.Process.Kill() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#程序标题 | ||
app_title="GO-GUI" | ||
#程序初始化的时候,需要调用的程序(可以放在app目录下面),一般是本地网站程序,没有留空 | ||
#start_exec="app/myapp.exe" | ||
start_exec="" | ||
#程序初始化的时候,打开的首页 | ||
start_url="http://www.baidu.com" | ||
#窗口宽度,单位像素 | ||
window_width=800 | ||
#窗口高度,单位像素 | ||
window_height=500 | ||
#内部服务,不要修改 | ||
srv="../srv/srv.exe" | ||
#内部服务,不要修改 | ||
cef="../cef/cef.exe" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.exe |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"io/ioutil" | ||
"net" | ||
"net/http" | ||
"os" | ||
"strings" | ||
"time" | ||
) | ||
|
||
func main() { | ||
listen := flag.String("b", "127.0.0.1", "binding ip") | ||
flag.Parse() | ||
fmt.Fprintf(os.Stdout, "http://%s:%s", *listen, run_http_server(*listen)) | ||
select {} | ||
} | ||
|
||
func handler(w http.ResponseWriter, req *http.Request) { | ||
w.Header().Set("Content-Type", "text/html; charset=utf-8") | ||
if strings.HasPrefix(req.URL.Path, "/load") { | ||
f, _ := os.OpenFile("start.html", os.O_RDONLY, 0666) | ||
c, _ := ioutil.ReadAll(f) | ||
fmt.Fprintf(w, string(c)) | ||
} else if strings.HasPrefix(req.URL.Path, "/ping") { | ||
_url := req.URL.Query().Get("url") | ||
err := HTTPGet(_url, 5000) | ||
if err == nil { | ||
fmt.Fprintf(w, "1") | ||
} | ||
fmt.Println(err) | ||
} | ||
} | ||
|
||
func run_http_server(ip string) (port string) { | ||
http.HandleFunc("/", handler) | ||
listener, err := net.Listen("tcp", ip+":0") | ||
if err != nil { | ||
panic(err) | ||
} | ||
go func() { | ||
panic(http.Serve(listener, nil)) | ||
}() | ||
return fmt.Sprintf("%d", listener.Addr().(*net.TCPAddr).Port) | ||
} | ||
|
||
func HTTPGet(URL string, timeout int) (err error) { | ||
tr := &http.Transport{} | ||
var resp *http.Response | ||
var client *http.Client | ||
defer func() { | ||
if resp != nil && resp.Body != nil { | ||
resp.Body.Close() | ||
} | ||
tr.CloseIdleConnections() | ||
}() | ||
client = &http.Client{Timeout: time.Millisecond * time.Duration(timeout), Transport: tr} | ||
resp, err = client.Get(URL) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.