国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

? ??? ?? Golang Go?? ??? ??? ??? ??? ??: ??? ???

Go?? ??? ??? ??? ??? ??: ??? ???

Nov 04, 2024 am 08:18 AM

Building Cross-Platform System Services in Go: A Step-by-Step Guide

??? ???? ??????

??? ???? ??? ??? ????? ?? ??????? ???? ?? ???????. ??? ?? ?? ???? ???? ????? ?????. ??, ??, ?? ??? ?? ??? ???? ?? ??? Windows? Service Control Manager, Linux(???? Destro)?? ?????? macOS?? ?????.

?? ??????? ?? ???? ???? ??? ?? ?????? ????, ??, ?? ????? ????? ?? ??? ??????. Linux??? ??? ???? ????? ????? ??, macOS??? Launch Agent ?? ????? ???.

?? ??? ???? ???? ?? ??*?*

??? ??? ??? ???? ???? ???, ???, ???? ??? ?? ??? ?????. Go? ?? ?? ??? ? ??? ?????.

  • ??? ? ??: Go? ???? ???? ?? ??? ??? ?? ??? ? ?? ??? ????? ???? ??? ?????. ??? ?? ?????? ???? ?? ???? ????? ??? ? ???? ??????.

  • ??? ?? ? ???: Go? ??? ??? ??? ??? ???? ???? ????? ?????. ??? ?? ?? ??? ?? ??? ??? ???? ? ?????.

  • ???? ?? ?? ???: Go? ??? ??? ??? ?? ? ?? ??? ??????. ???? ??? ????? ???? ??? ?? ??? ?? ???? ???? ?? ?? ??? ????? ??? ??? ??? ???? ????.

  • ??? ??? ? ???: Go? ??? ??? ??? ?? ?? ??????? ??? ?? ??? ?? ??? ??? ? ????. CGO? ?? Go? Win32 ? Objective-C? ?? ?? ?? ??? API? ?? ??? ? ?? ????? ?? ??? ??? ? ?? ???? ?????.

Go?? ??? ??

? ?? ??????? GO? ???? ???? ?? GO ??? ?? ?? ??? ??? ?????. ??? ?? ?? ????? ?? ?????.

???? ??

go-service/
├── Makefile                 # Build and installation automation
├── cmd/
│   └── service/
│       └── main.go          # Main entry point with CLI flags and command handling
├── internal/
│   ├── service/
│   │   └── service.go       # Core service implementation
│   └── platform/            # Platform-specific implementations
│       ├── config.go        # Configuration constants
│       ├── service.go       # Cross-platform service interface
│       ├── windows.go       # Windows-specific service management
│       ├── linux.go         # Linux-specific systemd service management
│       └── darwin.go        # macOS-specific launchd service management
└── go.mod                   # Go module definition

1??: ?? ??

Go ?? ???:

go mod init go-service

internal/platform ???? ? config.go?? ?? ??? ?????. ? ??? ?? ??? ?? ?? ?? ?????? ??? ?? ??? ? ????.

??: ??/???/config.go

package main

const (
 ServiceName    = "go-service"                                                      //Update your service name
 ServiceDisplay = "Go Service"                                                      // Update your display name
 ServiceDesc    = "A service that appends 'Hello World' to a file every 5 minutes." // Update your Service Description
 LogFileName    = "go-service.log"                                              // Update your Log file name
)

func GetInstallDir() string {
 switch runtime.GOOS {
 case "darwin":
  return "/usr/local/opt/go-service"
 case "linux":
  return "/opt/go-service"
 case "windows":
  return filepath.Join(os.Getenv("ProgramData"), ServiceName)
 default:
  return ""
 }
}

func copyFile(src, dst string) error {
 source, err := os.Open(src)
 if err != nil {
  return fmt.Errorf("failed to open source file: %w", err)
 }
 defer source.Close()

 destination, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
 if err != nil {
  return fmt.Errorf("failed to create destination file: %w", err)
 }
 defer destination.Close()

 _, err = io.Copy(destination, source)
 return err
}

?? ??:

  • ???? ??? ?? ?? ???? ??? ??.

  • GetInstallDir()? ? OS? ?? ??? ?? ? ?? ?? ??? ?????.

  • ??? ?? ?? GetInstallDir()?? ???? ?? ??? ?? ??? ???? ?? copyFile()? ?????.

2??: ?? ??? ?? ??

??/?????? ???? ?? ??? ?????. ?? ??? ??? ?? ???? ?? ??? ?????.

? ??? ???? 5??? ??? ? ????? ??? "Hello World"? ?????.

??: Internal/service/service.go

??? ??

go-service/
├── Makefile                 # Build and installation automation
├── cmd/
│   └── service/
│       └── main.go          # Main entry point with CLI flags and command handling
├── internal/
│   ├── service/
│   │   └── service.go       # Core service implementation
│   └── platform/            # Platform-specific implementations
│       ├── config.go        # Configuration constants
│       ├── service.go       # Cross-platform service interface
│       ├── windows.go       # Windows-specific service management
│       ├── linux.go         # Linux-specific systemd service management
│       └── darwin.go        # macOS-specific launchd service management
└── go.mod                   # Go module definition

??? ??

go mod init go-service

??? ????

? ???? ???? ??? ?? ?? ? ?? ??? ?????.

package main

const (
 ServiceName    = "go-service"                                                      //Update your service name
 ServiceDisplay = "Go Service"                                                      // Update your display name
 ServiceDesc    = "A service that appends 'Hello World' to a file every 5 minutes." // Update your Service Description
 LogFileName    = "go-service.log"                                              // Update your Log file name
)

func GetInstallDir() string {
 switch runtime.GOOS {
 case "darwin":
  return "/usr/local/opt/go-service"
 case "linux":
  return "/opt/go-service"
 case "windows":
  return filepath.Join(os.Getenv("ProgramData"), ServiceName)
 default:
  return ""
 }
}

func copyFile(src, dst string) error {
 source, err := os.Open(src)
 if err != nil {
  return fmt.Errorf("failed to open source file: %w", err)
 }
 defer source.Close()

 destination, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
 if err != nil {
  return fmt.Errorf("failed to create destination file: %w", err)
 }
 defer destination.Close()

 _, err = io.Copy(destination, source)
 return err
}

?? ??? ??

type Service struct {
 logFile string
 stop    chan struct{}
 wg      sync.WaitGroup
 started bool
 mu      sync.Mutex
}

run ???? ?? ??? ??? ?????.

?? ??:

  • ??? ??? ?? ?? ??

  • ???? ?? ??

  • ??? ?? ??

  • ?? ??

?? ??

? ???? 5??? ?????? ?? "Hello World"? ?????

func New() (*Service, error) {
 installDir := platform.GetInstallDir()
 if installDir == "" {
  return nil, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
 }

 logFile := filepath.Join(installDir, "logs", platform.LogFileName)

 return &Service{
  logFile: logFile,
  stop:    make(chan struct{}),
 }, nil
}

3??: ???? ??? ?? ??

internal/platform ?????? ???? ??, ??, ???? ?? ???? ??? ???? ????.

macOS(darwin.go)

darwin.go?? launchctl? ???? ??? ?? ? ??? ???? .plist ?? ??? ?? macOS ?? ??? ?????.

??:internal/platform/darwin.go

// Start the service
func (s *Service) Start(ctx context.Context) error {
 s.mu.Lock()
 if s.started {
  s.mu.Unlock()
  return fmt.Errorf("service already started")
 }
 s.started = true
 s.mu.Unlock()

 if err := os.MkdirAll(filepath.Dir(s.logFile), 0755); err != nil {
  return fmt.Errorf("failed to create log directory: %w", err)
 }

 s.wg.Add(1)
 go s.run(ctx)

 return nil
}

// Stop the service gracefully
func (s *Service) Stop() error {
 s.mu.Lock()
 if !s.started {
  s.mu.Unlock()
  return fmt.Errorf("service not started")
 }
 s.mu.Unlock()

 close(s.stop)
 s.wg.Wait()

 s.mu.Lock()
 s.started = false
 s.mu.Unlock()

 return nil
}

???(linux.go)

Linux??? systemd? ???? ???? ?????. .service ?? ? ?? ???? ?????.

??:internal/platform/linux.go

func (s *Service) run(ctx context.Context) {
 defer s.wg.Done()
 log.Printf("Service started, logging to: %s\n", s.logFile)

 ticker := time.NewTicker(5 * time.Minute)
 defer ticker.Stop()

 if err := s.writeLog(); err != nil {
  log.Printf("Error writing initial log: %v\n", err)
 }

 for {
  select {
  case <-ctx.Done():
   log.Println("Service stopping due to context cancellation")
   return
  case <-s.stop:
   log.Println("Service stopping due to stop signal")
   return
  case <-ticker.C:
   if err := s.writeLog(); err != nil {
    log.Printf("Error writing log: %v\n", err)
   }
  }
 }
}

???(windows.go)

Windows? ?? sc ??? ???? ???? ???? ?????.

??:internal/platform/windows.go

func (s *Service) writeLog() error {
 f, err := os.OpenFile(s.logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
 if err != nil {
  return fmt.Errorf("failed to open log file: %w", err)
 }
 defer f.Close()

 _, err = f.WriteString(fmt.Sprintf("[%s] Hello World\n", time.Now().Format(time.RFC3339)))
 if err != nil {
  return fmt.Errorf("failed to write to log file: %w", err)
 }
 return nil
}

4??: ?? ?? ??(main.go)

????? cmd/service/main.go?? main.go? ???? ??, ?? ? ??? ??? ?????.

??:cmd/service/main.go

package platform

import (
 "fmt"
 "os"
 "os/exec"
 "path/filepath"
)

type darwinService struct{}

const plistTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>%s</string>
    <key>ProgramArguments</key>
    <array>
        <string>%s</string>
        <string>-run</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>%s</string>
</dict>
</plist>`

func (s *darwinService) Install(execPath string) error {
 installDir := GetInstallDir()
 if err := os.MkdirAll(installDir, 0755); err != nil {
  return fmt.Errorf("failed to create installation directory: %w", err)
 }

 // Copy binary to installation directory
 installedBinary := filepath.Join(installDir, "bin", filepath.Base(execPath))
 if err := os.MkdirAll(filepath.Dir(installedBinary), 0755); err != nil {
  return fmt.Errorf("failed to create bin directory: %w", err)
 }

 if err := copyFile(execPath, installedBinary); err != nil {
  return fmt.Errorf("failed to copy binary: %w", err)
 }

 plistPath := filepath.Join("/Library/LaunchDaemons", ServiceName+".plist")
 content := fmt.Sprintf(plistTemplate, ServiceName, installedBinary, installDir)

 if err := os.WriteFile(plistPath, []byte(content), 0644); err != nil {
  return fmt.Errorf("failed to write plist file: %w", err)
 }

 if err := exec.Command("launchctl", "load", plistPath).Run(); err != nil {
  return fmt.Errorf("failed to load service: %w", err)
 }
 return nil
}

func (s *darwinService) Uninstall() error {
 plistPath := filepath.Join("/Library/LaunchDaemons", ServiceName+".plist")

 if err := exec.Command("launchctl", "unload", plistPath).Run(); err != nil {
  return fmt.Errorf("failed to unload service: %w", err)
 }

 if err := os.Remove(plistPath); err != nil {
  return fmt.Errorf("failed to remove plist file: %w", err)
 }
 return nil
}

func (s *darwinService) Status() (bool, error) {
 err := exec.Command("launchctl", "list", ServiceName).Run()
 return err == nil, nil
}

func (s *darwinService) Start() error {
 if err := exec.Command("launchctl", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *darwinService) Stop() error {
 if err := exec.Command("launchctl", "stop", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 return nil
}

??? ?? ? ??

??? ?? ??? ???? ????? GOOS ? GOARCH ?? ??? ?????. ?? ?? Windows??? ????? ??? ?????.

package platform

import (
 "fmt"
 "os"
 "os/exec"
 "path/filepath"
)

type linuxService struct{}

const systemdServiceTemplate = `[Unit]
Description=%s

[Service]
ExecStart=%s -run
Restart=always
User=root
WorkingDirectory=%s

[Install]
WantedBy=multi-user.target
`

func (s *linuxService) Install(execPath string) error {
 installDir := GetInstallDir()
 if err := os.MkdirAll(installDir, 0755); err != nil {
  return fmt.Errorf("failed to create installation directory: %w", err)
 }

 installedBinary := filepath.Join(installDir, "bin", filepath.Base(execPath))
 if err := os.MkdirAll(filepath.Dir(installedBinary), 0755); err != nil {
  return fmt.Errorf("failed to create bin directory: %w", err)
 }

 if err := copyFile(execPath, installedBinary); err != nil {
  return fmt.Errorf("failed to copy binary: %w", err)
 }

 servicePath := filepath.Join("/etc/systemd/system", ServiceName+".service")
 content := fmt.Sprintf(systemdServiceTemplate, ServiceDesc, installedBinary, installDir)

 if err := os.WriteFile(servicePath, []byte(content), 0644); err != nil {
  return fmt.Errorf("failed to write service file: %w", err)
 }

 commands := [][]string{
  {"systemctl", "daemon-reload"},
  {"systemctl", "enable", ServiceName},
  {"systemctl", "start", ServiceName},
 }

 for _, args := range commands {
  if err := exec.Command(args[0], args[1:]...).Run(); err != nil {
   return fmt.Errorf("failed to execute %s: %w", args[0], err)
  }
 }
 return nil
}

func (s *linuxService) Uninstall() error {
 _ = exec.Command("systemctl", "stop", ServiceName).Run()
 _ = exec.Command("systemctl", "disable", ServiceName).Run()

 servicePath := filepath.Join("/etc/systemd/system", ServiceName+".service")
 if err := os.Remove(servicePath); err != nil {
  return fmt.Errorf("failed to remove service file: %w", err)
 }
 return nil
}

func (s *linuxService) Status() (bool, error) {
 output, err := exec.Command("systemctl", "is-active", ServiceName).Output()
 if err != nil {
  return false, nil
 }
 return string(output) == "active\n", nil
}

func (s *linuxService) Start() error {
 if err := exec.Command("systemctl", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *linuxService) Stop() error {
 if err := exec.Command("systemctl", "stop", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 return nil
}

Linux? ??:

package platform

import (
 "fmt"
 "os"
 "os/exec"
 "path/filepath"
 "strings"
)

type windowsService struct{}

func (s *windowsService) Install(execPath string) error {
 installDir := GetInstallDir()
 if err := os.MkdirAll(installDir, 0755); err != nil {
  return fmt.Errorf("failed to create installation directory: %w", err)
 }

 installedBinary := filepath.Join(installDir, "bin", filepath.Base(execPath))
 if err := os.MkdirAll(filepath.Dir(installedBinary), 0755); err != nil {
  return fmt.Errorf("failed to create bin directory: %w", err)
 }

 if err := copyFile(execPath, installedBinary); err != nil {
  return fmt.Errorf("failed to copy binary: %w", err)
 }

 cmd := exec.Command("sc", "create", ServiceName,
  "binPath=", fmt.Sprintf("\"%s\" -run", installedBinary),
  "DisplayName=", ServiceDisplay,
  "start=", "auto",
  "obj=", "LocalSystem")

 if err := cmd.Run(); err != nil {
  return fmt.Errorf("failed to create service: %w", err)
 }

 descCmd := exec.Command("sc", "description", ServiceName, ServiceDesc)
 if err := descCmd.Run(); err != nil {
  return fmt.Errorf("failed to set service description: %w", err)
 }

 if err := exec.Command("sc", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *windowsService) Uninstall() error {
 _ = exec.Command("sc", "stop", ServiceName).Run()
 if err := exec.Command("sc", "delete", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to delete service: %w", err)
 }

 // Clean up installation directory
 installDir := GetInstallDir()
 if err := os.RemoveAll(installDir); err != nil {
  return fmt.Errorf("failed to remove installation directory: %w", err)
 }
 return nil
}
func (s *windowsService) Status() (bool, error) {
 output, err := exec.Command("sc", "query", ServiceName).Output()
 if err != nil {
  return false, nil
 }
 return strings.Contains(string(output), "RUNNING"), nil
}

func (s *windowsService) Start() error {
 if err := exec.Command("sc", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *windowsService) Stop() error {
 if err := exec.Command("sc", "stop", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 return nil
}

macOS? ??:

go-service/
├── Makefile                 # Build and installation automation
├── cmd/
│   └── service/
│       └── main.go          # Main entry point with CLI flags and command handling
├── internal/
│   ├── service/
│   │   └── service.go       # Core service implementation
│   └── platform/            # Platform-specific implementations
│       ├── config.go        # Configuration constants
│       ├── service.go       # Cross-platform service interface
│       ├── windows.go       # Windows-specific service management
│       ├── linux.go         # Linux-specific systemd service management
│       └── darwin.go        # macOS-specific launchd service management
└── go.mod                   # Go module definition

??? ??

?? ?? ??? ?? ???? ??? ??? ?? ??? ???? ??? ? ????.

??: ??? ??? ????? ?? ????? ?? ??? ????? ?? ???? ??? ???? ???.

  • ??? ??: --install ???? ???? ???? ?????.
go mod init go-service
  • ?? ??: ???? ?? ??? ????? ??? ?????.
package main

const (
 ServiceName    = "go-service"                                                      //Update your service name
 ServiceDisplay = "Go Service"                                                      // Update your display name
 ServiceDesc    = "A service that appends 'Hello World' to a file every 5 minutes." // Update your Service Description
 LogFileName    = "go-service.log"                                              // Update your Log file name
)

func GetInstallDir() string {
 switch runtime.GOOS {
 case "darwin":
  return "/usr/local/opt/go-service"
 case "linux":
  return "/opt/go-service"
 case "windows":
  return filepath.Join(os.Getenv("ProgramData"), ServiceName)
 default:
  return ""
 }
}

func copyFile(src, dst string) error {
 source, err := os.Open(src)
 if err != nil {
  return fmt.Errorf("failed to open source file: %w", err)
 }
 defer source.Close()

 destination, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
 if err != nil {
  return fmt.Errorf("failed to create destination file: %w", err)
 }
 defer destination.Close()

 _, err = io.Copy(destination, source)
 return err
}
  • ??? ??: ???? ???? ?? ?? --uninstall ???? ?????.
type Service struct {
 logFile string
 stop    chan struct{}
 wg      sync.WaitGroup
 started bool
 mu      sync.Mutex
}

TaskFile? ???? ??? ?? ? ??(?? ??)

Go ??? ???? ???? ???? ???? ??? ? ??? TaskFile? ???? ?? ????. ??? ????? ????? ??? ?????.

  • ?? ????? ??? ??

  • ??? YAML ?? ??

  • ??? ??? ??

?? ??

?? Task? ???? ??? ?????.

func New() (*Service, error) {
 installDir := platform.GetInstallDir()
 if installDir == "" {
  return nil, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
 }

 logFile := filepath.Join(installDir, "logs", platform.LogFileName)

 return &Service{
  logFile: logFile,
  stop:    make(chan struct{}),
 }, nil
}

?? ?? ??? ???? ?????.

?OS

// Start the service
func (s *Service) Start(ctx context.Context) error {
 s.mu.Lock()
 if s.started {
  s.mu.Unlock()
  return fmt.Errorf("service already started")
 }
 s.started = true
 s.mu.Unlock()

 if err := os.MkdirAll(filepath.Dir(s.logFile), 0755); err != nil {
  return fmt.Errorf("failed to create log directory: %w", err)
 }

 s.wg.Add(1)
 go s.run(ctx)

 return nil
}

// Stop the service gracefully
func (s *Service) Stop() error {
 s.mu.Lock()
 if !s.started {
  s.mu.Unlock()
  return fmt.Errorf("service not started")
 }
 s.mu.Unlock()

 close(s.stop)
 s.wg.Wait()

 s.mu.Lock()
 s.started = false
 s.mu.Unlock()

 return nil
}

???

func (s *Service) run(ctx context.Context) {
 defer s.wg.Done()
 log.Printf("Service started, logging to: %s\n", s.logFile)

 ticker := time.NewTicker(5 * time.Minute)
 defer ticker.Stop()

 if err := s.writeLog(); err != nil {
  log.Printf("Error writing initial log: %v\n", err)
 }

 for {
  select {
  case <-ctx.Done():
   log.Println("Service stopping due to context cancellation")
   return
  case <-s.stop:
   log.Println("Service stopping due to stop signal")
   return
  case <-ticker.C:
   if err := s.writeLog(); err != nil {
    log.Printf("Error writing log: %v\n", err)
   }
  }
 }
}

???

func (s *Service) writeLog() error {
 f, err := os.OpenFile(s.logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
 if err != nil {
  return fmt.Errorf("failed to open log file: %w", err)
 }
 defer f.Close()

 _, err = f.WriteString(fmt.Sprintf("[%s] Hello World\n", time.Now().Format(time.RFC3339)))
 if err != nil {
  return fmt.Errorf("failed to write to log file: %w", err)
 }
 return nil
}

?? ??

???? ??? Taskfile.yml? ????.

package platform

import (
 "fmt"
 "os"
 "os/exec"
 "path/filepath"
)

type darwinService struct{}

const plistTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>%s</string>
    <key>ProgramArguments</key>
    <array>
        <string>%s</string>
        <string>-run</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>%s</string>
</dict>
</plist>`

func (s *darwinService) Install(execPath string) error {
 installDir := GetInstallDir()
 if err := os.MkdirAll(installDir, 0755); err != nil {
  return fmt.Errorf("failed to create installation directory: %w", err)
 }

 // Copy binary to installation directory
 installedBinary := filepath.Join(installDir, "bin", filepath.Base(execPath))
 if err := os.MkdirAll(filepath.Dir(installedBinary), 0755); err != nil {
  return fmt.Errorf("failed to create bin directory: %w", err)
 }

 if err := copyFile(execPath, installedBinary); err != nil {
  return fmt.Errorf("failed to copy binary: %w", err)
 }

 plistPath := filepath.Join("/Library/LaunchDaemons", ServiceName+".plist")
 content := fmt.Sprintf(plistTemplate, ServiceName, installedBinary, installDir)

 if err := os.WriteFile(plistPath, []byte(content), 0644); err != nil {
  return fmt.Errorf("failed to write plist file: %w", err)
 }

 if err := exec.Command("launchctl", "load", plistPath).Run(); err != nil {
  return fmt.Errorf("failed to load service: %w", err)
 }
 return nil
}

func (s *darwinService) Uninstall() error {
 plistPath := filepath.Join("/Library/LaunchDaemons", ServiceName+".plist")

 if err := exec.Command("launchctl", "unload", plistPath).Run(); err != nil {
  return fmt.Errorf("failed to unload service: %w", err)
 }

 if err := os.Remove(plistPath); err != nil {
  return fmt.Errorf("failed to remove plist file: %w", err)
 }
 return nil
}

func (s *darwinService) Status() (bool, error) {
 err := exec.Command("launchctl", "list", ServiceName).Run()
 return err == nil, nil
}

func (s *darwinService) Start() error {
 if err := exec.Command("launchctl", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *darwinService) Stop() error {
 if err := exec.Command("launchctl", "stop", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 return nil
}

?? ?? ??

??? ??(??/??? ?? ??):

package platform

import (
 "fmt"
 "os"
 "os/exec"
 "path/filepath"
)

type linuxService struct{}

const systemdServiceTemplate = `[Unit]
Description=%s

[Service]
ExecStart=%s -run
Restart=always
User=root
WorkingDirectory=%s

[Install]
WantedBy=multi-user.target
`

func (s *linuxService) Install(execPath string) error {
 installDir := GetInstallDir()
 if err := os.MkdirAll(installDir, 0755); err != nil {
  return fmt.Errorf("failed to create installation directory: %w", err)
 }

 installedBinary := filepath.Join(installDir, "bin", filepath.Base(execPath))
 if err := os.MkdirAll(filepath.Dir(installedBinary), 0755); err != nil {
  return fmt.Errorf("failed to create bin directory: %w", err)
 }

 if err := copyFile(execPath, installedBinary); err != nil {
  return fmt.Errorf("failed to copy binary: %w", err)
 }

 servicePath := filepath.Join("/etc/systemd/system", ServiceName+".service")
 content := fmt.Sprintf(systemdServiceTemplate, ServiceDesc, installedBinary, installDir)

 if err := os.WriteFile(servicePath, []byte(content), 0644); err != nil {
  return fmt.Errorf("failed to write service file: %w", err)
 }

 commands := [][]string{
  {"systemctl", "daemon-reload"},
  {"systemctl", "enable", ServiceName},
  {"systemctl", "start", ServiceName},
 }

 for _, args := range commands {
  if err := exec.Command(args[0], args[1:]...).Run(); err != nil {
   return fmt.Errorf("failed to execute %s: %w", args[0], err)
  }
 }
 return nil
}

func (s *linuxService) Uninstall() error {
 _ = exec.Command("systemctl", "stop", ServiceName).Run()
 _ = exec.Command("systemctl", "disable", ServiceName).Run()

 servicePath := filepath.Join("/etc/systemd/system", ServiceName+".service")
 if err := os.Remove(servicePath); err != nil {
  return fmt.Errorf("failed to remove service file: %w", err)
 }
 return nil
}

func (s *linuxService) Status() (bool, error) {
 output, err := exec.Command("systemctl", "is-active", ServiceName).Output()
 if err != nil {
  return false, nil
 }
 return string(output) == "active\n", nil
}

func (s *linuxService) Start() error {
 if err := exec.Command("systemctl", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *linuxService) Stop() error {
 if err := exec.Command("systemctl", "stop", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 return nil
}

???? ?? ??:

package platform

import (
 "fmt"
 "os"
 "os/exec"
 "path/filepath"
 "strings"
)

type windowsService struct{}

func (s *windowsService) Install(execPath string) error {
 installDir := GetInstallDir()
 if err := os.MkdirAll(installDir, 0755); err != nil {
  return fmt.Errorf("failed to create installation directory: %w", err)
 }

 installedBinary := filepath.Join(installDir, "bin", filepath.Base(execPath))
 if err := os.MkdirAll(filepath.Dir(installedBinary), 0755); err != nil {
  return fmt.Errorf("failed to create bin directory: %w", err)
 }

 if err := copyFile(execPath, installedBinary); err != nil {
  return fmt.Errorf("failed to copy binary: %w", err)
 }

 cmd := exec.Command("sc", "create", ServiceName,
  "binPath=", fmt.Sprintf("\"%s\" -run", installedBinary),
  "DisplayName=", ServiceDisplay,
  "start=", "auto",
  "obj=", "LocalSystem")

 if err := cmd.Run(); err != nil {
  return fmt.Errorf("failed to create service: %w", err)
 }

 descCmd := exec.Command("sc", "description", ServiceName, ServiceDesc)
 if err := descCmd.Run(); err != nil {
  return fmt.Errorf("failed to set service description: %w", err)
 }

 if err := exec.Command("sc", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *windowsService) Uninstall() error {
 _ = exec.Command("sc", "stop", ServiceName).Run()
 if err := exec.Command("sc", "delete", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to delete service: %w", err)
 }

 // Clean up installation directory
 installDir := GetInstallDir()
 if err := os.RemoveAll(installDir); err != nil {
  return fmt.Errorf("failed to remove installation directory: %w", err)
 }
 return nil
}
func (s *windowsService) Status() (bool, error) {
 output, err := exec.Command("sc", "query", ServiceName).Output()
 if err != nil {
  return false, nil
 }
 return strings.Contains(string(output), "RUNNING"), nil
}

func (s *windowsService) Start() error {
 if err := exec.Command("sc", "start", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }
 return nil
}

func (s *windowsService) Stop() error {
 if err := exec.Command("sc", "stop", ServiceName).Run(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 return nil
}

??? ??? ??:

package main

import (
 "context"
 "flag"
 "fmt"
 "log"
 "os"
 "os/signal"
 "syscall"
 "time"

 "go-service/internal/platform"
 "go-service/internal/service"
)

func main() {
 log.SetFlags(log.LstdFlags | log.Lmicroseconds)

 install := flag.Bool("install", false, "Install the service")
 uninstall := flag.Bool("uninstall", false, "Uninstall the service")
 status := flag.Bool("status", false, "Check service status")
 start := flag.Bool("start", false, "Start the service")
 stop := flag.Bool("stop", false, "Stop the service")
 runWorker := flag.Bool("run", false, "Run the service worker")
 flag.Parse()

 if err := handleCommand(*install, *uninstall, *status, *start, *stop, *runWorker); err != nil {
  log.Fatal(err)
 }
}

func handleCommand(install, uninstall, status, start, stop, runWorker bool) error {
 platformSvc, err := platform.NewService()
 if err != nil {
  return err
 }

 execPath, err := os.Executable()
 if err != nil {
  return fmt.Errorf("failed to get executable path: %w", err)
 }

 switch {
 case install:
  return platformSvc.Install(execPath)
 case uninstall:
  return platformSvc.Uninstall()
 case status:
  running, err := platformSvc.Status()
  if err != nil {
   return err
  }
  fmt.Printf("Service is %s\n", map[bool]string{true: "running", false: "stopped"}[running])
  return nil
 case start:
  return platformSvc.Start()
 case stop:
  return platformSvc.Stop()
 case runWorker:
  return runService()
 default:
  return fmt.Errorf("no command specified")
 }
}

func runService() error {
 svc, err := service.New()
 if err != nil {
  return fmt.Errorf("failed to create service: %w", err)
 }

 ctx, cancel := context.WithCancel(context.Background())
 defer cancel()

 sigChan := make(chan os.Signal, 1)
 signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

 log.Println("Starting service...")
 if err := svc.Start(ctx); err != nil {
  return fmt.Errorf("failed to start service: %w", err)
 }

 log.Println("Service started, waiting for shutdown signal...")
 <-sigChan
 log.Println("Shutdown signal received, stopping service...")

 if err := svc.Stop(); err != nil {
  return fmt.Errorf("failed to stop service: %w", err)
 }
 log.Println("Service stopped successfully")
 return nil
}

?? ??? ?? ?? ??:

GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o go-service.exe ./cmd/service

??

? ???? ?? ??? ??? Go?? ?? ????? ???? ???? ??? ??? ???? ?? ? ????. ? ???? ?? ??? ?? ??? ???? ??? main.go ??? ???? ?? ??? ????.

?? ??? GitHub? Go ??? ???? ?????.

? ??? Go?? ??? ??? ??? ??? ??: ??? ???? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? ????? ??
? ?? ??? ????? ???? ??? ??????, ???? ?????? ????. ? ???? ?? ???? ?? ??? ?? ????. ???? ??? ???? ???? ??? ?? admin@php.cn?? ?????.

? AI ??

Undresser.AI Undress

Undresser.AI Undress

???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover

AI Clothes Remover

???? ?? ???? ??? AI ?????.

Video Face Swap

Video Face Swap

??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

???

??? ??

???++7.3.1

???++7.3.1

???? ?? ?? ?? ???

SublimeText3 ??? ??

SublimeText3 ??? ??

??? ??, ???? ?? ????.

???? 13.0.1 ???

???? 13.0.1 ???

??? PHP ?? ?? ??

???? CS6

???? CS6

??? ? ?? ??

SublimeText3 Mac ??

SublimeText3 Mac ??

? ??? ?? ?? ?????(SublimeText3)

???

??? ??

??? ????
1600
29
PHP ????
1502
276
???
Golang Frontend ?? ?????? Golang Frontend ?? ?????? Jul 08, 2025 am 01:44 AM

Golang? ?? ??? ??? ????? ??? ?? ???? ??? ? ??? ? ?? ????. ?? ??? ???, ?? ?? ? ??? ?? ?????? ????? API ??, ???? ???, ?? ???, ?????? ?? ? CLI ??? ?? ??? ?? ????? ???? ? ?????. Golang? ? ??? ??? ?? ??? ???? Gopherjs? ?? JavaScript? ?????? Tinygo? ?? WebAssembly?? ????? ??? ?? ??? ???? ?? ??? ???? HTML ???? ?? ? ? ????. ??? ???? ??? ?? ??? ??? ??JavaScript/TypeScript ? ???? ???????. ??? Golang? ??? ???? ???? ?? ?? ??? ? ?????.

GO? ???? ?? GO? ???? ?? Jul 09, 2025 am 02:37 AM

GO? ???? ?? ??? ??? ???? ?? ??? ???? ??? ???? ????. 1. ?? ???? ?? ???? ??????? ?? ? ???? ??????. Windows? .msi ??? ???? MacOS? .pkg ??? ???? Linux? .tar.gz ??? ???? /usr /local ????? ??? ????. 2. Linux/MacOS?? ?? ??, ?? ~/.bashrc ?? ~/.zshrc? ???? ??? Gopath? ???? Windows Set ??? ??? ???? ?????. 3. ?? ??? ???? ??? ???? ??? ???? Hello.Go? ???? ?? ? ??? ???? ??????. ???? ???? ?? ?? ? ??

Golang?? GraphQL API? ???? ?? Golang?? GraphQL API? ???? ?? Jul 08, 2025 am 01:03 AM

GO?? GraphQlapi? ????? GQLGEN ?????? ???? ?? ???? ????? ?? ????. 1. ?? ???? ???? ?? ?? ??? ???? GQLGEN? ?? ??? ?????? ??????. 2. ?? ?? GraphQLSchema? ???? POST ?? ? ?? ??? ??? ?? API ?? ? ?? ??? ??????. 3. ?? ?? ????? ????? ?? ??? ???? Resolver?? ???? ??? ?????. 4. ????? ??? Qlhandler? httpserver? ???? ?? ???? ?? API? ???????. ?? ?? ?? ??, ?? ??, ?? ??? ? ?? ??? ???? ???? ?? ??? ?????.

go sync.waitgroup ?? go sync.waitgroup ?? Jul 09, 2025 am 01:48 AM

sync.waitgroup? ?? ? ??? ??? ?? ? ??? ???? ? ?????. ??? ??? ? ?? ??? ?? ?? ??? ???? : ??, ?? ? ??. 1. Aadd (n) ?? ? ?? ? ?? ?????. 2. DONE ()? ? ? ??? ??? ???? ???? 1 ? ?? ???. 3. Wait ()? ?? ??? ?? ? ??? ?? ? ??? ?????. ?? ??? ?? ?? ?? : ADD? ?? ? ???? ????????. ?? ??? ??? DON? ????? ??????. ??? ?? ???? ?? ????. ? ???? ?? ???, ?? ??? ?? ? ?? ?????? ????? ??? ????? ????? ?? ? ? ????.

?? ????? ?????? ?? ????? ?????? Jul 09, 2025 am 02:46 AM

Go? Embed ???? ???? ? ???? ??? HTML, CSS, ?? ? ?? ??? ???? ? ??? ?? ???? ????? ?? ???? ? ????. 1. ?? ? ???? ????? ??????. 2. ??/*? ?? ?? ????? ??? ? ??? embed.fs? ?? ?? ?? ??? ??? ? ????. 3. ?? ?? ?? ?? ??? ?? ??? ?? ??? ???? ???? ????? ?? ????. 4. ???? ???? ?? ???, ?? ?? ?? ? ?? ?? ?????????. Embed? ???? ??? ??? ????? ???? ??? ??? ? ? ????.

???/??? ??? ?????? ???/??? ??? ?????? Jul 20, 2025 am 04:14 AM

??? ? ??? ??? ??? ?? ???? ? ??? ??? ???? ? ????. 1. ?? ?????? ??, ???, ??, ??? ? ??? ???? ? ???? ??? ? ???? ????. 2. ??? ? ??? ??, ?? ??, ??? ???, ??? ?? ?? ?? ???? ??? ?? ??, ?? ???, ??? ?? ??, ?? ?? ?? ?? ?? ??? ? ????. 3. FFMPEG, OPENCV, WEBRTC, GSTREAMER ? ?? ??? ???? ??? ???? ?? ????. 4. ?? ?? ???? ???? ??, ???? ??? ??? ?? ??, ?? ??? ? ??? ?? ?????? ???????. ??? ?? ???? ????? ?? ???? ??? ??? ????? ? ??????.

?? ?? ? ??? ???? ?? ?? ?? ? ??? ???? ?? Jul 15, 2025 am 03:05 AM

?? ?? ??? ? ??? ???? ?? ??? ????. ??? Net/HTTP ???? ???? ?? ???? ???? ? ????. 1. net/http? ???? ?? ??? ??? ??????. ?? ?? ??? ???? ? ?? ??? ?? ??? ????. 2. ??? ?? : Servemux? ???? ?? ??? ? ??? ?? ?? ????? ??? ?????. 3. ???? ?? : ?? ?? ? ?? ??? ? ?? ?????? ???? ??? ??? ?????. 4. ?? ?? ??? : http.fileserver? ?? HTML, CSS ? JS ??? ?????. 5. ?? ? ?? : HTTPS ???, ?? ??? ??? ???? ?? ? ??? ????? ?? ?? ??? ?????. ??? ?? ???? ????? ??? ???? ?? ? ?? ????.

?? ???? ?????? ?? ???? ?????? Jul 14, 2025 am 02:54 AM

Select Plus Default? ??? ?? ??? ???? ??? ?? ????? ??? ? Select? ?? ??? ????? ???? ????. 1. ???? ?? ???? ???? ?? ? ? ??? ?? ??? ?? ??? ?? ?????. 2. ??? ??. ?? ?? ?? ????? ???? ?????. ??? ?? ?? ???? ?? ?? ????. 3. ?? ??? ????, ??? ?? ??? ???? ?? ?? ????? ???? ???????. ?? ??? ?? ?? ??? ?? ???? ?? ? ? ??? ?? ? ??? ?? ????? ??? ???? ????.

See all articles