/// OSVR-Unity Connection
///
///
/// Copyright 2014 Sensics, Inc.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace OSVR
{
namespace Unity
{
public class DLLSearchPathFixer
{
///
/// Call in a static constructor of an object depending on native code.
///
/// It is required if that native DLL being accessed depends on other native DLLs alongside it.
///
public static void fix()
{
// Amend DLL search path - see http://forum.unity3d.com/threads/dllnotfoundexception-when-depend-on-another-dll.31083/#post-1042180
// for original inspiration for this code.
var fixer = new DLLSearchPathFixer();
fixer.ConditionallyAddRelativeDir("Plugins");
fixer.ConditionallyAddRelativeDir(new List() { "Plugins", IntPtr.Size == 4 ? "x86" : "x86_64" });
fixer.ApplyChanges();
}
///
/// Constructor for private use as a helper within the static fix() method.
///
private DLLSearchPathFixer()
{
#if !UNITY_WINRT
var currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
//Debug.Log(String.Format("Old PATH: {0}", currentPath));
OrigDirs = new List(currentPath.Split(Path.PathSeparator));
UnityDataDir = Application.dataPath;
UnityDataDirBackslashed = Application.dataPath.Replace("/", "\\");
#endif
}
///
/// Update the process environment PATH variable to contain the full list (entries new and old) of directories.
///
private void ApplyChanges()
{
#if !UNITY_WINRT
// Combine new and old dirs
var allDirs = new List(NewDirs);
allDirs.AddRange(OrigDirs);
var newPathString = String.Join(Path.PathSeparator.ToString(), allDirs.ToArray());
//Debug.Log(String.Format("New PATH: {0}", newPathString));
Environment.SetEnvironmentVariable("PATH", newPathString, EnvironmentVariableTarget.Process);
#endif
}
///
/// If a directory specified relative to the Unity data dir is not yet in the PATH, add it.
///
/// Components of a directory name relative to the Unity data dir.
private void ConditionallyAddRelativeDir(List dirComponents)
{
ConditionallyAddRelativeDir(PathTools.Combine(dirComponents));
}
///
/// If a directory specified relative to the Unity data dir is not yet in the PATH, add it.
///
/// A directory name relative to the Unity data dir.
private void ConditionallyAddRelativeDir(string relativePortion)
{
if (IsRelativeDirIncludedInPath(relativePortion))
{
// early out.
return;
}
NewDirs.Add(PathTools.Combine(UnityDataDir, relativePortion));
}
///
/// Checks to see if a directory specified relative to the Unity data dir is included in the path so far.
/// It checks using both forward-slashed and backslashed versions of the Unity data dir.
///
/// Directory relative to the Unity data dir
/// true if the given directory is included in the path so far
private bool IsRelativeDirIncludedInPath(string relativePortion)
{
return IsIncludedInPath(PathTools.Combine(UnityDataDir, relativePortion)) || IsIncludedInPath(PathTools.Combine(UnityDataDirBackslashed, relativePortion));
}
///
/// Checks to see if a directory is included in the path so far (both new and old directories).
///
/// Directory name
/// true if the given directory name is found in either the new or old directory lists.
private bool IsIncludedInPath(string dir)
{
return NewDirs.Contains(dir) || OrigDirs.Contains(dir);
}
private string UnityDataDir = string.Empty;
private string UnityDataDirBackslashed = string.Empty;
private List NewDirs = new List();
private List OrigDirs = null;
///
/// Utilities for combining path components with a wider variety of input data types than System.IO.Path.Combine
///
private class PathTools
{
internal static string Combine(string a, string b)
{
return Path.Combine(a, b);
}
internal static string Combine(string[] components)
{
return String.Join(Path.DirectorySeparatorChar.ToString(), components);
}
internal static string Combine(List components)
{
return PathTools.Combine(components.ToArray());
}
}
}
}
}