Community

    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Update installed Plugins via script/cmd

    Help wanted · · · – – – · · ·
    plugins plugin manager script plugin-admin command line
    5
    15
    2707
    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.
    • Eddga
      Eddga last edited by

      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
      • PeterJones
        PeterJones last edited by

        @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
        • Alan Kilborn
          Alan Kilborn last edited by

          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
          • PeterJones
            PeterJones last edited by

            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
            • Alan Kilborn
              Alan Kilborn last edited by Alan Kilborn

              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
              • PeterJones
                PeterJones last edited by

                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
                • Eddga
                  Eddga last edited by

                  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.

                  Meta Chuh 1 Reply Last reply Reply Quote 3
                  • Meta Chuh
                    Meta Chuh @Eddga last edited by

                    @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
                    • Eddga
                      Eddga last edited by

                      @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.

                      Meta Chuh 1 Reply Last reply Reply Quote 2
                      • Meta Chuh
                        Meta Chuh @Eddga last edited by Meta Chuh

                        @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.

                        Ekopalypse 1 Reply Last reply Reply Quote 2
                        • Ekopalypse
                          Ekopalypse @Meta Chuh last edited by

                          @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()
                          
                          
                          Meta Chuh 2 Replies Last reply Reply Quote 3
                          • Meta Chuh
                            Meta Chuh @Ekopalypse last edited by Meta Chuh

                            @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
                            • Meta Chuh
                              Meta Chuh @Ekopalypse last edited by

                              @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
                              • Ekopalypse
                                Ekopalypse last edited by

                                @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
                                • Ekopalypse
                                  Ekopalypse last edited by

                                  gagagaggei… :-D

                                  1 Reply Last reply Reply Quote 1
                                  • First post
                                    Last post
                                  Copyright © 2014 NodeBB Forums | Contributors