• Login
Community
  • Login

Update installed Plugins via script/cmd

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
pluginsplugin managerscriptplugin-admincommand line
15 Posts 5 Posters 5.1k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E
    Eddga
    last edited by Feb 22, 2019, 2:30 PM

    Dear Notepad++ Community,

    Dunno if this is the right place to ask for this. But anyway:
    I’m currently looking for a way to update all plugins that are currently installed in Notepad++ with a script.
    I’m an IT admin and we have multiple Notepad++ users who also depend on several plugins.
    I’d like to have a way updating their plugins without having to access their PCs or granting them the necessary rights.
    Something like deploying a script or command line that would trigger the Plugins Admin to update all installed plugins maybe would be the most elegant way. But I couldn’t find any information regarding such a purpose.

    Thanks for your help guys.
    Kind regards
    Eddga

    1 Reply Last reply Reply Quote 1
    • P
      PeterJones
      last edited by Feb 22, 2019, 2:47 PM

      @Eddga ,

      Welcome to the Community.

      I do not know of such a feature, though it seems a reasonable feature for deploying in an enterprise environment. This FAQ explains how to make a feature request that the developer will see (unfortunately, it’s not here).

      1 Reply Last reply Reply Quote 2
      • A
        Alan Kilborn
        last edited by Feb 22, 2019, 2:51 PM

        Why is everybody so in love with this type of method of updating? Sounds like an awesome way to break a bunch of functionality with buggy new things…

        1 Reply Last reply Reply Quote 2
        • P
          PeterJones
          last edited by Feb 22, 2019, 3:19 PM

          From what I’ve heard, I.T. departments like automating and scripting updates as much as possible, because they have to deal with so many machines. For mere mortals like me, who only ever has to take care of his home pc and try to prevent ever needing to deal with I.T. on his work pc, it seems overkill… But I think if your job involves updating dozens of applications on hundreds of PCs, being able to automate is useful. :-)

          1 Reply Last reply Reply Quote 3
          • A
            Alan Kilborn
            last edited by Alan Kilborn Feb 22, 2019, 3:41 PM Feb 22, 2019, 3:39 PM

            I understand that part. The part that I don’t understand is the “if it ain’t broke why fix it part”. Notepad++ has demonstrated time and time again that it is not tested well (IMO, but if it is not your opinion, do you remember Plugins Admin, encoding detection, etc etc), thus for people that don’t have time to “play” with it (I guess the peoples that do is us !), all the updating is just going to lead to frustration. You heard it here first. :)

            1 Reply Last reply Reply Quote 3
            • P
              PeterJones
              last edited by Feb 22, 2019, 4:11 PM

              Well, I would hope that anyone in an IT department who didn’t want users to have permission to upgrade their own plugins would vet the various plugins before forcing the upgrade on users. That may be optimistic on my part. :-)

              1 Reply Last reply Reply Quote 3
              • E
                Eddga
                last edited by Feb 28, 2019, 8:58 AM

                Thanks for your fast answers and the input.
                @PeterJones I’ll give the feature request a try. :)
                @Alan-Kilborn I really get and support your “never change a running system” point. Thing is that our users always get notifications for newer versions being available and they also want the newest version. I’d also say that (in general [and I’m not really familiar with how much this applies for np++ or its plugins]) most of the time updates are more about fixing security issues than fixing broken parts of the program.

                M 1 Reply Last reply Feb 28, 2019, 9:19 AM Reply Quote 3
                • M
                  Meta Chuh moderator @Eddga
                  last edited by Feb 28, 2019, 9:19 AM

                  @Eddga

                  i currently deploy plugin updates like this (notepad++ v7.6.3, 32 bit, default installation, semi automatic deployment):

                  first i update all plugins manually on one admin machine.
                  then i make a copy of %ProgramFiles(x86)%\Notepad++\plugins\ to a network drive, reachable by all user pc’s.
                  (it will be %ProgramFiles%\Notepad++\plugins\ if you use the x64 version on all systems)
                  then i deploy them with a batch script that is started on all machines at startup, via scheduled tasks (schtasks), using either the system account or an admin account, in order to have permissions to write to %ProgramFiles(x86%).
                  this startup batch script just copies all files from \\Servername_or_ip\Updates\Notepad++\plugins\ to %ProgramFiles%\Notepad++\plugins\ on each machine.

                  please report back, if you can use, refine or simplify this way of deploying plugins.

                  1 Reply Last reply Reply Quote 3
                  • E
                    Eddga
                    last edited by Feb 28, 2019, 9:42 AM

                    @Meta-Chuh thanks for the answer!
                    Actually that’s the exact way I’m working this around at the moment. Only that we are using DeskCenter as deployment software and I’m doing it via this one. But that doesn’t seem to be a really convenient way to me. I mean, sure it works and may be the way to do it for now, but it still takes some additional minutes of my time and also needs me to check for updates myself every now and then. I guess I’ll do the feature request and meanwhile use the existing workaround.

                    M 1 Reply Last reply Feb 28, 2019, 10:02 AM Reply Quote 2
                    • M
                      Meta Chuh moderator @Eddga
                      last edited by Meta Chuh Feb 28, 2019, 10:03 AM Feb 28, 2019, 10:02 AM

                      @Eddga

                      but it still takes some additional minutes of my time and also needs me to check for updates myself every now and then

                      yes, same for me, that’s why i wrote semi automatic.

                      to make it automatic, we could parse the json live plugin lists from here:
                      notepad++ latest plugin list (x86): https://raw.githubusercontent.com/notepad-plus-plus/nppPluginList/master/src/pl.x86.json
                      notepad++ latest plugin list (x64): https://raw.githubusercontent.com/notepad-plus-plus/nppPluginList/master/src/pl.x64.json

                      automatically downloading and extracting the needed plugins from the given urls inside the list into our deployment network drive.
                      then deploy them at the startup scripts with e.g. cwrsync or robocopy, in order that they will only be copied if anything has changed.

                      unfortunately i didn’t write this for myself yet.
                      i wanted to implement that already, but i didn’t have time (and/or drive) to do so for now.

                      E 1 Reply Last reply Feb 28, 2019, 5:25 PM Reply Quote 2
                      • E
                        Ekopalypse @Meta Chuh
                        last edited by Feb 28, 2019, 5:25 PM

                        @Meta-Chuh

                        Just in case that this might be helpful to you (or whomever),
                        here a python script which does more or less what you want it to do.
                        Changes needs to be done in main function.
                        For the first time run it downloads everything and creates the two needed local json files,
                        which will be used to compare with the web json files in future runs.

                        import urllib
                        import urllib2
                        import os
                        from zipfile import ZipFile
                        import json
                        
                        empty_dict = {u'arch': u'32',
                                      u'name': u'npp-pluginList',
                                      u'npp-plugins': [   {   u'author': u'',
                                                              u'description': u'',
                                                              u'display-name': u'',
                                                              u'folder-name': u'',
                                                              u'homepage': u'',
                                                              u'id': u'',
                                                              u'repository': u'',
                                                              u'version': u''
                                                          },
                                                      ],
                                      u'version': u'0'}
                        
                        
                        download_directory = None
                        extract_to_directory = None
                        
                        
                        def extract_plugin(_file, _folder):
                            try:
                                extract_to = os.path.join(extract_to_directory, _folder)
                                with ZipFile(_file, 'r') as zip:
                                    zip.extractall(extract_to)
                            except Exception as e:
                                print('-->> extracting {} failed with error {}'.format(_file, e))
                        
                        
                        def plugin_downloaded(repo):
                            success = False
                            saved_file = None
                            try:
                                print('going to download {}'.format(repo))
                                _,_,_file = repo.rpartition('/')
                                if not _file.endswith('.zip'):
                                        _file += '.zip'
                                _file = urllib.url2pathname(_file)
                        
                                if not os.path.isdir(download_directory):
                                    os.makedirs(download_directory)
                        
                                saved_file = os.path.join(download_directory, _file)
                                f = urllib2.urlopen(repo, timeout=3)
                                data = f.read()
                                with open(saved_file, 'wb') as f:
                                    f.write(data)
                        
                                success = True
                            except Exception as e:
                                print('-->> downloading {} failed with error {}'.format(repo, e))
                            return success, saved_file
                        
                        
                        def check_for_updated_plugin(new_plugin_list, local_plugin_list):
                            lookup = {plugin['id']:plugin for plugin in local_plugin_list}
                            for new_plugin in new_plugin_list:
                                if new_plugin['id'] in lookup:
                                    if new_plugin['version'] != lookup[new_plugin['id']]['version']:
                                        successful, _file = plugin_downloaded(new_plugin['repository'])
                                        if successful:
                                            extract_plugin(_file, new_plugin['folder-name'])
                                else:
                                    successful, _file = plugin_downloaded(new_plugin['repository'])
                                    if successful:
                                        extract_plugin(_file, new_plugin['folder-name'])
                        
                        
                        def main():
                            global download_directory
                            global extract_to_directory
                        
                            for arch in ['x86','x64']:
                                download_directory = r'D:\npp\download_plugins\{}\download'.format(arch)
                                extract_to_directory = r'D:\npp\download_plugins\{}\extractto'.format(arch)
                                local_plugin_json_file = r'D:\npp\download_plugins\plugin{}.json'.format(arch)
                                web_plugin_json_url = r'https://raw.githubusercontent.com/notepad-plus-plus/nppPluginList/master/src/pl.{}.json'.format(arch)
                        
                                print('\n{}\n\nChecking plugins for architecture:{}'.format('#'*80, arch))
                                try:
                                    data = urllib.urlopen(web_plugin_json_url)
                                    downloaded_plugin_json = json.load(data)
                        
                                    if not os.path.exists(local_plugin_json_file):
                                        __local_plugin_json = empty_dict
                                    else:
                                        with open(local_plugin_json_file, 'r') as f:
                                            __local_plugin_json = json.load(f)
                        
                                    if __local_plugin_json['version'] != downloaded_plugin_json['version']:
                                        check_for_updated_plugin(downloaded_plugin_json['npp-plugins'], __local_plugin_json['npp-plugins'])
                                        with open(local_plugin_json_file, 'w') as f:
                                            json.dump(downloaded_plugin_json, f)
                                    else:
                                        print('No updates available')
                        
                                except Exception as e:
                                    print('-->> Something went wrong for arch {}: {}'.format(arch, e))
                        
                                finally:
                                   print('\n' + '#'*80)
                        
                            print('finished')
                        
                        
                        main()
                        
                        
                        M 2 Replies Last reply Feb 28, 2019, 9:12 PM Reply Quote 3
                        • M
                          Meta Chuh moderator @Ekopalypse
                          last edited by Meta Chuh Mar 1, 2019, 12:32 AM Feb 28, 2019, 9:12 PM

                          @Ekopalypse

                          this is soooo nice !!! 🙏😃👍
                          i somehow counted on that i can count on you 😉

                          i have just tested your script within the PythonScript plugin and it works like a charm.
                          this is so awesome, it simply deserves more explanation, so i will promote it a bit with a little …


                          plugins auto downloader manual:
                          (© Ekopalypse 2019)

                          features:

                          • all plugins will be automatically downloaded for both x86 and x64 architectures.

                          • all plugins will be automatically extracted to a freely configurable plugins location.

                          • all plugin zips are kept at an extra location. the admin can freely choose whether to deploy from a set of automatically downloaded zip files, or copying the required, automatically extracted plugins directly.

                          • plugins that have already been downloaded, will be skipped and not downloaded again.
                            an admin can start this script as many times as he wants, without producing elevated internet traffic.
                            (if all plugins are up to date, it will only take appx 2 seconds for the comparison at a re-run.)


                          setup and usage:

                          • the desired paths, where the plugins should be downloaded to, have to be set at the variables
                            download_directory, extract_to_directory and local_plugin_json_file within the main() section of plugins auto updater.py.
                            important note: the paths for download_directory and extract_to_directory begin after = r' and end before {},
                            except local_plugin_json_file where the path begins after local_plugin_json_file = r' and ends before plugin{}.json as the last part is the json filename instead of a folder, as seen at the demo path setup below.

                          • demo path setup:
                            in the path customisation example below, i’ve used the destination path H:\Downloads\plugin\:

                          download_directory = r'H:\Downloads\plugins\{}\download'.format(arch)
                          extract_to_directory = r'H:\Downloads\plugins\{}\extractto'.format(arch)
                          local_plugin_json_file = r'H:\Downloads\plugins\plugin{}.json'.format(arch)
                          
                          • to run this script, execute it in any python environment, either from the command line, a batch script, scheduled task, or the notepad++ pythonscript plugin, which can also be set to execute on every notepad++ startup.

                          notes:

                          • all x86 plugin zip files can be found at YourCustomPath\plugins\x86\download\ and all x64 plugin zips at YourCustomPath\plugins\x64\download\

                          • all extracted x86 plugins will be at YourCustomPath\plugins\x86\extractto\ and all extracted x64 plugins at YourCustomPath\plugins\x64\extractto\

                          important note: all re-publications of this script, distribution outside the notepad++ community, integration to any public repo not owned or maintained by the author, or posting this script at a different location, require the consent of the scripts author @Ekopalypse before doing so.

                          1 Reply Last reply Reply Quote 2
                          • M
                            Meta Chuh moderator @Ekopalypse
                            last edited by Feb 28, 2019, 10:14 PM

                            @Ekopalypse

                            ps: nur um mal auf nummer sicher zu gehen: in diesem fall ist “nett” nicht der kleine bruder von scheisse, sondern einfach geil, saugeil sogar 😉


                            ps: just to be on the safe side: in this case “nice” is not the little brother of s… but simply cool, even as cool as a pig 😉

                            i know, i know, it doesn’t make much sense when translated to english, but afaik “nice” in german is sometimes kind of an insult.
                            for example if a girl says: “you are such a nice guy”, she usually means that he’s the little mini-me of a dude she wouldn’t even date if he would be the last man on earth … but even more boring than that 😂

                            and saugeil is as untranslatable as affengeil, which is best described by >>> this 80’s song <<< .

                            1 Reply Last reply Reply Quote 1
                            • E
                              Ekopalypse
                              last edited by Feb 28, 2019, 10:24 PM

                              @Meta-Chuh
                              First, thank you for your awesome usage guide.
                              Works exactly like you mentioned. :-D thumbs up.
                              @all
                              And of course, everyone can use it like they want.
                              It is free to use like the free in free beer.
                              Like with every software, don’t rely on it - check from time to time
                              whether it still works as the script doesn’t do much error checking.

                              1 Reply Last reply Reply Quote 1
                              • E
                                Ekopalypse
                                last edited by Feb 28, 2019, 10:25 PM

                                gagagaggei… :-D

                                1 Reply Last reply Reply Quote 1
                                8 out of 15
                                • First post
                                  8/15
                                  Last post
                                The Community of users of the Notepad++ text editor.
                                Powered by NodeBB | Contributors