Top > OOoBasic > Generic > Extensions

拡張機能用 API Edit

拡張機能で利用する API

XPackageManager Edit

パッケージのインストールやインストール済みのパッケージの操作を行う API です。

以下のようにして "user" もしくは "shared" コンテキストを指定して取得します。

Function GetPackageManager( sContext As String )
  oPMF = GetDefaultContext().getByName( _
    "/singletons/com.sun.star.deployment.thePackageManagerFactory" )
  GetPackageManager = oPMF.getPackageManager(sContext)
End Function
Sub pm2
  oPM = GetPackageManager("user")
  oAC = oPM.createAbortChannel()
  oPackages = oPM.getDeployedPackages(oAC,Null)
End Sub

3.3 からは上記のものが deprecated になったため次のサービスを利用します。

oEM = com.sun.star.deployment.ExtensionManager.get()

パッケージディレクトリ Edit

拡張機能パッケージはたとえば user コンテキストの場合は OpenOffice.org/user/uno_packages/cache/uno_packages 以下にインストールされます。このとき、パッケージごとにディレクトリが作成されて配置されます。(このディレクトリ名は com.sun.star.io.TempFile などのサービスが作成したもの)

このディレクトリ名がランダムに決定されるため、以前はパッケージのディレクトリに依存したコードを書かないように、とされていました。 2.3 から新しい API として com.sun.star.deployment.PackageInformationProvider single ton が実装され、com.sun.star.deployment.XPackageInformationProvider インターフェースからパッケージのディレクトリ URL を取得できるようになりました。

PackageInformationProvider Edit

この API を利用するには、パッケージの description.xml ファイルに identifier を設定する必要があります。

以下のような形で利用します。

Sub GetPackageLocation()
  oPIP = GetDefaultContext().getByName( _
    "/singletons/com.sun.star.deployment.PackageInformationProvider")
  Inputbox ,, oPIP.getPackageLocation("mytools.mri")
End Sub

結果 file:///C:/Users/huga/AppData/Roaming/OpenOffice.org2/user/uno_packages/ cache/uno_packages/2A00.tmp_/MRI.oxt

Py-UNO で行う場合。

  0
  1
  2
  3
  4
  5
  6
def get_extension_dirurl(ctx,extid=EXTENSION_ID):
    """Get extension directory url from the extension id."""
    pip_name = "/singletons/com.sun.star.deployment.PackageInformationProvider"
    if ctx.hasByName(pip_name):
        pip = ctx.getByName(pip_name)
        return pip.getPackageLocation(extid)
    return ""

BeanShell

import com.sun.star.container.XNameAccess;
import com.sun.star.deployment.XPackageInformationProvider;

// get PackageInformationProvider from ComponentContext
XNameAccess xNameAccess = (XNameAccess) UnoRuntime.queryInterface(
	XNameAccess.class, xComponentContext );

Object oPIP = xNameAccess.getByName( 
     "/singletons/com.sun.star.deployment.PackageInformationProvider" );
XPackageInformationProvider xPIP = (XPackageInformationProvider) UnoRuntime.queryInterface(
	XPackageInformationProvider.class, oPIP);
// get the url of the directory extension installed
String sPackageURL = xPIP.getPackageLocation( "mytools.mri" );

2.2 以前との共有 Edit

2.3 以降では前述の PackageInformationProvider が利用できます。しかし、パッケージのバージョン依存性がこれのみの場合には 2.2 以前でも利用したくなります。

拡張機能 ID は 2.0.4 からサポートされているため、それを利用すればパッケージの位置を知ることができます。

コンテキストから PackageInformationProvider が見つかると (2.3 以降) それを利用し、それ以外の時には thePackageManagerFactory からインストールされているパッケージを調べてディレクトリを取得します。

 sPkgLocation = ""
 sPkgId = "mytools.Honyonyo"
 sPIPName = "/singletons/com.sun.star.deployment.PackageInformationProvider" '2.3
 sPMFName = "/singletons/com.sun.star.deployment.thePackageManagerFactory"
 
 If oContext.hasByName(sPIPName) Then ' 2.3
   oPkgIP = oContext.getByName(sPIPName)
   sPkgLocation = oPkgIP.getPackageLocation(sPkgId)
 
 ElseIf oContext.hasByName(sPMFName) Then
   oPkgMgr = oContext.getByName(sPMFName).getPackageManager("user")
   oPackages = oPkgMgr.getDeployedPackages(oPkgMgr.createAbortChannel(),Null)
   For i = 0 To UBound(oPackages)
     If oPackages(i).getIdentifier().Value = sPkgId Then
       sPkgLocation = oPackages(i).getURL()
       oExpander = oContext.getByName( _
           "/singletons/com.sun.star.util.theMacroExpander")
       sPkgLocation = Mid(oExpander.expandMacros(sPkgLocation),21)
     End If
   Next i
 End If

thePackageManagerFactory から取得したパッケージから取得できるパッケージのディレクトリ URI は vnd.sun.star.expand: ... のような形式になっているため、theMacroExpander で URL に変換しています。

拡張機能パッケージ内 URI Edit

3.3 から拡張機能パッケージへのプロトコルが利用できます。拡張機能パッケージコンテントプロバイダを通過する場合に利用できます。

URI の形式は次のようになります。利用には拡張機能 ID が必要です。

vnd.sun.star.extension://EXTENSION_ID/to_file

以下のものでは動作が確認できました。

  • css.ucb.SimpleFileAccess
  • css.graphic.GraphicProvider
  • css.awt.DialogProvider

SimpleFileAccess が内部で該当する ucb のプロバイダを利用しているため、各種サービスが内部で SimpleFileAccess を利用していればこの形式の URI を利用できるはずです。

 dp = CreateUnoService("com.sun.star.awt.DialogProvider")
 dlg = dp.createDialog( _
     "vnd.sun.star.extension://mytools.mri/dialogs/Config.xdl")
 dlg.execute()

パッケージのインストール Edit

拡張機能パッケージを API 経由でインストールできます。しかし、インストールしますか?のダイアログの OK ボタンを自動的に押すような処理が必要なため、普通は利用しないべきです。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
    class ProgressHandler(unohelper.Base, XProgressHandler):
        def push(self, status): pass
        def update(self, status): pass
        def pop(self): pass
    
    class Interactionhalder(unohelper.Base, XInteractionHandler):
        def __init__(self, act):
            self.act = act
        
        def handle(self, request):
            message = request.getRequest()
            if not isinstance(message, str):
                message = message.Message
            try:
                n = self.act.query(message)
                if n == 1:
                    type_name = "com.sun.star.task.XInteractionApprove"
                else:
                    type_name = "com.sun.star.task.XInteractionAbort"
                for continuation in request.getContinuations():
                    if continuation.queryInterface(uno.getTypeByName(type_name)):
                        continuation.select()
            except Exception as e:
                print(e)
    
    def query(self, message, buttons=2):
        return show_message(self.ctx, self.pages[6].getPeer(), 
            message, "", "querybox", buttons)
    
    class CommandEnv(unohelper.Base, XCommandEnvironment):
        def __init__(self, act):
            self.act = act
        
        def getInteractionHandler(self):
            return self.act.__class__.Interactionhalder(self.act)
        
        def getProgressHandler(self):
            return self.act.__class__.ProgressHandler()
 
    def install(self, command_env):
        if not self.file_exists(self.package_url):
            raise Exception("Extension package lost.")
        manager = self.ctx.getByName(
            "/singletons/com.sun.star.deployment.ExtensionManager")
        ac = manager.createAbortChannel()
        try:
            package = manager.addExtension(
                self.package_url, 
                (), 
                "user", 
                ac, 
                command_env
            )
        except Exception as e:
            print(e)
            return False
        return True

このコードではメッセージボックスでユーザーに選択させていますが、css.task.XInteractionApprove を選択して select メソッドを呼ぶと、ユーザーの操作なしでインストールできます。 勝手にパッケージをインストールされると困るものもあるので、ユーザーの承諾を得るようにしてください。


Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes