I’m getting more comfortable with PInvoke from C#. I’ve been using a web site that contains a pretty wide variety of recipes for getting at Win32 API calls with PInvoke.
At some point soon I need to take a look at the WindowsAPICodePack-Core which appears to have pre-built versions of some of these things. For now I’m happy that I’m getting closer to the point where I know how to invoke most API calls directly using PInvoke.
I do wish there was a more comprehensive reference document discussing all of the capabilities and ins and outs of using this facility. As is there are examples and specific documentation for some items (I’ve been using my copy of .NET 2.0 Interoperability Recipes: A Problem-Solution Approach to work out the basics and the PInvoke web site to extend that to more complicated examples.
I’ve put some of the sample code I’ve been playing with on GitHub at DupScan. This project is again code aimed at deduplicating file trees for archiving and management. The big driver here is the unique file ID API.
Building C++ supporting libraries on my small dev machine. Looking at another pass of C++/CLI work and some more thinking about motion capture options.
I’ve built zlib and bzlib2 yesterday. To get these building with VS 2017 I built them with their standard build procedures (which appeared to build 32 bit libraries) and then created visual studio 2017 projects to build the same pieces using fresh settings.
I’ve got boost, openssl, opencv and the mongodb c and c++ libraries on my list for today. The mongodb libraries are my primary target here though all of the above are of interest. This is also what is driving my CMake reading as several of these libraries use CMake for their builds.
I’m pretty interested in C++/CLI as a way to get access to C and C++ functionality from C#. Given the productivity that C# provides, access to C and C++ APIs and libraries from that environment would help quite a bit. My primary driver was access to the Win32 file ID API for some file management work, but Win32 APIs keep coming up now and again. I do need to take a look as some newer C# libraries that Malcolm suggested that may provide pre-packaged access here.
In the past, I’ve run into build issues when combining C# and C++/CLI in the same project. I expect this was setup issues so I’m now looking to take a more serious look at this.
The motion capture work will start out with OpenCV and getting my web cams running with code behind them to process the images. I’m thinking that pre-recording things and then post processing might be a good idea…using a light strobe to synchronize things could simplify time sync as well. Much to consider…
I’ve got boost, zlib and libbz2 built on boojum now. Next step will be to test the installs with a small program or two. Hoping that all went well and I have usable, native, win64 libraries available.
Once those have been checked out I’ll take another run at building the MongoDB drivers…this time on boojum rather than chaos. Boojum has a shorter history and is distinctly less cluttered than chaos so I’m hoping that this just works. Expecting less than that though…I’ll probably need to dig deeper into he CMake configs to get where I want to go. I’ll update as I move forward…now off to lunch though.
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.