YehudaKremer / msix

Create Msix installer for flutter windows-build files.
https://pub.dev/packages/msix
MIT License
280 stars 70 forks source link

[BUG] App with sqlite3.dll, only works as admin #76

Closed filipenanclarez closed 2 years ago

filipenanclarez commented 2 years ago

:information_source: Info

Version: v2.8.1

:speech_balloon: Description

After flutter build windows i put sqlite3.dll on output folder. Then run flutter pub run msix:create. Then make install with msix in a new clean computer. In app folder c:\program files\windowsapps\myapp the sqlite3.dll is there, alright. But if i run the app from start menu, app cannot load dll. If i run from the folder, then app can load dll and works correctly. If i run from start menu as admin, then app can load dll and works correctly. So i think problem is related with some permissions to run with capabilities to execute thirty party dlls, but i can't find in documentation. I'm using https://pub.dev/packages/sqflite_common_ffi package, and if i run .exe from folder, with sqlite3.dll on same folder as .exe, work correctly. Only with msix instalation and then run from start menu as common user is problem.

:scroll: Pubspec.yaml

name: xxxxxxxxx
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: ">=2.15.1 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  webview_windows: ^0.1.2
  webview_flutter: ^3.0.0
  flutter_vector_icons: ^1.0.0  
  sqflite: ^2.0.1
  path: ^1.8.0
  sqflite_common_ffi: ^2.1.0
  file_picker: ^4.3.1
  archive: ^3.1.6
  html: ^0.15.0  
  charset: ^0.2.0
  hive: ^2.0.5
  http: ^0.13.4
  path_provider: ^2.0.8
  xml: ^5.3.1
  url_launcher: ^6.0.17
  flutter_easyloading: ^3.0.3
  move_to_background: ^1.0.2
  cryptography: ^2.0.5
  share_plus: ^3.0.4
  bitsdojo_window: ^0.1.1+1  

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_launcher_icons_maker: "^0.10.1"
  msix: ^2.8.1

flutter_icons:
  android: true
  ios: true
  windows: true
  remove_alpha_ios: true
  image_path: "assets/icon/icon.png"
  image_path_android: "assets/icon/android_icon.png"
  image_path_ios: "assets/icon/ios_icon.png"

flutter:
  uses-material-design: true
  assets:
    - assets/nocover.png
    - assets/nocover.jpg
  fonts:
    - family: Roboto Mono
      fonts:
        - asset: assets/RobotoMono-Regular.ttf
    - family: M1
      fonts:
        - asset: assets/fonts/mplus-1m-regular.ttf
    - family: Ubuntu
      fonts:
        - asset: assets/fonts/UbuntuMono-R.ttf

msix_config:
  display_name: XXXXX
  publisher_display_name: XXXX
  logo_path: "assets/icon/icon.png"
YehudaKremer commented 2 years ago

Hey

Can you please try this with the assets_directory_path folder, See: https://github.com/YehudaKremer/msix#file_folder-dll-files-and-assets-ffi-library

Let see if its resolve the admin problem

filipenanclarez commented 2 years ago

Hey

Can you please try this with the assets_directory_path folder, See: https://github.com/YehudaKremer/msix#file_folder-dll-files-and-assets-ffi-library

Let see if its resolve the admin problem

I already tried, but the package put the dll in a subfolder, then not work. How can i do to make package put the dll in root folder?

YehudaKremer commented 2 years ago

Please try this: https://github.com/YehudaKremer/msix/issues/72#issuecomment-1003711861

filipenanclarez commented 2 years ago

Please try this: #72 (comment)

Tried, but problem still works.

But i found the problem.

Not related to your package, sorry for this.

But if somebody need the solution, here a explanation:

When chosse the path of database file, if we use this function databaseFactoryFfi.getDatabasesPath() then the location of final release return c:\windows\system32\.dart_tool\sqflite_common_ffi\databases. But this directory require admin permissions to read/write.

So for fix, i change my code to use path_provider and get the directory with getApplicationSupportDirectory() function. Then everything works now.

Here my peace of code for who need help:

BEFORE:

 Future<Database> openConnection() async {
    sqfliteFfiInit();

    final databasePah = await databaseFactoryFfi.getDatabasesPath();  <<< HERE THE PROBLEM

    var databasePathFinal = join(databasePah.path, _DATABASE_NAME);

    DatabaseFactory databaseFactory = databaseFactoryFfi;

    _db = await databaseFactory.openDatabase(databasePathFinal,
           options: OpenDatabaseOptions( ...
           ...

AFTER:

 Future<Database> openConnection() async {
    sqfliteFfiInit();

    final databasePah = await pathprovider.getApplicationSupportDirectory();   <<< HERE THE SOLUTION

    var databasePathFinal = join(databasePah.path, _DATABASE_NAME);

    DatabaseFactory databaseFactory = databaseFactoryFfi;

    _db = await databaseFactory.openDatabase(databasePathFinal,
           options: OpenDatabaseOptions( ...
           ...
YehudaKremer commented 2 years ago

Wonderful👍 Thanks for sharing your solution