{"id":873,"date":"2015-08-24T13:15:46","date_gmt":"2015-08-24T19:15:46","guid":{"rendered":"http:\/\/islascruz.org\/blog\/?page_id=873"},"modified":"2017-07-11T13:55:23","modified_gmt":"2017-07-11T13:55:23","slug":"win32services","status":"publish","type":"page","link":"https:\/\/islascruz.org\/blog\/win32services\/","title":{"rendered":"How to make Win32Services"},"content":{"rendered":"<p>[adinserter block=&#8221;2&#8243;]<br \/>\n<img decoding=\"async\" src=\"http:\/\/islascruz.org\/html\/data\/files\/python-logo-glassy.png\" alt=\"\" align=\"right\" \/>Hi, in this case I&#8217;m going to show you how to create simple services for the win32 platform using the powerfull Python programming language and the py2exe utility.<\/p>\n<p>Writing Python applications under windows is quite simple, maybe you didn&#8217;t use windows to develop your application (as I do most times), the code, what you want to do with your application is up to you, and I&#8217;m not goint to touch the programming techniques for developing windows applications, Just, create a simple -and useles- win32 service that will help you to uderstand how to create your very own windows service.<\/p>\n<p>First, every single program that you create with python and compile with py2exe and does run well, may be a win32 service, it may be a program that fetches the <a href=\"http:\/\/feeds2.feedburner.com\/islascruz\/general?format=xml\" target=\"_blank\" rel=\"noopener\">RSS xml feed<\/a> for <a href=\"http:\/\/www.islascruz.org\">islascruz.org<\/a>, maybe is a more complex program to generate some files and then send them to another server, maybe is a simple program to remind you to sand up an walk 10 minutes.<\/p>\n<p>Said that we don&#8217;t really need to create a program thinking on it as a service, we will create a simple program and test it using the python interpreter, who needs to compile?, well, we need it, but just when we are sure that our program performs well.<\/p>\n<pre class=\"lang:python decode:1 \">#!\/usr\/bin\/env python\nimport time\nimport thread\nimport os\nimport sys\n\nclass service_test:\n    def __init__(self):\n        thread.start_new(self.do_something, tuple())\n        while True:\n            if getattr(sys,'stopservice', False):\n                sys.exit()\n            time.sleep(0.3)\n\n    def do_something(self):\n        '''\n        Do something\n        '''\n        while True:\n            fname ='C:\\\\\\\\test.txt'\n            f = open(fname , 'a')\n            f.write(time.time())\n            f.close()\n            time.sleep(1)\n\n\nif __name__ == \"__main__\":\n    tst = service_test()\n\n<\/pre>\n<p>Now that we have this program running in our windows environment, we can start thinking in converting into a service. First, I don&#8217;t know you, but I haven&#8217;t make Windows to load a python script and run it as a service. This is because Win32 use it&#8217;s own method to start\/stop the services. Then, we will need to create a wrapper for our program, this wrapper will interface with the windows service mananger. Doing it is quite simple, lets see it.<\/p>\n<pre class=\"lang:python decode:1 \">\nimport win32serviceutil\nimport win32service\nimport win32event\nimport os\nimport sys\nimport time\n\nsys.stopservice = \"false\"\n\ndef main():\n    '''\n    Modulo principal para windows\n    '''\n    sys.path.insert(0,os.getcwd())\n    import service_module\n    a = service_module.service_test()\n\nclass ServiceLauncher(win32serviceutil.ServiceFramework):\n    _svc_name_ = 'ServiceTest'\n    _scv_display_name_ ='Servicio de pruebas'\n    def __init__(self, args):\n        win32serviceutil.ServiceFramework.__init__(self, args)\n        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)\n\n    def SvcStop(self):\n        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)\n        sys.stopservice = \"true\"\n        win32event.SetEvent(self.hWaitStop)\n\n    def SvcDoRun(self):\n        main()\n<\/pre>\n<p>[adinserter block=&#8221;2&#8243;]<\/p>\n<p>As you can see in this piece of code, we have a class called ServiceLauncher, actually it doesn&#8217;t really matter if you name it as you want, but, we need some variables that starts with &#8220;<em>svc<\/em>&#8221; and the important is _svc_name, this variable should have the name of our service, the very same name of the executable that we are going to compile. The <strong>init<\/strong> method initialize our service.<\/p>\n<p>Then, we have two methods. one SvcStop, this method will be called when we want to stop the service in the service mananger. As our program is not running here, is safe to communicate with it by some method, I use a variable stored in &#8220;sys&#8221; which is &#8220;pooled&#8221; on the main program to know when it&#8217;s time to stop the program.<\/p>\n<p>THe method SvcDoRun is quite explicit, it starts the program. Now, you guess that when you start your service must be doing something, even sleeping, because, if it stops, then an error message will be saved in the Windows logs.<\/p>\n<p>Ok, we have our program and our wrapper class, but, did I said that Windows cannot load a python scritp as a service?. Well, we need to compile it. here is when <a href=\"http:\/\/www.py2exe.org\" target=\"_blank\" rel=\"noopener\">py2exe<\/a> comes in.<\/p>\n<p>Py2Exe will help us to convert those scripts in a binary for windows, a simple binary for execution or a Windows service :-D. I use this script to create my windows services, py2exe makes use of the distutils and hence a setup.py script must be used to compile the our scripts. check the next code that will help you to create console programs and win32 services.<\/p>\n<p>[adinserter block=&#8221;2&#8243;]<\/p>\n<pre class=\"lang:python decode:1 \">import sys\nbuildservice = True\nif '--no-service' in sys.argv[1:]:\n    buildservice = False\n    sys.argv = [k for k in sys.argv if k != '--no-service']\n    print sys.argv\n\nfrom distutils.core import setup\nimport os\nimport py2exe\nimport glob\nimport shutil\n\nsys.path.insert(0,os.getcwd())\n\ndef getFiles(dir):\n    \"\"\"\n    Retorna una tupla de tuplas del directorio\n    \"\"\"\n    # dig looking for files\n    a= os.walk(dir)\n    b = True\n    filenames = []\n\n    while (b):\n        try:\n            (dirpath, dirnames, files) = a.next()\n            filenames.append([dirpath, tuple(files)])\n        except:\n            b = False\n    return filenames\n\nDESCRIPTION = 'Servicio de pruebas'\nNAME = 'servicetest'\n\n\nclass Target:\n    def __init__(self,**kw):\n            self.__dict__.update(kw)\n            self.version        = \"1.00.00\"\n            self.compay_name    = \"islascruz.org\"\n            self.copyright      = \"(c) 2009, Marco Islas\"\n            self.name           = NAME\n            self.description    = DESCRIPTION\n\nmy_com_server_target = Target(\n        description    = DESCRIPTION,\n        service = [\"service_module\"],\n        modules = [\"service_module\"],\n        create_exe = True,\n        create_dll = True)\n\nif not buildservice:\n    print 'Compilando como ejecutable de windows...'\n    setup(\n        name = NAME ,\n        description = DESCRIPTION,\n        version = '1.00.00',\n        console = ['service_module.py'],\n        zipfile=None,\n        options = {\n                \"py2exe\":{\"packages\":\"encodings\",\n                    \"includes\":\"win32com,win32service,win32serviceutil,win32event\",\n                    \"optimize\": '2'\n                    },\n                },\n    )\nelse:\n    print 'Compilando como servicio de windows...'\n    setup(\n        name = NAME,\n        description = DESCRIPTION,\n        version = '1.00.00',\n        service = [{'modules':[\"ServiceLauncher\"], 'cmdline':'pywin32'}],\n        zipfile=None,\n        options = {\n                \"py2exe\":{\"packages\":\"encodings\",\n                    \"includes\":\"win32com,win32service,win32serviceutil,win32event\",\n                    \"optimize\": '2'\n                    },\n                },\n    )\n<\/pre>\n<p>Maybe you want to read the distutils documentation to understand it. Once you have your binary, you can use it to install it on the win32 services list, just run your program with the &#8220;-install&#8221; parameter and you are done!.<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_873\" class=\"pvc_stats all  \" data-element-id=\"873\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/islascruz.org\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>[adinserter block=&#8221;2&#8243;] Hi, in this case I&#8217;m going to show you how to create simple services for the win32 platform using the powerfull Python programming language and the py2exe utility. Writing Python applications under windows is quite simple, maybe you didn&#8217;t use windows to develop your application (as I do most times), the code, what [&hellip;]<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_873\" class=\"pvc_stats all  \" data-element-id=\"873\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/islascruz.org\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":1267,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-873","page","type-page","status-publish","has-post-thumbnail","hentry"],"brizy_media":[],"_links":{"self":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/pages\/873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/comments?post=873"}],"version-history":[{"count":8,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/pages\/873\/revisions"}],"predecessor-version":[{"id":4182,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/pages\/873\/revisions\/4182"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/media\/1267"}],"wp:attachment":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/media?parent=873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}