I spent a good bit of time over the weekend digging into some java coding for work. Wrapping some things up and the extra time will help.
I noticed that there is a third edition of effective java out there. I have the older edition, but it is really too old to be helpful with the current state of the java world. The ‘effective’ books overall have tended to be very helpful with usage, idioms and anti-patterns beyond the basic so I’m looking forward to reading this volume and seeing what it has to offer.
I spent a good piece of today writing up a free-standing command line tool to display the unique file id for windows files. The API that provides this is exceptionally useful when working with file cleanup in systems where there are mount points, symbolic links and other reparse points present. This API is not directly accessible from languages such as java or C# and thus an invokable command line tool seems handy. Interop and jni would also offer access, but the command line tool seems the most general purpose (if perhaps low on the performance scale).
I wound up writing a small command line option parser to support this work (though only used a little at this point). I’ll likely keep this around and use it in other tools going forward.
I’m also looking at adding a json output generation option and a stream in/stream out switch to make this little tool more useful for higher volume solutions with programmatic interfaces. It seems as if a json based programmatic interface using standard I/O streams would offer significant performance while also providing enough ‘traction’ to make program to program use of the tool practical.
I ran into a small hiccup this evening as I was unable to upload the code to github as github appeared to be suffering from some sort of relatively serious failure. Hoping that tomorrow morning things will be in better shape and I can push the code up then.
I will probably build a simple json library for local use over the next couple of days (I’ve done this before and it is relatively straightforward as json is a very regular and simple format). I need small and easy more than capable and fast so something coded locally seems best.
Spent some time over the weekend looking at APIs in windows that give access to the monitor configuration of the system that code is running on.
I tend to run on systems with several monitors (usually as many as is practical). Ideally, I’d like to create tools that can use the available display real-estate in helpful ways.
The main API involved is EnumDisplayMonitors which will invoke your provided callback function with the HMONITOR for each monitor that is recognized by the system. Calling GetMonitorInfoW can then provide some of the details of each display in a MONITORINFOEX structure.
One oddity in all of this is that a monitor with a scaling factor applied (my 4K monitor is set to 150% scale factor for usability reasons) returns the post-scaling size with a gap in the coordinate system that reflects the ‘missing’ pixels. In my case the small monitor I use to keep an eye on the router is logically far to the right of the left hand edge of the big monitor.
There is a supplementary API call GetScaleFactorForMonitor which returns a DEVICE_SCALE_FACTOR indicating the current scale factor for a given monitor. This is a little bit strange on my system as the big monitor appears to be set for 150% scaling but the API call shows 140% scaling. The size numbers match what I’d expect for 150% so something must be a bit off here…
Interesting API to look into GetDpiForMonitor and MONITOR_DPI_TYPE.
Looks as if the SetProcessDpiAwareness API (with PROCESS_DPI_AWARENESS and WM_DPICHANGED) may have a part in all of this as well…deciding whether the process gets presented DPI aware or virtualized display metrics.
Curious translation in GetPhysicalMonitorsFromHMONITOR could use a bit of a look.
I need to read more of the DPI aware and multi-monitor articles before I’m done here. I also want a better idea of how this functionality interacts with WPF user interfaces as I’m likely to build the upper layers that way.
This certainly gets more complicated with display scaling and DPI calculations in the mix.
Some more relevant articles (I haven’t read these all in detail yet):
In order to get the full ID of a file in Win32 the GetFileInformationByHandle returning a BY_HANDLE_FILE_INFORMATION which contains 64 bits of file ID (and the volume id where the file resides) is a start.
The GetFileInformationByHandleEx with FILE_INFO_BY_HANDLE_CLASS of returns FILE_ID_INFO which provides the full (potentially) 128 bit file id as required for ReFS.
I’ll likely provide support for both of these shortly, likely using C++/CLI to simplify the interface.
Given these two pieces of information it should be much safer to clear out duplicate files as various sorts of links and mount points will still show the ultimate file identity properly and avoid deleting apparent duplicates that are really just aliased paths to the same file.