2016-10-15 4 views
3

Ma commande gksudo actuelle fonctionne avec Process.spawn_async_with_pipes. Cependant, si je change de gksudo avec pkexec, la fenêtre pkexec n'est pas affichée et la commande se termine directement sans l'invite et ne renvoie rien. Lorsque j'utilise Process.spawn_command_line_sync avec la même commande pkexec, il affiche l'invite pour demander le mot de passe et les commandes s'exécutent correctement et retournent le résultat.spawn processus asynchrone ne fonctionne pas avec pkexec

Ma principale raison d'utiliser pkexec est d'utiliser polkit et de ne pas inviter l'utilisateur à des utilisations ultérieures de la commande qui nécessite des permissions root.

Ma méthode pour le code Process.spawn_async_with_pipes est indiquée ci-dessous. J'ai besoin d'aide pour faire en sorte que pkexec fonctionne en arrière-plan. L'invite devrait bloquer le gui mais une fois que l'utilisateur aura fourni le mot de passe, il devra retourner le contrôle au gui et continuer l'exécution en arrière-plan. C'est exactement ce qui se passe avec gksudo.

Merci à l'avance

Ceci est la méthode async

public int execute_sync_multiarg_command_pipes(string[] spawn_args) { 
     debug("Starting to execute async command: "+string.joinv(" ", spawn_args)); 
     spawn_async_with_pipes_output.erase(0, -1); //clear the output buffer 
     MainLoop loop = new MainLoop(); 
     try { 
      string[] spawn_env = Environ.get(); 
      Pid child_pid; 

      int standard_input; 
      int standard_output; 
      int standard_error; 

      Process.spawn_async_with_pipes ("/", 
       spawn_args, 
       spawn_env, 
       SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
       null, 
       out child_pid, 
       out standard_input, 
       out standard_output, 
       out standard_error); 

      // capture stdout: 
      IOChannel output = new IOChannel.unix_new (standard_output); 
      output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stdout"); 
      }); 

      // capture stderr: 
      IOChannel error = new IOChannel.unix_new (standard_error); 
      error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stderr"); 
      }); 

      ChildWatch.add (child_pid, (pid, status) => { 
       // Triggered when the child indicated by child_pid exits 
       Process.close_pid (pid); 
       loop.quit(); 
      }); 
      loop.run(); 
     } catch(SpawnError e) { 
      warning("Failure in executing async command ["+string.joinv(" ", spawn_args)+"] : "+e.message); 
      spawn_async_with_pipes_output.append(e.message); 
     } 
     debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]..."); 
     return 0; 
    }` 

Voici comment il est appelé:

execute_sync_multiarg_command_pipes({"pkexec", COMMAND_USING_SUDO[6]}); 
+0

Quelques choses. Utilisez-vous Linux ou Windows? Vous voudrez peut-être vérifier votre lien. Cela ne fonctionne pas pour moi. Troisièmement, pourquoi utilisez-vous 'spawn_async_with_pipes' quand les docs que vous référencez sont' spawn_async'? Juste curieux. Vous posez d'excellentes questions cependant. – oldtechaa

+0

@oldtechaa Y a-t-il même un port de kit de politique pour Windows? –

+0

Veuillez fournir un [MVCE] (https://stackoverflow.com/help/mcve) (c'est-à-dire un exemple de code minimal que nous pouvons examiner). –

Répondre

0

Frai une commande fonctionne de pkexec async:

public static int main (string[] args) { 
    MainLoop loop = new MainLoop(); 
    try { 
     string[] spawn_args = {"pkexec", "ls", "-l", "-h"}; 
     string[] spawn_env = Environ.get(); 
     Pid child_pid; 

     Process.spawn_async ("/", 
      spawn_args, 
      spawn_env, 
      SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
      null, 
      out child_pid); 

     ChildWatch.add (child_pid, (pid, status) => { 
      // Triggered when the child indicated by child_pid exits 
      Process.close_pid (pid); 
      loop.quit(); 
     }); 

     loop.run(); 
    } catch (SpawnError e) { 
     stdout.printf ("Error: %s\n", e.message); 
    } 
    return 0; 
} 

Le p Rompt arrive et la liste des fichiers résultants est de mon répertoire "/ root" comme prévu.

Donc le problème doit être ailleurs.

Il fonctionne également avec des tuyaux:

private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) { 
    if (condition == IOCondition.HUP) { 
     stdout.printf ("%s: The fd has been closed.\n", stream_name); 
     return false; 
    } 

    try { 
     string line; 
     channel.read_line (out line, null, null); 
     stdout.printf ("%s: %s", stream_name, line); 
    } catch (IOChannelError e) { 
     stdout.printf ("%s: IOChannelError: %s\n", stream_name, e.message); 
     return false; 
    } catch (ConvertError e) { 
     stdout.printf ("%s: ConvertError: %s\n", stream_name, e.message); 
     return false; 
    } 

    return true; 
} 

public static int main (string[] args) { 
    MainLoop loop = new MainLoop(); 
    try { 
     string[] spawn_args = {"pkexec", "ls", "-l", "-h"}; 
     string[] spawn_env = Environ.get(); 
     Pid child_pid; 

     int standard_input; 
     int standard_output; 
     int standard_error; 

     Process.spawn_async_with_pipes ("/", 
      spawn_args, 
      spawn_env, 
      SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
      null, 
      out child_pid, 
      out standard_input, 
      out standard_output, 
      out standard_error); 

     // stdout: 
     IOChannel output = new IOChannel.unix_new (standard_output); 
     output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
      return process_line (channel, condition, "stdout"); 
     }); 

     // stderr: 
     IOChannel error = new IOChannel.unix_new (standard_error); 
     error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
      return process_line (channel, condition, "stderr"); 
     }); 

     ChildWatch.add (child_pid, (pid, status) => { 
      // Triggered when the child indicated by child_pid exits 
      Process.close_pid (pid); 
      loop.quit(); 
     }); 

     loop.run(); 
    } catch (SpawnError e) { 
     stdout.printf ("Error: %s\n", e.message); 
    } 
    return 0; 
} 

Même ce (qui comprend maintenant votre exemple fragment de code) fonctionne:

StringBuilder spawn_async_with_pipes_output; 

private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) { 
    if (condition == IOCondition.HUP) { 
     stdout.printf ("%s: The fd has been closed.\n", stream_name); 
     return false; 
    } 

    try { 
     string line; 
     channel.read_line (out line, null, null); 
     stdout.printf ("%s: %s", stream_name, line); 
    } catch (IOChannelError e) { 
     stdout.printf ("%s: IOChannelError: %s\n", stream_name, e.message); 
     return false; 
    } catch (ConvertError e) { 
     stdout.printf ("%s: ConvertError: %s\n", stream_name, e.message); 
     return false; 
    } 

    return true; 
} 

public int execute_sync_multiarg_command_pipes(string[] spawn_args) { 
     debug("Starting to execute async command: "+string.joinv(" ", spawn_args)); 
     spawn_async_with_pipes_output.erase(0, -1); //clear the output buffer 
     MainLoop loop = new MainLoop(); 
     try { 
      string[] spawn_env = Environ.get(); 
      Pid child_pid; 

      int standard_input; 
      int standard_output; 
      int standard_error; 

      Process.spawn_async_with_pipes ("/", 
       spawn_args, 
       spawn_env, 
       SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
       null, 
       out child_pid, 
       out standard_input, 
       out standard_output, 
       out standard_error); 

      // capture stdout: 
      IOChannel output = new IOChannel.unix_new (standard_output); 
      output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stdout"); 
      }); 

      // capture stderr: 
      IOChannel error = new IOChannel.unix_new (standard_error); 
      error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stderr"); 
      }); 

      ChildWatch.add (child_pid, (pid, status) => { 
       // Triggered when the child indicated by child_pid exits 
       Process.close_pid (pid); 
       loop.quit(); 
      }); 
      loop.run(); 
     } catch(SpawnError e) { 
      warning("Failure in executing async command ["+string.joinv(" ", spawn_args)+"] : "+e.message); 
      spawn_async_with_pipes_output.append(e.message); 
     } 
     debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]..."); 
     return 0; 
    } 

public static int main (string[] args) { 
    spawn_async_with_pipes_output = new StringBuilder(); 
    execute_sync_multiarg_command_pipes ({"pkexec", "ls", "-l", "-h"}); 
    return 0; 
} 
+0

Merci beaucoup. mon code fonctionnait tout le temps. J'appelais incorrectement la méthode execute_sync_multiarg_command_pipes! J'ai accepté votre réponse ci-dessus. Comme c'est un exemple complet, cela pourrait aider quelqu'un à essayer d'utiliser la méthode asynchrone –