PackageKit DBus-API und nur Probleme...

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

PackageKit DBus-API und nur Probleme...

Beitrag von Targion »

Hallo!
Für die PackageKit Integration in mein Projekt würde ich gerne die DBus-Schnittstelle benutzen. Also erstmal PackageKit über Git geholt, kompiliert und installiert. Bevor ich den Code auf Pascal umschreibe wollte ich die API noch mit einem Python-Script, welches auch offiziell als Demo existiert, testen:

Code: Alles auswählen

import dbus
 
try:
    bus = dbus.SessionBus()
except dbus.DBusException, e:
    print 'Unable to connect to dbus: %s' % str(e)
    sys.exit()
try:
    proxy = bus.get_object('org.freedesktop.PackageKit', '/org/freedesktop/PackageKit')
    iface = dbus.Interface(proxy, 'org.freedesktop.PackageKit')
    iface.InstallPackageName('amor')
except dbus.DBusException, e:
    print 'Unable to use PackageKit: %s' % str(e)
Zuerst bekam ich die Meldung:

Code: Alles auswählen

Unable to use PackageKit: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.PackageKit was not provided by any .service files
Deshalb habe ich im Ordner /usr/share/dbus-1/services manuell eine Datei mit folgendem Inhalt erstellt:

Code: Alles auswählen

[D-BUS Service]
Name=org.freedesktop.PackageKit
Exec=/usr/sbin/packagekitd --disable-timer
User=root
Jetzt bekomme ich folgende Meldung:

Code: Alles auswählen

Unable to use PackageKit: org.freedesktop.DBus.Error.Spawn.ChildExited: Launch helper exited with unknown return code 0
oder als Root, wenn der Daemon noch nicht läuft:

Code: Alles auswählen

Unable to use PackageKit: org.freedesktop.DBus.Error.NoReply: Did not receive areply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
Das heißt der Daemon antwortet überhaupt nicht auf die Anfragen, oder die DBus-verbindung verbietet die Anfrage.
Ist rein zufällig ein PackageKit Entwickler da? Weiß jemand, wie man den Fehler beheben kann? Ich kenne mich mit DBus unter Linux noch nicht so supergut aus, vielleicht mache ich auch irgendwas falsch.
Getestetes Linuxsystem: K/Ubuntu 8.10

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: PackageKit DBus-API und nur Probleme...

Beitrag von marcov »

Targion hat geschrieben:Hallo!
Für die PackageKit Integration in mein Projekt würde ich gerne die DBus-Schnittstelle benutzen. Also erstmal PackageKit über Git geholt, kompiliert und installiert. Bevor ich den Code auf Pascal umschreibe wollte ich die API noch mit einem Python-Script, welches auch offiziell als Demo existiert, testen:
Ein GCC Vorbild macht mehr Sinn als ein Python script. Das ist viel directer zu uebersetzen.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: PackageKit DBus-API und nur Probleme...

Beitrag von Targion »

Das macht doch auch nichts andere als Python oder? Und Python ist viel schneller zum Testen. Mit einem Pascal-Test gab's übrigens dasselbe Ergebnis.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: PackageKit DBus-API und nur Probleme...

Beitrag von Targion »

Ich habe eben noch einen Test unter openSUSE gemacht: Da funktioniert's tadellos.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: PackageKit DBus-API und nur Probleme...

Beitrag von Targion »

Hallo! Lag tatsächlich am Python-Script!
Ich habe jetzt folgende Pascal-Variante aus einem Beispiel erstellt:

Code: Alles auswählen

{
 * Call a method on a remote object
 }
procedure PaxkageKit_InstallPkgName(param: PChar);
var
  msg: PDBusMessage;
  args: DBusMessageIter;
  pending: PDBusPendingCall;
  stat: Boolean;
  level: dbus_uint32_t;
 //
  err: DBusError;
  conn: PDBusConnection;
  ret: cint;
begin
{ Initializes the errors }
  dbus_error_init(@err);
 
  { Connection }
  conn := dbus_bus_get(DBUS_BUS_SESSION, @err);
 
  if dbus_error_is_set(@err) <> 0 then
  begin
    WriteLn('Connection Error: ' + err.message);
    dbus_error_free(@err);
  end;
 
  if conn = nil then Exit;
 
  WriteLn('Calling remote method with ', param);
 
  { Request the name of the bus }
  ret := dbus_bus_request_name(conn, 'org.freedesktop.PackageKit', DBUS_NAME_FLAG_REPLACE_EXISTING, @err);
 
dbus_g_proxy_call
  if dbus_error_is_set(@err) <> 0 then
  begin
    WriteLn('Name Error: ' + err.message);
    dbus_error_free(@err);
  end;
 
  if ret <> DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER then Exit;
 
  // create a new method call and check for errors
  msg := dbus_message_new_method_call('org.freedesktop.PackageKit', // target for the method call
                                      '/org/freedesktop/PackageKit', // object to call on
                                      'org.freedesktop.PackageKit', // interface to call on
                                      'InstallPackageName'); // method name
  if (msg = nil) then
  begin
    WriteLn('Message Null');
    Exit;
  end;
 
  // append arguments
  dbus_message_iter_init_append(msg, @args);
  if (dbus_message_iter_append_basic(@args, DBUS_TYPE_STRING, @param) = 0) then
  begin
    WriteLn('Out Of Memory!');
    Exit;
  end;
 
  // send message and get a handle for a reply
  if (dbus_connection_send_with_reply(conn, msg, @pending, -1) = 0) then // -1 is default timeout
  begin
    WriteLn('Out Of Memory!');
    Exit;
  end;
  if (pending = nil) then
  begin
    WriteLn('Pending Call Null');
    Exit;
  end;
  dbus_connection_flush(conn);
 
  WriteLn('Request Sent');
 
  // free message
  dbus_message_unref(msg);
 
  // block until we recieve a reply
  dbus_pending_call_block(pending);
 
  // get the reply message
  msg := dbus_pending_call_steal_reply(pending);
  if (msg = nil) then
  begin
    WriteLn('Reply Null');
    Exit;
  end;
  // free the pending message handle
  dbus_pending_call_unref(pending);
 
  // read the parameters
  if (dbus_message_iter_init(msg, @args) = 0) then
     WriteLn('Message has no arguments!')
  else if (DBUS_TYPE_BOOLEAN <> dbus_message_iter_get_arg_type(@args)) then
     WriteLn('Argument is not boolean!')
  else
     dbus_message_iter_get_basic(@args, @stat);
 
  if (dbus_message_iter_next(@args) = 0) then
     WriteLn('Message has too few arguments!')
  else if (DBUS_TYPE_UINT32 <> dbus_message_iter_get_arg_type(@args)) then
     WriteLn('Argument is not int!')
  else
     dbus_message_iter_get_basic(@args, @level);
 
  WriteLn('Got Reply: ', stat, ', ', level);
 
  // free reply
  dbus_message_unref(msg);
end;
Das funktioniert leider nicht. Ist hier wer, der sich damit auskennt? Mit dem Python-Beispiel funktioniert's, der Pascal-Code nicht.

Antworten