My 1th usable Golang applet

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.
    1. Why do you write this program?

    2. Find time Synchronization API

    3. Writing a synchronization program

    4. Encapsulated as a Windows service

  1. Why do you write this program?

    has been concerned about the Golang, from the April 2011 configuration environment wrote a Hello world! (Http://weibo.com/1409046677/wr4n3vdYFV), and then did not write Golang code, just focus on golang information/information. Last year to a little more serious to see some Golang basic grammar, and then a few days ago, the desktop computer was turned on for a bit, it may be the BIOS battery is not power, it always need to reset the time after the boot. So it is better to use Golang write a Windows service automatically update the system time, so that the Golang applet today.

    Another person might say that using Windows Time synchronization is OK, no need to bother. Here my main purpose is to make a sudden interest to use Golang practiced hand, followed by Windows comes with the time synchronization feature may not work because of the wall, anyway, I have not succeeded in manual synchronization,

  2. Find time Synchronization API

    When searching for information, I learned that the network time Protocol (NTP) (http://baike.baidu.com/view/60648.htm) can be very accurate synchronization, I do not want to be so high requirements, just get the latest time, update time on the line, So you have to find a usable online can get the latest time API, began to worry about the wall, looking for domestic, Baidu has a http://open.baidu.com/special/time/, but a page, not what I want, and finally determine the use of foreign HTTP// www.earthtools.org/timezone-1.1/35.86166/104.195397

  3. Writing a synchronization program

    Quite simple a small program, the idea is to get the API data, take the time, and then set to the system time, because is not familiar with the Golang API, do not know how to use Golang to update the system time, and then use Golang call DOS command to update.

    When writing code, it is clear that in Golang, the case of the public and private, but in the definition of timezone structure, the variables used in lowercase, resulting in always get the correct data, tossing a lot of time. In addition, it took some time to find information for iso-8859-1 coding.

  4. Encapsulated as a Windows service

    About writing Windows service, start searching for data http://sanatgersappa.blogspot.com/2013/07/windows-service-with-go-easy-way.html (need to flip the wall ), feel NSSM (http://nssm.cc/) is very convenient, consider using NSSM program, using NSSM to register EXE program as a Windows service, command:

    NSSM Install MyService D:\MyService.exe
    (where D:\MyService.exe is the full path to the EXE file).

    I wrote 2 batch programs Createservice.bat:
    NSSM Install Syncsystemtimeservice%cd%\syncsystemtim.exe

    Deleteservice.bat:
    SC Delete Syncsystemtimeservice

    Windows Service registration is successful, after starting the Syncsystemtimeservice service, my program does not seem to take effect, I suspect that either must use the full path (cannot use the%cd% variable), or may use%~dp0 instead of%cd% (reference: http:/ /stackoverflow.com/questions/16255184/ How-do-i-find-the-current-directory-of-a-batch-file-and-then-use-it-for-the-pat), and then I did not continue to investigate the reason, Found on the Internet a service program written using Golang: Http://bitbucket.org/kardianos/service, pull the code down, adjust it to meet the requirements I want.

    Enclose the complete code:

    Config.txt:

    10s



    Syncsystemtime.go

    package mainimport  (   "Bitbucket.org/kardianos/service"    "bitbucket.org/ Kardianos/osext "  " Encoding/xml "  " errors "  " FMT "  " io "  " io /ioutil "  " net/http "  " OS "  " os/exec "  " Time "var log  Service. Loggerfunc main ()  {  var name =  "Syncsystemtimeservice"   var  displayName =  "Sync system time service"   var desc =  " Synchronize Update window Time service (get latest time over network) "  var s, err = service. NewService (NAME,&NBSP;DISPLAYNAME,&NBSP;DESC)   log = s  if err !=  nil {    fmt. Printf ("%s unable to start: %s",  displayname, err)     return   }  if len (OS. Args)  > 1 {    var err error    verb := os. args[1]    switch verb {      case  "Install":         err = s.install ()          if err != nil {           fmt. Printf ("failed to install: %s\n",  err)            return        }         fmt. Printf ("service \"%s\ " installed.\n",  displayname)       case   "Remove":         err = s.remove ()          if err != nil {           fmt. Printf ("failed to remove: %s\n",  err)           return        }         fmt. Printf ("service \"%s\ " removed.\n",  displayname)       case  " Run ":         dowork ()       case " Start ":         err = s.start ()          if err != nil {           fmt. Printf ("failed to start: %s\n",  err)            return        }         Fmt. Printf ("service \"%s\ " started.\n",  displayname)       case  " Stop ":         err&nbsP;= s.stop ()         if err != nil {           fmt. Printf ("failed to stop: %s\n",  err)            return        }         Fmt. Printf ("service \"%s\ " stopped.\n",  displayname)     }     return  }  err = s.run (func ()  error {    go  dowork ()     return nil  }, func ()  error {     stopwork ()     return nil  })   if err !=  nil {    s.error (Err. Error ())   }}func dowork ()  {  log. Info ("I ' m running!")   const defaultschedulingtime =  "30m"  // minutes  schedulingTime := defaultSchedulingTime   configFile :=  "Config.txt"   configpath, err := osext. Executablefolder ()   if err != nil {    log. Warning (Err. Error ())   } else {    configFile = configPath +  Configfile  }  log. Info (configfile)   timeconfig, err := ioutil. ReadFile (configfile)   if err == nil {    schedulingtime  = string (Timeconfig)   } else {    log. Warning (Err. Error ())   }  timeduration, err := time. Parseduration (Schedulingtime)   if err != nil {    log. Warning (Err. Error ())     timeduration, err = time. ParseduratiOn (Defaultschedulingtime)   }  go ()   timer := time. Newticker (timeduration)   for {    select {       case <-timer. C:      go ()     }  }  select {}} Func stopwork ()  {  log. Info ("I ' m stopping!")} Func go ()  {  networktime := getnetworktime ()   setsystemtime ( Networktime)}/**1.035.86166104.1953978h21 apr 2014 23:08:092014-04-21 23:08:09 + 08002014-04-21 15:08:09unknown*/type timezone struct {  localtime string   ' xml: "localtime" '   IsoTime string  ' xml: "Isotime" '   utctime string   ' xml: "Utctime" '}func charsetreader (Charset string, r io. Reader)   (IO. Reader, error)  {  if charset ==  "iso-8859-1 " | |  charset ==  "Iso-8859-1" &NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;RETURN&NBSP;R,&NBSP;NIL&NBSP;&NBSP;}   return nil, errors. New ("unsupported character set encoding: "  + charset)}func GetNetworkTime ()  string {  const web_service_url =  "HTTP://WWW.EARTHTOOLS.ORG/TIMEZONE-1.1/ 35.86166/104.195397 "  result, err1 := http. Get (Web_service_url)   if err1 != nil {    log. Warning (ERR1. Error ())     return  ""   }  defer result. Body.close ()   var timezone timezone  data := xml. Newdecoder (result. Body)   data. Charsetreader = charsetreader  if err := data. Decode (&timezone); err != nil {    return  "" &NBSP;&NBSP;}   // fmt. Println (timezone.Utctime)   return timezone. Utctime}func setsystemtime (datetime string)  {  if dateTime ==  ""   {    return  }  currenttime := time. Now (). Format ("2006-01-02 15:04:05")   logcontent := currenttime  converttime,  err1 := time. Parse ("2006-01-02 15:04:05",  datetime)   if err1 != nil {     log. Warning (ERR1. Error ())     return  }  converttime = converttime.add (8  * time. Hour)   logContent = logContent +  " --> "  +  Converttime.format ("2006-01-02 15:04:05")   comparevalue := converttime.format (" 2006-01-02 15:04:05 ")   //  if the time (month and day) is the same, the   if currenttime[0:len is not updated ( currenttime) -3] == comparevalue[0:len (comparevalue)-3] {    log. Info ("same time, not to update: "  + currentTime +  " | "  + comparevalue)     return  }  _, err2 :=  Exec. Command ("CMD",  "/C",  "DATE",  converttime.format ("2006-01-02")). Output ()   if err2 != nil {    log. Error (ERR2. Error ())   }  _, err2 = exec. Command ("CMD",  "/C",  "Time",  converttime.format ("15:04:05")). Output ()   if err2 != nil {    log. Error (ERR2. Error ())   }  currenttime = time. Now (). Format ("2006-01-02 15:04:05")   logContent = logContent +  " -->   " + currenttime  log. Info (logcontent)   // writelogfile (logcontent)}/*func writelogfile (logContent string) & nbsp;error {  filename :=  "Log.txt"   file, err := os. OpenFile (Filename, os. O_rdwr|os. O_create|os. o_append, 0666)   if err != nil {    log. Fatal ("Error opening file: %v",  err)     return err  }   defer file. Close ()   log. Setoutput (file)   log. Println (logcontent)   return nil}*/
  5. BTW: Because log print logs can be seen in the Windows Event Viewer, I commented out the Writelogfile function.

    Small programs, small features, please tap, welcome criticism.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.