2

私は、1つの個人用プラグイン( )とEclipse Helios(3.6)の他の多数で構成されるcom.example.product1つの個人用機能()に基づく個人用Eclipse RCP製品( )を持っています。アプリに更新を確認し、必要に応じてp2サイトから更新してもらいたい。ヘッドレスにする必要があります。つまり、ユーザーは更新プロセスで対話しませんが、ダイアログで進行状況が表示される場合があります。com.example.featurecom.example.plugin

更新の実装は、 RCPメールアプリケーションに基づいています。メソッドを少し変更してP2Util.checkForUpdatesロギングを含め、そこで何がうまくいかないかを確認できるようにしました。

    static IStatus checkForUpdates(IProvisioningAgent agent,
        IProgressMonitor monitor) throws OperationCanceledException,
        InvocationTargetException {
    ProvisioningSession session = new ProvisioningSession(agent);
    UpdateOperation operation = new UpdateOperation(session);
    SubMonitor sub = SubMonitor.convert(monitor,
            "Checking for application updates...", 200);
    IStatus status = operation.resolveModal(sub.newChild(100));
    if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
        return status;
    }
    if (status.getSeverity() == IStatus.CANCEL)
        throw new OperationCanceledException();

    if (status.getSeverity() != IStatus.ERROR) {
        try {
            logger.info( "Status is " + status );
            Update[] updates = operation.getPossibleUpdates();              
            for( Update u : updates){
                logger.info( "Update is " + u );
            }               
            ProvisioningJob job = operation.getProvisioningJob(null);
            if( job == null ){
                logger.error( "Provisioning Job is null" );
            }
            status = job.runModal(sub.newChild(100));
            if (status.getSeverity() == IStatus.CANCEL) {
                throw new OperationCanceledException();
            }
        } catch ( Exception e ){
            logger.error( "Exception while trying to get updates", e);
        }
    }
    return status;
}

機能にp2.infファイルと同じレベルのexample.productファイルがあります。を含む:

org.eclipse.equinox.p2.touchpoint.eclipse.addRepository": 
instructions.configure=\ 
org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(type:0,location:file${#58}/C${#58}/workspace/updatesite/);\
org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(type:1,location:file${#58}/C${#58}/workspace/updatesite/);

プラグイン、機能、製品IDを1.0.0に設定して製品をビルドします。製品エクスポートウィザードを使用して、Eclipseから製品をエクスポートして実行できます。私はこれをするときにカチカチ音をたてるgenerate metadata repository

Create an Update Site ProjectFeatureManfiestEditorのオプションを使用して更新サイトを作成します。`com.example.feature'を追加してビルドします。それが機能するかどうかを確認するために、EclipseIDEの[新しいソフトウェアのインストール]オプションを使用して参照してみてください。そこで機能を確認できます。

3つのIDすべてを1.0.1に変更して更新サイトを構築します。アプリを起動すると、インストールする更新がない、ログにエラーがない、と表示されます。

更新サイトから更新されない理由はわかりませんが、頭に浮かんだのは次のとおりです。

1) p2.infファイルにさらに情報が必要な場合がありますが、名前空間、名前、範囲など、何が必要かわかりませんが、適切な実用的な例を見つけることができません。

2)このcheckForUpdates方法では、更新されるインストール可能なユニットを変更するために、プロファイルを使用して何かを行う必要がある場合があります。繰り返しになりますが、これを示唆するコメントのみが見つかり、その方法を示すサンプルコードは見つかりませんでした。

ここでは、ヒントやアイデアを高く評価しています。これは多くの時間を費やしています。

4

3 に答える 3

2

このコードを見てください。新しい製品バージョンで製品を再構築し、http サーバーのセットアップを試みます。ファイルリポジトリでは機能しませんでした。機能を公開するだけでは機能しません。

final IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

sub = SubMonitor.convert(monitor, Messages.getString("UpdateManager.searchforupdates"), 200); //$NON-NLS-1$
final Update update = getUpdate(profile, provisioningContext, engine, context);

status = operation.resolveModal(sub.newChild(100));
LogHelper.log(status);
if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
 status = null;
 return;
}
if (status.getSeverity() == IStatus.CANCEL)
 throw new OperationCanceledException();
if (status.getSeverity() != IStatus.ERROR) {
 log(IStatus.INFO, "Checking for available update matches", null); //$NON-NLS-1$
 Update[] selected = new Update[1];
 operation.setSelectedUpdates(new Update[0]);
 for (Update available : operation.getPossibleUpdates()) {
  if (available.equals(update)) {
   log(IStatus.INFO, "Update matches available: " + update, null); //$NON-NLS-1$
   selected[0] = available;
   operation.setSelectedUpdates(selected);
  }
 }
 if (selected[0] == null) {
  status = null;
  monitor.setCanceled(true);

  log(IStatus.WARNING, "No Update matches selected", null); //$NON-NLS-1$
  return;
 }
 ProvisioningJob job = operation.getProvisioningJob(monitor);
 if (job != null) {
  status = job.runModal(sub.newChild(100));
  if (status.getSeverity() != IStatus.ERROR) {
   prefStore.setValue(JUSTUPDATED, true);
   Display.getDefault().syncExec(new Runnable() {
    public void run() {
     PlatformUI.getWorkbench().restart();
    }
   });

  } else {
   LogHelper.log(status);
  }

 } else {
  log(IStatus.INFO, "getJob returned null", null); //$NON-NLS-1$
  status = null;
 }
 if (status != null && status.getSeverity() == IStatus.CANCEL)
  throw new OperationCanceledException();
 }
 }
};

Display.getDefault().asyncExec(new Runnable() {
public void run() {
try {
 new ProgressMonitorDialog(null).run(true, true, runnable);
} catch (InvocationTargetException x) {
 log(IStatus.ERROR, "Runnable failure", x); //$NON-NLS-1$
} catch (InterruptedException e) {
}
}
});
于 2010-10-12T11:33:24.873 に答える
1

@ user473284の回答には、私が使用したいくつかの提案がありましたが、それらが明確な要件であるかどうかはわかりません

1) ファイルを参照するのではなく、ローカル Web サーバーを使用します。2) 製品バージョンを増やし、製品のエクスポート ウィザードによって生成された更新リポジトリを使用します。

コード サンプルから参照されている getUpdate メソッドの実装が見つからなかったため、スニペットを利用できませんでした。

上記の変更の後、起動時にアプリが更新を検出しないままでした。デバッグすると、リポジトリがセッションに表示されないことがわかりました。p2.inf に更新 URL があり、機能マニフェスト エディターのフォーム フィールドに設定されているにもかかわらず、コードに更新 URL を明示的に追加する必要がありました。このコードは次のとおりです。

    public static void addUpdateSite(IProvisioningAgent provisioningAgent)
        throws InvocationTargetException {
    // Load repository manager
    IMetadataRepositoryManager metadataManager = (IMetadataRepositoryManager) provisioningAgent
            .getService(IMetadataRepositoryManager.SERVICE_NAME);
    if (metadataManager == null) {
        logger.error( "Metadata manager was null");
         Throwable throwable = new
         Throwable("Could not load Metadata Repository Manager");
         throwable.fillInStackTrace();
         throw new InvocationTargetException(throwable);
    }

    // Load artifact manager
    IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) provisioningAgent
            .getService(IArtifactRepositoryManager.SERVICE_NAME);
    if (artifactManager == null) {
        logger.error( "Artifact manager was null");
        Throwable throwable = new Throwable(
                "Could not load Artifact Repository Manager");
        throwable.fillInStackTrace();
        throw new InvocationTargetException(throwable);
    }

    // Load repo
    try {
        URI repoLocation = new URI("http://localhost/respository");
        logger.info( "Adding repository " + repoLocation );
        metadataManager.loadRepository(repoLocation, null);
        artifactManager.loadRepository(repoLocation, null);
    } catch (ProvisionException pe) {
        logger.error( "Caught provisioning exception " + pe.getMessage(), pe);
        throw new InvocationTargetException(pe);
    } catch (URISyntaxException e) {
        logger.error( "Caught URI syntax exception " + e.getMessage(), e);
        throw new InvocationTargetException(e);
    }
}

元の質問の checkForUpdates メソッドでこれを最初に呼び出します。この変更の後、少なくとも私のアプリは更新を認識し、インストールを試みます。私はまだ問題を抱えていますが、https://stackoverflow.com/questions/3944953/error-during-p2-eclipse-rcp-app-headless-updateで作成した独自の別の質問に値します

于 2010-10-15T18:11:07.083 に答える
0
  1. Web サーバーは必須ではありません。ファイルの場所で更新を取得できます。
  2. 製品バージョンの変更も必須です。
  3. 製品と共にエクスポートされる Update Site Project ビルドでこれらの機能を更新することはできませんが、エクスポートされた製品をハッキングすることでそれを行うことができます。
  4. (Install New Softwares) オプションを使用して他の機能を追加する場合は、Update Site Project ビルドでこれらの機能を更新できます。

うまくいけば、これは役に立ちます。さらに明確にする必要がある場合は、尋ねることができます。

于 2013-08-13T07:20:09.140 に答える