银河麒麟桌面操作系统v10(非sp1)右键卸载失败
首先附上点击卸载按钮后出发的程序内容,结尾说明解决方案
#!/usr/bin/env python2
# coding: utf-8
import gi
gi.require_version("Gtk", "2.0")
from gi.repository import Gtk, Gdk, GObject
try:
import sys
import string
import os
import commands
import threading
import tempfile
import gettext
except Exception, detail:
print detail
sys.exit(1)
from subprocess import Popen
# i18n
gettext.install("kylin-menu", "/usr/share/locale")
class RemoveExecuter(threading.Thread):
def __init__(self, package):
threading.Thread.__init__(self)
self.package = package
def run(self):
removePackages = string.split(self.package)
cmd = ["/usr/bin/synaptic-pkexec", "--hide-main-window", \
"--non-interactive"]
cmd.append("--progress-str")
# cmd.append("\"" + _("请等待,这可能需要一些时间...") + "\"")
cmd.append("\"" + _("Please wait") + "\"")
cmd.append("--finish-str")
# cmd.append("\"" + _("应用程序已成功卸载!") + "\"")
cmd.append("\"" + _("Application has been successfully removed!") + "\"")
f = tempfile.NamedTemporaryFile()
for pkg in removePackages:
f.write("%s\tdeinstall\n" % pkg)
cmd.append("--set-selections-file")
cmd.append("%s" % f.name)
f.flush()
comnd = Popen(' '.join(cmd), shell=True)
returnCode = comnd.wait()
f.close()
sys.exit(0)
# mainwin = mateRemoveWindow(sys.argv[1])
class mateRemoveWindow:
def __init__(self, desktopFile):
self.desktopFile = desktopFile
(status, output) = commands.getstatusoutput("dpkg -S " + self.desktopFile)
package = output[:output.find(":")]
if status != 0:
# warnDlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _("该应用程序已经被卸载。您确定需要将该菜单项从开始菜单移除吗?"))
warnDlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO,
_("This application has been removed. Are you sure remove the menu form the startup menu?"))
warnDlg.vbox.set_spacing(10)
response = warnDlg.run()
if response == Gtk.ResponseType.YES:
print "removing '%s'" % self.desktopFile
os.system("rm -f '%s'" % self.desktopFile)
os.system("rm -f '%s.desktop'" % self.desktopFile)
warnDlg.destroy()
sys.exit(0)
# warnDlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK_CANCEL, _("下面的软件包将会被删除:"))
warnDlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK_CANCEL,
_("The following packages will be removed:"))
warnDlg.vbox.set_spacing(10)
treeview = Gtk.TreeView()
# column1 = Gtk.TreeViewColumn(_("将会被删除的软件包"))
column1 = Gtk.TreeViewColumn(_("Packages will be removed"))
renderer = Gtk.CellRendererText()
column1.pack_start(renderer, False)
column1.add_attribute(renderer, "text", 0)
treeview.append_column(column1)
model = Gtk.ListStore(str)
dependenciesString = commands.getoutput("apt-get -s -q remove " + package + " | grep Remv")
dependencies = string.split(dependenciesString, "\n")
for dependency in dependencies:
dependency = dependency.replace("Remv ", "")
model.append([dependency])
treeview.set_model(model)
treeview.show()
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
scrolledwindow.set_size_request(300, 150)
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolledwindow.add(treeview)
scrolledwindow.show()
warnDlg.get_content_area().add(scrolledwindow)
response = warnDlg.run()
if response == Gtk.ResponseType.OK:
executer = RemoveExecuter(package)
executer.start()
elif response == Gtk.ResponseType.CANCEL:
sys.exit(0)
warnDlg.destroy()
Gtk.main()
if __name__ == "__main__":
mainwin = mateRemoveWindow(sys.argv[1])
Gtk.main()
程序内容分析:
mateRemoveWindow类负责处理来自开始菜单中被选中的应用,开始菜单中文的应用来自于:/usr/share/applications目录下的文件,所以当选中一款应用并卸载的时候,实际上是传递了一个==.desktop== 文件作为参数,卸载程序运行的时候会使用dpkg -S .desktop去判断这个文件属于哪个包,再由多线程程序RemoveExecuter这个类,运行ubuntu的新立得软件包管理的命令行命令执行卸载动作。
问题解决流程
首先看下对应的文件是否属于某个包,dpkg -S
文件
如果不属于任何包,那么卸载一定失败,可以手动卸载,或者使用以下命令来解决您的问题
# 本次仅测试,这个流程可以足以处理相同问题
#查看文件启动命令
] cat /usr/share/applications/firefox.desktop |grep -i Exec
Exec=firefox %u
Exec=firefox -new-window
Exec=firefox -private-window
#查看启动命令完整路径,可以简化为 dpkg -S $(which firefox)
] which firefox
/usr/bin/firefox
dpkg -S /usr/bin/firefox
firefox: /usr/bin/firefox
#这条命令若没有任何输出,那么后续的解决方法才有用
] dpkg -L firefox |grep /usr/share/applications/firefox.desktop
#修改dpkg应用文件数据库(这里测试用的是火狐浏览器,火狐浏览器的安装名就是firefox)(vim可以换成pluma)
vim /var/lib/dpkg/info/firefox.list
#在打开的文件最后一行添加,添加完成:x保存退出即可
/usr/share/applications/firefox.desktop
#此时再进行右键卸载动作,运行即可正常,逆向思维,如果删除任意软件数据库中对应的/usr/share/applications/任意.desktop ,则右键卸载不能运行正常