コード例 #1
0
        public static string ExtractNativeResource <T>(string resource, ABI abi)
        {
            var    split    = resource.Split('.');
            var    basePath = AppDomain.CurrentDomain.BaseDirectory;
            string path;

            if (!abi.IsWindows())
            {
                // On Windows, LoadLibrary makes it available for DllImport
                // regardless of the location. On Linux, we need to
                // set LD_LIBRARY_PATH which is not possible to do from
                // already running app that needs it. Extracting to the current
                // directory is the simplest thing:
                // - we do not support WoW64-like thing on Linux even if it exists, only 64 bit on Linux so far
                // - location should be writable, while /usr/lib and /usr/local/lib are not writeable
                // - on Windows there was IIS issue - it was reloading every time content changed,
                // that is why we used temp folder.

                // TODO currently need <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
                // otherwise managed dll is in NuGet folder, while native is extracted into local bin
                // folder. This flag is consistent with donet publish behavior that will place all
                // dlls in one place, so it's OK for now.

                path = Path.Combine(basePath, split[2] + "." + split[3]);
                if (File.Exists(path))
                {
                    return(path);
                }
            }
            else
            {
                // On Windows same manages dll could be run from both x32/x64
                // but LoadLibrary makes P/Invoke "just work" (TM)
                basePath = Path.Combine(basePath, split[1]);
                if (!Directory.Exists(basePath))
                {
                    Directory.CreateDirectory(basePath);
                }
                path = Path.Combine(basePath, split[2] + "." + split[3]);
                if (File.Exists(path))
                {
                    return(path);
                }
            }

            try
            {
                using (Stream resourceStream = GetResourceStream <T>(resource))
                {
                    using (DeflateStream deflateStream = new DeflateStream(resourceStream, CompressionMode.Decompress))
                    {
                        using (
                            FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write,
                                                                   FileShare.ReadWrite))
                        {
                            byte[] buffer = new byte[1048576];
                            int    bytesRead;
                            do
                            {
                                bytesRead = deflateStream.Read(buffer, 0, buffer.Length);
                                if (bytesRead != 0)
                                {
                                    fileStream.Write(buffer, 0, bytesRead);
                                }
                            }while (bytesRead != 0);
                        }
                    }
                }
                return(path);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                File.Delete(path);
                return(null);
            }
        }