Pytanie łączenie prekompilowanych plików binarnych w aplikację elektronów


Czy istnieje dobre rozwiązanie, w jaki sposób włączyć wstępnie skompilowane pliki binarne, takie jak imagemagick, do aplikacji elektronowej? istnieją moduły node.js, ale wszystkie są opakowaniem lub natywnym powiązaniem z bibliotekami instalowanymi na całym systemie. Zastanawiam się, czy możliwe jest wiązanie prekompilowanych plików binarnych w ramach dystrybucji.


18
2017-10-15 15:27


pochodzenie


Zobacz moją odpowiedź na to drugie WIĘC pytanie - gimenete


Odpowiedzi:


Znalazłem rozwiązanie tego problemu, ale nie mam pojęcia, czy jest to uważane za najlepszą praktykę. Nie mogłem znaleźć żadnej dobrej dokumentacji, włączając w to prekompilowane pliki binarne innych firm, więc po prostu bawiłem się nim, aż w końcu pracował z moim plikiem binarnym ffmpeg. Oto co zrobiłem (zaczynając od szybkiego uruchomienia elektronu, node.js v6):

Metoda Mac OS X

Z katalogu aplikacji uruchomiłem następujące polecenia w Terminalu, aby uwzględnić binarny plik ffmpeg jako moduł:

mkdir node_modules/ffmpeg
cp /usr/local/bin/ffmpeg node_modules/ffmpeg/
cd node_modules/.bin
ln -s ../ffmpeg/ffmpeg ffmpeg

(zastąpić /usr/local/bin/ffmpeg z twoją bieżącą ścieżką binarną, pobierz ją stąd) Umieszczenie łącza dozwolonego pakującego elektrony w celu włączenia zapisanego pliku binarnego do node_modules/ffmpeg/.

Następnie, aby uzyskać ścieżkę dołączonej aplikacji (tak, żebym mógł użyć bezwzględnej ścieżki dla mojego binarnego ... względne ścieżki nie działały bez względu na to, co zrobiłem) Zainstalowałem pakiet npm package-root-dir, uruchamiając następujące dowództwo:

npm i -S app-root-dir

Teraz, gdy miałem katalog aplikacji root, po prostu dołączam podfolder do mojego pliku binarnego i od tego miejsca. To jest kod, który umieściłem w renderer.js :.

var appRootDir = require('app-root-dir').get();
var ffmpegpath=appRootDir+'/node_modules/ffmpeg/ffmpeg';
console.log(ffmpegpath);

const
    spawn = require( 'child_process' ).spawn,
    ffmpeg = spawn( ffmpegpath, ['-i',clips_input[0]]);  //add whatever switches you need here

ffmpeg.stdout.on( 'data', data => {
     console.log( `stdout: ${data}` );
    });
   ffmpeg.stderr.on( 'data', data => {
console.log( `stderr: ${data}` );
    });

Metoda Windows

  1. Otwórz swój folder elektronów (domyślnym skrótem elektron-start jest nazwa domyślna), a następnie przejdź do folderu node_modules. Utwórz tam folder o nazwie ffmpeg i skopiuj swój statyczny plik binarny do tego katalogu. Uwaga: musi to być statyczna wersja twojego pliku binarnego, dla ffmpeg chwyciłem najnowszą kompilację Windows tutaj.
  2. Aby uzyskać ścieżkę dołączonej aplikacji (tak, żebym mógł użyć bezwzględnej ścieżki dla mojego binarnego ... względne ścieżki nie działały bez względu na to, co zrobiłem) zainstalowałem pakiet npm package-root-dir, uruchamiając następujące polecenie z wiersza poleceń w moim katalogu aplikacji:

     npm i -S app-root-dir
    
  3. W folderze node_modules przejdź do podfolderu .bin. Trzeba tutaj utworzyć kilka plików tekstowych, aby powiadomić węzeł o dołączonym właśnie pliku binarnego exe. Użyj ulubionego edytora tekstu i utwórz dwa pliki, jeden o nazwie ffmpeg z następującą treścią:

    #!/bin/sh
    basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
    
    case `uname` in
        *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
    esac
    
    if [ -x "$basedir/node" ]; then
      "$basedir/node"  "$basedir/../ffmpeg/ffmpeg" "$@"
      ret=$?
    else
      node  "$basedir/../ffmpeg/ffmpeg" "$@"
      ret=$?
    fi
    exit $ret
    

    A drugi plik tekstowy o nazwie ffmpeg.cmd:

    @IF EXIST "%~dp0\node.exe" (
     "%~dp0\node.exe"  "%~dp0\..\ffmpeg\ffmpeg" %*
    ) ELSE (
       @SETLOCAL
     @SET PATHEXT=%PATHEXT:;.JS;=;%
     node  "%~dp0\..\ffmpeg\ffmpeg" %*
    )
    

Następnie możesz uruchomić ffmpeg w swojej dystrybucji elektronów Windows (w renderer.js) w następujący sposób (używam również modułu węzła app-root-dir). Zwróć uwagę na cytaty dodane do ścieżki binarnej, jeśli aplikacja jest zainstalowana w katalogu ze spacjami (np C:\Program Files\YourApp) nie będzie bez nich działać.

var appRootDir = require('app-root-dir').get();
var ffmpegpath = appRootDir + '\\node_modules\\ffmpeg\\ffmpeg';

const
    spawn = require( 'child_process' ).spawn;
    var ffmpeg = spawn( 'cmd.exe', ['/c',  '"'+ffmpegpath+ '"', '-i', clips_input[0]]);  //add whatever switches you need here, test on command line first
ffmpeg.stdout.on( 'data', data => {
     console.log( `stdout: ${data}` );
 });
ffmpeg.stderr.on( 'data', data => {
     console.log( `stderr: ${data}` );
 });

10
2017-07-14 11:43



Aby było jasne, ta metoda wykorzystuje aplikację elektron-packager i wstępnie skompilowany plik binarny ffmpeg. [Powiązanie modułów z aplikacją elektronów] powyżej. - UltrasoundJelly
Czy mógłbyś wyjaśnić ln -s ../ffmpeg/ffmpeg node_modules/.bin/ffmpeg Czy łączysz link ffmpeg skopiować właśnie wykonałeś? Czy zmieniłeś katalog wcześniej ln -s? - Jake
Przepraszam, kod był niepoprawny. Zmieniłem katalogi, a następnie utworzyłem łącze. Dodano i zmieniono kod. - UltrasoundJelly
Uratowałeś mi życie. :-) Działa wspaniale z dcraw do konwersji surowego obrazu w mojej aplikacji elektronowej - zinne
cieszę się, że to pomogło. Właśnie dodałem metodę Windows. - UltrasoundJelly


Oto kolejna metoda przetestowana dotychczas na Macach i Windows. Wymaga pakietu "app-root-dir", nie wymaga ręcznego dodawania czegokolwiek do node_modules dir.

  1. Umieść swoje pliki pod resources / $ os/, gdzie $ os jest albo "prochowiec", "linux", lub "zdobyć". Proces kompilacji skopiuje pliki z tych katalogów zgodnie z docelowym systemem kompilacji.

  2. Położyć extraFiles opcja w twoich konfiguracjach kompilacji w następujący sposób:

package.json

  "build": {
    "extraFiles": [
      {
        "from": "resources/${os}",
        "to": "Resources/bin",
        "filter": ["**/*"]
      }
    ],
  1. Użyj czegoś takiego, aby określić bieżącą platformę.

get-platform.js

import { platform } from 'os';

export default () => {
  switch (platform()) {
    case 'aix':
    case 'freebsd':
    case 'linux':
    case 'openbsd':
    case 'android':
      return 'linux';
    case 'darwin':
    case 'sunos':
      return 'mac';
    case 'win32':
      return 'win';
  }
};
  1. Wywołaj plik wykonywalny z aplikacji w zależności od środowiska i systemu operacyjnego. Zakładam, że wersje wbudowane są w trybie produkcyjnym, a wersje źródłowe w innych trybach, ale można utworzyć własną logikę wywoływania.
import { join as joinPath, dirname } from 'path';
import { exec } from 'child_process';

import appRootDir from 'app-root-dir';

import env from './env';
import getPlatform from './get-platform';

const execPath = (env.name === 'production') ?
  joinPath(dirname(appRootDir.get()), 'bin'):
  joinPath(appRootDir.get(), 'resources', getPlatform());

const cmd = `${joinPath(execPath, 'my-executable')}`;

exec(cmd, (err, stdout, stderr) => {
  // do things
});

Myślę, że używałem konstruktor elektronów jako podstawa, generacja plików env jest z nim. Zasadniczo jest to tylko plik konfiguracyjny JSON.


8
2017-07-17 19:28





tl; dr:

tak, możesz! ale wymaga to napisania własnego, niezależnego dodatku, który nie zakłada żadnych założeń na temat bibliotek systemowych. Ponadto w niektórych przypadkach musisz się upewnić, że twój dodatek jest skompilowany dla pożądanego systemu operacyjnego.


Podzielmy to pytanie na kilka części:

- Dodatki (Rodzime moduły):

Dodatki to dynamicznie połączone obiekty udostępnione.

Innymi słowy, możesz po prostu napisać swój własny addon bez zależności od bibliotek systemowych (na przykład statycznie łącząc wymagane moduły) zawierające cały potrzebny kod.

Musisz wziąć pod uwagę, że takie podejście jest zależne od systemu operacyjnego, co oznacza, że ​​musisz skompilować swój dodatek do każdego systemu operacyjnego, który chcesz obsługiwać! (w zależności od tego, z jakich innych bibliotek możesz korzystać)

- Rodzime moduły dla elektronu:

Rodzime moduły Node są obsługiwane przez Electron, ale ponieważ Electron używa innej wersji V8 z oficjalnego Node, musisz ręcznie określić położenie nagłówków Electrona podczas budowania rodzimych modułów

Oznacza to, że natywny moduł, który został zbudowany na podstawie nagłówków węzłów, musi zostać przebudowany, aby mógł być użyty wewnątrz elektronu. Możesz znaleźć w dokumentach elektronowych.

- Zestaw modułów z aplikacją elektronów:

Przypuszczam, że chcesz mieć swoją aplikację jako samodzielny plik wykonywalny bez konieczności instalowania elektronów na swoich maszynach. Jeśli tak, mogę zasugerować użycie pakujący elektrony.


6
2017-10-20 17:29



więc mogłem po prostu pobrać wstępnie skompilowane imagemagick dla każdego systemu operacyjnego, spakować je w podfolderze i wykonać przeciwko niemu? - Tobias
edit: jak w przełączniku, jeśli jest to system Windows, używam imagemagick.exe itp - Tobias
@Tobias, jeśli otrzymasz plik wykonywalny, możesz po prostu uruchomić program za pomocą child_process moduł. Aby móc korzystać z funkcji biblioteki, potrzebujesz całego natywnego podejścia do dodatków. - Yan Foto
Czy kiedykolwiek zastanawiałeś się, jak połączyć swoją aplikację z prekompilowanym plikiem binarnym? - UltrasoundJelly