Introduction

The MicroStation Development Library (MDL) and MicroStationAPI provide APIs for developers wanting to create custom applications for MicroStation® from Bentley Systems. We create a MicroStation application as a DLL, written using C++ and built with the Microsoft C++ compiler and linker provided with Visual Studio.

When editing your source code, you can choose whether to use Microsoft Visual Studio, Microsoft Visual Studio Code, or one of your favourite text editors.

When building your app, you can use Visual Studio or the Bentley Systems make (bmake) tools.

Harvesting Files

Sometimes we want to process multiple files, otherwise known as batch processing. That is, we want to find each file in a directory, and possibly sub-directories, and do something with that file. Often, we want to open each file with MicroStation and edit the contents of that file.

File Collector Dialog

Our requirement for such an application can be summarised …

File Harvesting with Windows

The APIs available for C++ developers for Windows do not make it easy to achieve our goal. There is no simple way to harvest files in a folder and descend into sub-folders. That's not to say we can't achieve our goal using, say, the Win32 API. However, that approach may be frustating.

Boost.Filesystem

If you're a C++ developer who is not familiar with Boost, then fix that deficiency.

The Boost.Filesystem library makes it easy to achieve our goal. In fact, Boost.Filesystem makes it easy to do all kinds of useful things with files and folders. Moreover, the libary is operating-system agnostic. Code we write for Windows is easy to recompile for another operating system using a different compiler.

File Collector Project

The File Collector Project is a C++ application for MicroStation CONNECT. It uses the MicroStationAPI SDK. It demonstrates how to use Boost.Filesystem to harvest files. It shows how to test files for writability — can MicroStation edit a file?

File Collector Dialog

File Collector Class

The project demonstrates several useful idioms for MicroStation developers. However, the main purpose of the project is to gather files. The class that implements the file collector is FileCollector, which has a collection of boost::filesystem::paths.

Some typedef aliases clarify what's going on …

using PathCollection    = std::vector<boost::filesystem::path>;
using PathIterator      = PathCollection::iterator;
using PathConstIterator = PathCollection::const_iterator;

Thanks to Boost.FileSystem, harvesting files could not be simpler …

size_t   FileCollector::Harvest  (path const& p)
{
    using namespace boost::filesystem;
    directory_iterator begin (p);
    directory_iterator end;
    for (; begin != end; ++begin)
    {
        InsertPath (*begin);
    }
    return paths_.size ();
}

Method InsertPath tests the passed boost.filesystem.path. It rejects objects that are not files such as links and folders. Optionally, it checks to see whether we have a CAD file — that is, a file that MicroStation can open. It also optionally rejects read-only files that we can't edit. Acceptable files are added to the PathCollection class variable.

File Type Description

There's one area where we venture outside Boost.Filesystem and into Windows shell programming. As you may know, when an application registers the file types it deals with, it informs Windows about that type with a brief description. You can see that description if you open a folder using Windows Explorer. A PDF file, for example, is shown as an Adobe Acrobat Document.

Windows shell programming generally involves the library of functions having prefix SH. In this case we're using SHGetFileInfo() to obtain file type information. As is often the case, I would not have got this far without help from the web. Here are two sites that I found particularly useful when working out how to call SHGetFileInfo() correctly …

First, we need to include this Win32 header …

#include  <Shobjidl.h>    //	Windows Shell API

Here's the function declaration …

static std::wstring  DescribeFileType (boost::filesystem::path const&  p);

Here's the function implementation …

///////////////////////////////////////////////////////////////////////
//	static
std::wstring        FileCollector::DescribeFileType    (path const&  p)
{
    ::SHFILEINFO    fileInfo    = { 0 };
    ::SHGetFileInfo (p.filename ().wstring ().c_str (), FILE_ATTRIBUTE_ARCHIVE, &fileInfo, sizeof (fileInfo),
        SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME);
    std::wstring    descr      (fileInfo.szTypeName);
    return descr;
}

Loading File Collector

Build the project. The executable files delivered to \MicroStation\mdlapps are FileCollector.ma and FileCollector.dll. Load the application into MicroStation with this key-in …

mdl load FileCollector folder-path

The File Collector dialog opens.

The following key-in commands become available once you've loaded FileCollector …

Command Description Arguments
HARVEST FILES Collect Files Initial Folder
HARVEST SET SUBFOLDERS Set the sub-folders flag ON | OFF | TOGGLE
HARVEST SET CAD Harvest only CAD files ON | OFF | TOGGLE
HARVEST SET WRITABLE Reject read-only files ON | OFF | TOGGLE
HARVEST EXIT Unload the application

The check-box dialog items (also known as toggle buttons) in the File Collector dialog serve the same purpose as the HARVEST SET commands.


Download

Download the File Collector Project

You can download the File Collector Project. The project is built using BMake. It uses the C++ compiler and linker installed with Visual Studio 2015. You will need to install the Boost libraries. This project was built and tested using Boost 1.64.

Questions

Post questions about C++ and the MicroStationAPI to the MicroStation Programming Forum.