简体   繁体   中英

Xamarin.Android PackageInstaller Session.commit “Files still open” Exception on apk silent install

I'm trying to code a proof of concept, with Xamarin android . A sort of EMM tool, ie an application which will be on charge to install other application and manage the device. So Android Marshmallow is a good start with android for work features.

My app is Device Owner therefore it should have no problem to silently install other applications. It can download an apk from a website without a problem. But when I try to install it, it throws an " Files still open " exception despite of calling all Close() methods.

I have taken my code from the example of the excellent android-testdpc sample on github here

I have changed it for it work in c# with Xamarin.

Here is my code :

    public static bool InstallPackage(Context context, Handler handler, InputStream input, String packageName)
    {
        try
        {
            PackageInstaller packageInstaller = context.PackageManager.PackageInstaller;
            PackageInstaller.SessionParams param = new PackageInstaller.SessionParams(PackageInstallMode.FullInstall);
            param.SetAppPackageName(packageName);
            // set params
            int sessionId = packageInstaller.CreateSession(param);
            PackageInstaller.Session session = packageInstaller.OpenSession(sessionId);
            using (System.IO.Stream output = session.OpenWrite("COSU", 0, -1))
            {
                byte[] buffer = new byte[65536];
                int c;
                while ((c = input.Read(buffer)) != -1)
                {
                    output.Write(buffer, 0, c);
                }
                session.Fsync(output);
                input.Close();
                output.Close();
            }
            session.Commit(createIntentSender(context, sessionId)); // this line throws exception 'Files stil open'
            return true;
        }
        catch (Exception ex)
        {
            Log.Error(TAG, "Error installing package: " + packageName, ex);
            handler.SendMessage(handler.ObtainMessage(Common.MSG_INSTALL_FAIL,
                    packageName));
            return false;
        }
    }

I'm stuck with this for the moment. if I have the time I will try to install android studio and test my code in java to see if the problem come from Xamarin.

If someone got any clue for my problem I will really appreciate the help

SecurityException : if streams opened through openWrite(String, long, long) are still open.

The Java peer object is not closed yet, this is how I force it for the PackageInstaller.Session.Commit :

var input = Assets.Open(packageName);
var packageInstaller = PackageManager.PackageInstaller;
var sessionParams = new PackageInstaller.SessionParams(PackageInstallMode.FullInstall);
sessionParams.SetAppPackageName(packageName);
int sessionId = packageInstaller.CreateSession(sessionParams);
var session = packageInstaller.OpenSession(sessionId);
using (var output = session.OpenWrite(packageName, 0, -1))
{
    input.CopyTo(output);
    session.Fsync(output);
    foreach (var name in session.GetNames())
        Log.Debug("Installer", name);
    output.Close();
    output.Dispose();
    input.Close();
    input.Dispose();
    GC.Collect();
}
var pendingIntent = PendingIntent.GetBroadcast(BaseContext, sessionId, new Intent(Intent.ActionInstallPackage), 0);
session.Commit(pendingIntent.IntentSender);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM