Skip to content
Advertisement

Use of MONO_IOMAP to cope with a hard-coded file path?

I’m trying to get a Windows .NET binary to run under Linux using Mono. The app runs fine on Windows. It presently fails under Mono because it can’t find a file with a hard-coded path.

For testing, I’m using a Fedora 23 VirtualBox VM running under Windows 7. All the files are present on the VM’s FS (no shares with the Windows FS). The installed Mono version is 4.0.5.

It is not practical to modify and/or recompile the app.

App environment:

  • The application binary is located in “/way/down/in/this/directory/app.exe” It appears symbols have been stripped.

  • The application has a hard-coded path that looks like “C:BLAHThis.file”. The file contains the app’s runtime configuration information.

I’m invoking app.exe as follows:

#!/bin/bash
pushd /way/down/in/this/directory
export MONO_IOMAP=<whatever>
mono app.exe

I’ve tried each of the valid values of MONO_IOMAP (case, drive, all) with each of the following file configurations:

  1. Rename “This.file” to “C:\BLAH\This.file” (a filename that contains a literal colon and single literal backslashes) and place a copy in the same directory as app.exe.

  2. Copy “This.file” to “/BLAH/This.file”

No matter what value of MONO_IOMAP I use, the app still manages to complain about not being able to find “This.file”.

I know next to nothing about .NET (I develop C++ and Python apps under Linux), and this is my first time experimenting with Mono, so I could easily be missing some fundamental clues.

The Mono documentation for MONO_IOMAP provides no specific examples of the transformations it enables (preventing a copy-paste-try approach), nor does it provide contextual advice for its use. Web searches failed to uncover much of anything.

Anything else I should try?

Advertisement

Answer

Hard-coded Windows drives are an issue as things such as “C:” are valid directories.

The ‘easiest’ way around this is to actually create the full Window “drive” path and use MONO_IOMAP=case, the ‘best’ way is to correct the code 😉

Assuming your program hard-codes @”C:BLAHThis.file” or @”BLAHThis.file”, then create those paths based on where your CIL .exe is being run:

Directory Structure:

tree
.
├── C:
│   └── blah
│       └── This.file
├── blah
│   └── This.file
└── monoio.exe

Example output using MONO_IOMAP=case

MONO_IOMAP=case mono monoio.exe
BLAHThis.file
works....
C:BLAHThis.file
works....

Example Code:

using System;
using System.IO;

namespace monoio
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            var hardPath = @"BLAHThis.file";
            Console.WriteLine (hardPath);
            FileStream file;
            try {
                file = File.Open (hardPath, FileMode.Open);
                file.Close ();
                Console.WriteLine("works....");
            } catch (Exception ex) {
                Console.WriteLine (ex.Message);
            }

            var hardPathVolume = @"C:BLAHThis.file";
            Console.WriteLine (hardPathVolume);
            try {
                file = File.Open (hardPathVolume, FileMode.Open);
                file.Close ();
                Console.WriteLine("works....");
            } catch (Exception ex) {
                Console.WriteLine (ex.Message);
            } 
        }
    }
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement