Skip to content

Windows port #5

Open
Open

Description

@aquette

Activity

  1. aquette commented on Feb 14, 2013

    @aquette
    MemberAuthor
  2. clepple commented on Feb 18, 2013

    @clepple
    Member

    I did a regression check on whether the code compiles for non-Windows systems, and it looks like there is an issue with this trunk merge to 2.6.5: 6e51ff2

    The code still compiles, but the documentation does not: http://buildbot.networkupstools.org/public/nut/builders/Ubuntu-natty-x86/builds/322/steps/compile/logs/stdio

    It looks like it is related to the change to the formatting of the INSTALL file, but it is possible that another related change did not get pulled in from the trunk.

  3. clepple commented on Feb 20, 2013

    @clepple
    Member

    I think the INSTALL file was overwritten by mistake during that merge with the standard GNU installation instructions:

    http://trac.networkupstools.org/projects/nut/browser/branches/windows_port/INSTALL?rev=3714
    versus
    http://trac.networkupstools.org/projects/nut/browser/trunk/INSTALL?rev=3857

    I'm going to copy over the INSTALL from master, and apply this commit: http://trac.networkupstools.org/projects/nut/changeset/2958/ (but @bohe-eaton feel free to update the instructions if they are out of date)

  4. intrudo commented on Apr 12, 2016

    @intrudo

    Hello!

    A few weeks ago I have successfully built NUT in MinGW environment using Windows-v2.6.5-7 branch (you may find a manual I have posted to nut-upsdev mailing list).

    I would like to help with Windows port development. I have examined the source code of several components (upsd, upsmon, nut) and I have got some ideas. I will be happy to share them with NUT team.

    MAINTAINER UPDATE: Links to those mail posts in the archive:

  5. aquette commented on Apr 28, 2016

    @aquette
    MemberAuthor

    hi @intrudo , thanks for jumping in.
    The best for now is probably to present your ideas here and / or to fork a branch of the Windows one and start applying these ideas.

    see also ntUPSd - Network UPS Tools Services for Windows (https://github.com/6XGate/ntUPSd) from @6XGate

    thx and cheers

  6. intrudo commented on Apr 30, 2016

    @intrudo

    Hi @aquette ! Let’s start =)

    First of all, I would like to say that I am not going to do something without acceptance of NUT Team (it would be great to coordinate high-level tasks at least). Please, feel free to say "no", if something is out of your vision/roadmap.

    I sent a message with my ideas to nut-upsdev list and discussed some points with @clepple already. You may find there more details why I think so. So, here are just short descriptions.

    1. Produce cross-compiled source code to build *nix, x86 and x64 versions from single sources. Linux environment must be used only.
    2. Make a software abstraction layer (SAL) to hide all functions’ calls like "system", "syslog", etc. Windows version will have special implementation of them, *nix will translate the calls to standard ones. For example, no one will call "system" directly, but "nut_system" only. "nut_system" will call standard "system" function for *nix and "CreateProcess" for Windows. As result of such abstraction, we will have common program flow in source code without platform specific conditions like #ifdef.
    3. Improve logging for Windows version and use file-based log instead of Windows Event Log. Moreover, standard syslog should be supported in Windows version too (to have equal behavior with *nix version).
    4. Eliminate NUT service in Windows version (it provides "syslogd" and "initd" functions). Implement every daemons (upsmon, upsd) as Windows services. Here is open question what to do with drivers; it looks quite redundant to port every driver as service. I think to create additional Windows service (or extend upsdrvctrl program) to control them (start, stop, etc.), so, they can stay as console applications.

    Sure, I see many minor tasks, but let us discuss them later.

    The one thing I worry is branch. I was going to fork Windows-v2.6.5-7 branch and completing Windows port there. @clepple thinks that Windows-v2.6.5-7 should be rebased before. Unfortunately, I am not GIT expert and I am afraid that there will be many conflicts during rebase. Moreover, I think that my commits will be quite massive. What is the best way to synchronize master branch and my repository? I will be glad to get any hint.

    I have looked into sources of ntUPSd project. They are complete different from NUT one, but maybe I will find something useful there.

    Thanks!

  7. clepple commented on Apr 30, 2016

    @clepple
    Member

    The best for now is probably to present your ideas here and / or to fork a branch of the Windows one and start applying these ideas.

    @aquette for reference, here is the previous nut-upsdev discussion: http://lists.alioth.debian.org/pipermail/nut-upsdev/2016-April/007172.html

    Let me know if you have further questions about why I don't think a major Windows development effort should be based on that branch. The architectural changes that @intrudo proposed are probably best done by using Windows-v2.6.5-7 as a guide. For instance, there are a lot of #ifdef WIN32 blocks that will get even messier if 64-bit #ifdefs are needed. Also, a lot of drivers have been added or changed substantially since 2.6.x, and I think it would be best to re-port them using the proposed APIs and coding style.

  8. intrudo commented on May 5, 2016

    @intrudo

    Well, if you do not mind, I will fork Windows-v2.6.5-7 branch to implement the SAL. After it is completed, we could get back to the question of proper branching and future merge.

  9. clepple commented on May 7, 2016

    @clepple
    Member

    Well, if you do not mind, I will fork Windows-v2.6.5-7 branch to implement the SAL. After it is completed, we could get back to the question of proper branching and future merge.

    Agreed. For prototyping, I do not mind development on that branch (or a branch of the branch, given that branches are cheap in Git). I just want to make sure that everyone understands that merging (in the Git sense of the word, where two lines of history connect back to each other) any of the old Windows-* branches back into master will be a train wreck due to the leftover translated SVN cruft, plus the rebasing issues. (We cleaned up most of the SVN cruft in master with reposurgeon, and spent a lot of time verifying correctness against old tarballs, but we did not do the same to the Windows branches.)

    I think a lot of the Windows-specific files from the branch could be copied over to a new Windows branch that starts from either v2.7.4 or master, though I think that they would change a bit for the proposed reduction of #ifdef WIN32 blocks.

  10. mrudat commented on Sep 18, 2016

    @mrudat

    Depending on which library is being used for the windows port, would it not already either include a system and syslog function, or not include either, and thus allow us to write a replacement function also removing the need for different code for each platform.

  11. added a commit that references this issue on Jan 28, 2017
  12. added a commit that references this issue on Mar 1, 2017
  13. aquette commented on Mar 22, 2017

    @aquette
    MemberAuthor

    Adding a user provided doc on "How to build NUT Windows Port":
    http://lists.alioth.debian.org/pipermail/nut-upsdev/2016-April/007171.html

  14. 25 remaining items

  15. chocmake commented on Mar 5, 2024

    @chocmake

    Hmm, perhaps I should make it a separate issue but here are various things I've tried with no effect:

    SHUTDOWNCMD "shutdown /l" [no effect, this is the logout argument on Windows]
    SHUTDOWNCMD "notepad.exe" [to see if it could execute any Windows CLI paths]
    SHUTDOWNCMD "cmd.exe /c "C:\Portable\NUT\etc\script.bat""
    SHUTDOWNCMD "/etc/script.bat"

    Also tried instead using upssched-cmd but I think the issue is everything is being interpreted as Linux-native commands and there's no way I'm aware of to 'break out' of the Linux interpreter to execute native Windows commands.

    shutdown /s which works must just be being interpreted coincidentally as the Linux equivalent (not sure what the /s argument would be interpreted as since only familiar with -h and -t in Linux).

    Goal with a script is I need to run commands to close any open VMs then hibernate my system when the FSD signal is detected, since a vanilla shutdown wouldn't handle all scenarios.

  16. jimklimov commented on Mar 5, 2024

    @jimklimov
    Member

    My guess would be that Windows slashes must be doubled (so as to be escaped), and if quotes are deemed needed - also escaped. So purely parser-wise these would be more correct:

    SHUTDOWNCMD "cmd.exe /c \"C:\\Portable\\NUT\\etc\\script.bat\""
    SHUTDOWNCMD "cmd.exe /c C:\\Portable\\NUT\\etc\\script.bat"
    

    Maybe explicit cmd is not required (should be the OS-registered handler for batch files)... coupling with Unix-style slash support (in modern Windows), maybe this would work:

    SHUTDOWNCMD "C:/Portable/NUT/etc/script.bat"
    

    Edit: tested a forced shutdown via the server and indeed the upsmon window left open detected it and shutdown the system (had previously edited the SHUTDOWNCMD to be the Windows equivalent of shutdown /s).

    I was under the impression that you did nail the syntax for it? Or did it only work for "interactive" upsmon in a window?

    ...not sure what the /s argument would be interpreted as...

    Check shutdown /? on your system, its set of options varied over editions; e.g. from what I found:

    Usage: shutdown [/i | /l | /s | /sg | /r | /g | /a | /p | /h | /e | /o] [/hybrid] [/soft] [/fw] [/f]
        [/m \\computer][/t xxx][/d [p|u:]xx:yy [/c "comment"]]
    
        No args    Display help. This is the same as typing /?.
        /?         Display help. This is the same as not typing any options.
        /i         Display the graphical user interface (GUI).
                   This must be the first option.
        /l         Log off. This cannot be used with /m or /d options.
        /s         Shutdown the computer.
        /sg        Shutdown the computer. On the next boot, if Automatic Restart Sign-On
                   is enabled, automatically sign in and lock last interactive user.
                   After sign in, restart any registered applications.
        /r         Full shutdown and restart the computer.
        /g         Full shutdown and restart the computer. After the system is rebooted,
                   if Automatic Restart Sign-On is enabled, automatically sign in and
                   lock last interactive user.
                   After sign in, restart any registered applications.
        /a         Abort a system shutdown.
                   This can only be used during the time-out period.
                   Combine with /fw to clear any pending boots to firmware.
        /p         Turn off the local computer with no time-out or warning.
                   Can be used with /d and /f options.
        /h         Hibernate the local computer.
                   Can be used with the /f option.
        /hybrid    Performs a shutdown of the computer and prepares it for fast startup.
                   Must be used with /s option.
        /fw        Combine with a shutdown option to cause the next boot to go to the
                   firmware user interface.
        /e         Document the reason for an unexpected shutdown of a computer.
        /o         Go to the advanced boot options menu and restart the computer.
                   Must be used with /r option.
        /m \\computer Specify the target computer.
        /t xxx     Set the time-out period before shutdown to xxx seconds.
                   The valid range is 0-315360000 (10 years), with a default of 30.
                   If the timeout period is greater than 0, the /f parameter is
                   implied.
        /c "comment" Comment on the reason for the restart or shutdown.
                   Maximum of 512 characters allowed.
        /f         Force running applications to close without forewarning users.
                   The /f parameter is implied when a value greater than 0 is
                   specified for the /t parameter.
        /d [p|u:]xx:yy  Provide the reason for the restart or shutdown.
                   p indicates that the restart or shutdown is planned.
                   u indicates that the reason is user defined.
                   If neither p nor u is specified the restart or shutdown is
                   unplanned.
                   xx is the major reason number (positive integer less than 256).
                   yy is the minor reason number (positive integer less than 65536).
    
    Reasons on this computer:
    (E = Expected U = Unexpected P = planned, C = customer defined)
    Type    Major   Minor   Title
    
     U      0       0       Other (Unplanned)
    E       0       0       Other (Unplanned)
    E P     0       0       Other (Planned)
     U      0       5       Other Failure: System Unresponsive
    E       1       1       Hardware: Maintenance (Unplanned)
    E P     1       1       Hardware: Maintenance (Planned)
    E       1       2       Hardware: Installation (Unplanned)
    E P     1       2       Hardware: Installation (Planned)
    E       2       2       Operating System: Recovery (Unplanned)
    E P     2       2       Operating System: Recovery (Planned)
      P     2       3       Operating System: Upgrade (Planned)
    E       2       4       Operating System: Reconfiguration (Unplanned)
    E P     2       4       Operating System: Reconfiguration (Planned)
      P     2       16      Operating System: Service pack (Planned)
            2       17      Operating System: Hot fix (Unplanned)
      P     2       17      Operating System: Hot fix (Planned)
            2       18      Operating System: Security fix (Unplanned)
      P     2       18      Operating System: Security fix (Planned)
    E       4       1       Application: Maintenance (Unplanned)
    E P     4       1       Application: Maintenance (Planned)
    E P     4       2       Application: Installation (Planned)
    E       4       5       Application: Unresponsive
    E       4       6       Application: Unstable
     U      5       15      System Failure: Stop error
     U      5       19      Security issue (Unplanned)
    E       5       19      Security issue (Unplanned)
    E P     5       19      Security issue (Planned)
    E       5       20      Loss of network connectivity (Unplanned)
     U      6       11      Power Failure: Cord Unplugged
     U      6       12      Power Failure: Environment
      P     7       0       Legacy API shutdown
    
  17. chocmake commented on Mar 5, 2024

    @chocmake

    My guess would be that Windows slashes must be doubled (so as to be escaped), and if quotes are deemed needed - also escaped. So purely parser-wise these would be more correct:

    So tested these three (edited upsmon.conf, restarted NUT service in case it needed to be to detect the config changes, then sent FSD) but none had any effect (technically the one effect the FSD signal always has for the NUT client is stopping the Windows NUT service, since I suppose it assumes a shutdown has commenced and it no longer needs to be running).

    I was under the impression that you did nail the syntax for it? Or did it only work for "interactive" upsmon in a window?

    Only shutdown /s works, both when I originally launched upsmon or when using the background service that I later installed. It just happened to be the first command I tried since it was the Windows equivalent. Whereas other Windows arguments I've tried since like shutdown /l have no effect (nor other commands like those listed in my prior post).

    Check shutdown /? on your system, its set of options varied over editions; e.g. from what I found:

    Mmm, yeah for Windows I'm familiar, just not what it's being translated to (that is, if my later assumption is correct that everything gets interpreted as Linux commands). Linux man page for shutdown doesn't list any -s so was puzzled why only /s works.


    Currently testing in a Windows 10 VM via VirtualBox, to test feasibility (and for ease of restarting) before adding to my host Windows system.

  18. chocmake commented on Mar 8, 2024

    @chocmake

    Some more testing. Decided to stop the NUT service and launch upsmon.exe instead since an earlier post mentioned:

    I think as a service it has no easy access to a desktop session

    Also since it I noticed references in the source code to Cygwin, which supports executing Windows commands alongside Linux ones with the right syntax. Not sure if that's actually what is used as the interpreter but anyway.

    Results:

    • SHUTDOWNCMD "calc.exe" = works
    • SHUTDOWNCMD "cmd /c \"C:\\Portable\\NUT\\etc\\script.bat\"" = works
    • SHUTDOWNCMD "\"C:\\Portable\\NUT\\etc\\script.bat\"" = works
    • SHUTDOWNCMD "C:\Portable\NUT\etc\script.bat" = fails
    • SHUTDOWNCMD 'C:\Portable\NUT\etc\script.bat' (single quotes) = fails (read online this should work in Cygwin)
    • SHUTDOWNCMD "cmd.exe /c "C:\Portable\NUT\etc\custompoweroff.bat"" = fails
    • SHUTDOWNCMD "/etc/script.bat" = fails

    So at least I know now using upsmon.exe instead is feasible for launching commands other than shutdown /s.


    If there was a way that the service could execute files when at least given a full path it'd be useful. This SO page suggests that for example CMD.exe can be utilized with arguments via a service, so long as it doesn't require any UI/user interaction. Idk if this is relevant to how NUT handles it.

  19. jimklimov commented on Mar 8, 2024

    @jimklimov
    Member

    I read there is a common trick using Windows Task Scheduler to set up execution of complex commands (with privileges needed, ensuring stuff only runs once at a time, etc.) and scripts or other less privileged programs calling that via schtasks /Run "name".

    I suppose here it is overkill since the NUT service should already be quite privileged, but still a useful trick in the automation toolkit.

    You can probably try setting a higher debug_min in upsmon.conf (see wiki) and check if something appears in event log about programs it is trying to run, maybe failing (and with what hints then).

    Keep in mind that there is a NUT config parser involved first and foremost (converting string markup in text files into a char array in memory), so the outer double-quotes which concatenate space-separated tokens like shutdown and /s are important and are not passed as such to the OS. Notably, you should not need extra quotes to wrap a single token. The back-slashes are parsed in C style, so a single one means an escape symbol (like \n meaning end of line; you need \\ to escape and present a single backslash). The rest is passed to OS-dependent API for process creation (usually fork()+exec() or native CreateProcess() on Windows; in case of upsmon.c I see a generic system() for both, however) which is where embedded single/double quotes and path resolution (/etc/...) might matter.

  20. chocmake commented on Mar 8, 2024

    @chocmake

    Checked Event log messages when DEBUG_MIN 2 set.

    upsmon - [D2] pollups: ups@<ip>
    upsmon - [D2] parse_status: [FSD OL]
    upsmon - [D1] Critical UPS: ups@<ip>
    upsmon - [D2] do_notify: ntype 0x0006 (SHUTDOWN)
    upsmon - Failed to create power down flag!
    Exiting
    

    Then checked when set to DEBUG_MIN 3. Didn't increase verbosity but curiously the errors weren't logged (maybe because it was between polling checks?). So I guess 2 is the max verbosity (or 1, didn't try that).

    upsmon - [D2] pollups: ups@<ip>
    upsmon - [D2] parse_status: [OL]
    upsmon - [D2] pollups: ups@<ip>
    Exiting
    

    Might try the method of setting my custom script to execute when the service is detected as stopped (which afaict is possible with it via the Service properties). Edit: oh, I see what you meant re Task Scheduler, didn't click at first.


    Edit 2: tested creating a Task Scheduler task and using SHUTDOWNCMD "schtasks /run /tn "Task name here"" to trigger it in upsmon.conf.

    First tested that the task would launch the custom script when manually run via Task Scheduler and gave it Administrators user group privileges and enabled 'Run with highest privileges' option. It wouldn't run without admin privileges I found (edit: turns out there is but you have to disable the option to run when logged out, so tested setting task to run under current user only but similarly nothing triggered on FSD).

    However unfortunately the NUT service failed to launch it automatically when the FSD signal was received. If I'm missing something let me know.

  21. chocmake commented on Mar 9, 2024

    @chocmake

    Some success :) Found a way to make upsmon.exe launch entirely hidden, so that it can be run in the background instead of the NUT service for correctly launching arbitrary SHUTDOWNCMD values.

    It uses VBScript to launch it to begin with, which can be added to the Windows startup/etc.

    1. Create a VBS file in the sbin directory, eg: upsmon-hidden.vbs.
    2. Fill it with the following lines (the 0 tells VBScript to launch it window-less):
    Set wShell = CreateObject ("Wscript.Shell") 
    wShell.Run "upsmon.exe", 0
    
    1. Launch it and nothing will appear, however it will be listed in Task Manager's Details tab, along with a conhost item.

    Downsides to this approach:

    • Runs per-user instead of user-agnostic like a Windows service is. So if multiple users on system then each would require their own running copy, which also means multiple instances of whatever command/script is set for SHUTDOWNCMD will trigger simultaneously if both users logged in when FSD signal received (may or may not be an issue).
    • No Event Viewer logs added afaict (though I personally don't care).
    • In my limited testing nothing launched by the hidden upsmon.exe will be visible either, including batch scripts. So any commands used should be functional rather than say launching some visible window (unless it's just some passed argument to an already running program).

    Miscellaneous:

    • If upsmon.conf security permissions are changed to be read only for the current user (ie: to make modification a privileged action) upsmon.exe will fail to run, saying it can't access the file.
    • If using hibernation instead of shutdown upsmon.exe will need to be restarted following the restoration of the hibernation state (since it's not a Windows startup it won't auto launch otherwise). This can be accomplished by attaching a Task Scheduler task to the Power-Troubleshooter event with the Event ID of 1. See this answer for the correct path syntax to get VBS scripts to auto run without erroring.

    Other things explored prior to this that had no effect:

    • Editing NUT service Properties>Recovery settings to 'Run program' when service 'failure' detected. Apparently a service auto stopping doesn't count as a failure so this had no effect.
    • Running NUT service as current user via Properties>Log on and entering current user's Windows credentials.
    • Can't attach a Task Scheduler task to an Event Viewer log item in NUT's case since all events are logged as event ID 1, whether they're an error/warning/normal event. Also Exiting event is logged as normal item (I think that's the last event that occurs when FSD detected?).
  22. added a commit that references this issue on Jun 10, 2024
  23. added a commit that references this issue on Nov 30, 2024
  24. opoplawski commented on Feb 12, 2025

    @opoplawski

    We're trying to spin up a NUT server on Windows using a snapshot from around Aug 29 2024. Couple issues:

    • It seems at least at times to look for upsdrvctl.exe in bin instead of sbin:
    Can't create process C:\NUT\mingw64\bin\..\bin\upsdrvctl.exe start : 2
    

    We made copy of that program in bin. Not sure where that is coming from.

    • We're getting very little information from the driver (no battery, input, output items) and it incorrectly states that it is on battery:
    PS C:\WINDOWS\system32>  C:\NUT\mingw64\bin\upsc.exe upssrt5000va@localhost
    device.mfr: American Power Conversion
    device.model: Smart-UPS SRT_500
    device.serial: AS2135172099
    device.type: ups
    driver.debug: 0
    driver.flag.allow_killpower: 0
    driver.name: usbhid-ups
    driver.parameter.pollfreq: 30
    driver.parameter.pollinterval: 2
    driver.parameter.port: auto
    driver.parameter.synchronous: auto
    driver.state: quiet
    driver.version: 2.8.2.986-986-gf31b1ebf7
    driver.version.data: APC HID 0.100
    driver.version.internal: 0.56
    driver.version.usb: libusb-0.1 (or compat)
    ups.firmware: UPS 10.1 / ID=1020
    ups.mfr: American Power Conversion
    ups.model: Smart-UPS SRT_500
    ups.productid: 0003
    ups.serial: AS2135172099
    ups.status: OB
    ups.vendorid: 051d
    

    Any suggestions on how to debug that?

    Config is:

    [upssrt5000va]
      driver = usbhid-ups
      port = auto
      pollonly = yes
    

    Tried with and without pollonly.

  25. jimklimov commented on Feb 14, 2025

    @jimklimov
    Member

    Regarding driver info - I saw that when a Windows USB handler also attached to the device (seen as HID Battery). I think I posted reports with Eaton ECO 650 on that (for search).

    My finding was that proper libusb attachment with Zadig is a must.

  26. opoplawski commented on Feb 14, 2025

    @opoplawski

    That did the trick. Thanks!

    Any ideas about the upsdrvctl path issue?

  27. jimklimov commented on Feb 15, 2025

    @jimklimov
    Member

    Not yet, my guess is that some path macro compiled into nut.exe is wrong? (Assuming that is where the message comes from?)

  28. added a commit that references this issue on May 25, 2026
  29. added a commit that references this issue on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions