Skip to content

Instantly share code, notes, and snippets.

@imhuytq
Created January 24, 2022 08:06
Show Gist options
  • Save imhuytq/699a7c464cf939434e3a64789502960d to your computer and use it in GitHub Desktop.
Save imhuytq/699a7c464cf939434e3a64789502960d to your computer and use it in GitHub Desktop.
Tetsss
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?if $(var.Platform)=x64 ?>
<?define ProductCode = "102F7DF4-19A6-4d3d-987F-FF57A2031593" ?>
<?else ?>
<?define ProductCode = "8AE46CAF-220F-4B9F-9527-D4A19A27C45B" ?>
<?endif ?>
<Product Id="*" Name="Hiweb Printer" Language="1033" Version="1.0.0.0" Manufacturer="Hiweb Co.,Ltd" UpgradeCode="{F1E6FD66-E33F-4D89-8D1F-7F42D408632B}">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Icon Id="icon.ico" SourceFile="icon.ico"/>
<Property Id="ARPPRODUCTICON" Value="icon.ico" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir" />
<Feature Id="ProductFeature" Title="Printer" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="HiwebFolder" Name="Hiweb">
<Directory Id="INSTALLFOLDER" Name="Printer" />
</Directory>
</Directory>
<Directory Id="TempFolder" />
<Directory Id="CommonAppDataFolder">
<Directory Id="HiwebDataFolder" Name="Hiweb">
<Directory Id="PrinterNodeDataFolder" Name="Printer" />
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="SumatraPDF.exe" Guid="{5BC64FF6-A81D-46BC-8315-A5045E67B710}">
<File Id="SumatraPDF.exe" Name="SumatraPDF.exe" Source=".\SumatraPDF_x64.exe" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="Printer.exe" Guid="{976B18AD-C696-433A-9C1C-81795D3AB9BA}">
<File Id="Printer.exe" Name="Printer.exe" Source=".\Printer.exe" KeyPath="yes" Checksum="yes" />
<!--<ServiceInstall Name="Hiweb Printer Service" Description="Hiweb Printer Service" Start="auto" Type="ownProcess" ErrorControl="normal" Vital="yes" />-->
<!--<ServiceControl Id="StopService" Name="Hiweb Printer Service" Stop="uninstall" Remove="uninstall" />-->
</Component>
</ComponentGroup>
</Fragment>
</Wix>
package main
import (
"context"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"time"
"github.com/hashicorp/go-retryablehttp"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/urfave/cli/v2"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/debug"
)
var elog debug.Log
var client = retryablehttp.NewClient()
type Service struct {
i bool
}
func (service *Service) Execute(args []string, r <-chan svc.ChangeRequest, s chan<- svc.Status) (bool, uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
s <- svc.Status{State: svc.StartPending}
e := echo.New()
e.Use(middleware.CORS())
e.POST("printUrl", printUrl)
e.POST("printFile", printFile)
httpServer := http.Server{Addr: ":2020", Handler: e}
go func() {
log.Println("Starting http server...")
if err := httpServer.ListenAndServe(); err != http.ErrServerClosed {
// it is fine to use Fatal here because it is not main gorutine
log.Fatalf("HTTP server ListenAndServe: %v", err)
}
}()
s <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
loop:
for {
log.Println("For...")
c := <-r
switch c.Cmd {
case svc.Interrogate:
log.Println("Interrogate...")
s <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
log.Printf("svc... %v\n", c.Cmd)
s <- svc.Status{State: svc.StopPending}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := httpServer.Shutdown(ctx); err != nil {
return true, 2
}
break loop
default:
log.Printf("default... %v\n", c.Cmd)
// elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
continue loop
}
}
log.Println("break loop...")
return false, 0
}
type PrintUrlRequest struct {
Url string `json:"url" form:"url"`
}
func printUrl(c echo.Context) error {
req := new(PrintUrlRequest)
if err := c.Bind(req); err != nil {
return err
}
file, err := ioutil.TempFile("", "hiweb-printer-*.pdf")
if err != nil {
return err
}
resp, err := client.Get(req.Url)
if err != nil {
return err
}
defer resp.Body.Close()
if _, err := io.Copy(file, resp.Body); err != nil {
return err
}
return print(file)
}
type PrintFileRequest struct {
File string `json:"file" form:"file"`
}
func printFile(c echo.Context) error {
req := new(PrintFileRequest)
if err := c.Bind(req); err != nil {
return err
}
file, err := ioutil.TempFile("", "hiweb-printer-*.pdf")
if err != nil {
return err
}
// decode req.file from base64 encoded string to file
decoded, err := base64.StdEncoding.DecodeString(req.File)
if err != nil {
return err
}
if _, err := file.Write(decoded); err != nil {
return err
}
return print(file)
}
func print(file *os.File) error {
// defer os.Remove(file.Name())
fmt.Println(file.Name())
// exec command
cmd := exec.Command(sumatra, "-print-to", printer, "-print-settings", sumatraSettings, file.Name())
fmt.Println(cmd.String())
err := cmd.Run()
if err != nil {
return err
}
return nil
}
var sumatra string
var sumatraSettings string
var printer string
func main() {
app := &cli.App{
Name: "hiweb-printer",
Usage: "Hiweb Printer for Windows",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "sumatra-path",
Value: "SumatraPDF.exe",
Usage: "Path of Sumatra PDF",
Destination: &sumatra,
},
&cli.StringFlag{
Name: "sumatra-settings",
Value: "landscape,shrink,paper=stament",
Usage: "Sumatra PDF print settings",
Destination: &sumatraSettings,
},
&cli.StringFlag{
Name: "printer",
Aliases: []string{"p"},
Value: "Xprinter XP-490B",
Usage: "Printer name",
Destination: &printer,
},
},
HideHelpCommand: true,
Action: runService,
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
func runService(context *cli.Context) error {
// ex, err := os.Executable()
// if err != nil {
// panic(err)
// }
// fmt.Println(ex)
// fmt.Println(path.Dir(ex))
// filepath := ex + ".txt"
// fmt.Println(filepath)
// f, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
// if err != nil {
// log.Fatalf("error opening file: %v", err)
// }
// defer f.Close()
// log.SetOutput(f)
windowsService, err := svc.IsWindowsService()
if err != nil {
log.Fatalf("error windowsService: %v", err)
}
log.Printf("windowsService %t\n", windowsService)
s := &Service{
i: windowsService,
}
if windowsService {
err = svc.Run("Hiweb Printer Service", s)
} else {
err = debug.Run("Hiweb Printer Service", s)
}
if err != nil {
log.Fatalf("error Run: %v", err)
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment