@Override
	public void offerGhidraDevInstallation(TaskMonitor monitor) {
		if (SystemUtilities.isInHeadlessMode()) {
			return;
		}
		
		SystemUtilities.runSwingNow(() -> {

			boolean autoGhidraDevInstall = options.getBoolean(
				EclipseIntegrationOptionsPlugin.AUTO_GHIDRADEV_INSTALL_OPTION, false);

			String errorTitle = "Failed to install GhidraDev";

			if (!autoGhidraDevInstall) {
				int choice = OptionDialog.showYesNoDialog(null, "GhidraDev",
					"GhidraDev has not been installed in Eclipse.\n" +
						"Would you like it automatically installed in Eclipse's \"dropins\" directory?");
				if (choice != OptionDialog.YES_OPTION) {
					return;
				}
			}

			if (SystemUtilities.isInDevelopmentMode()) {
				Msg.showError(this, null, errorTitle,
					"Automatic installation of GhidraDev from development mode is not supported.\n" +
						"Please install it manually.");
				return;
			}

			File dropinsDir;
			try {
				dropinsDir = getEclipseDropinsDir();
			}
			catch (FileNotFoundException e) {
				Msg.showError(this, null, errorTitle, "Eclipse dropins directory does not exist.");
				return;
			}

			File ghidraDevDir = new ResourceFile(Application.getInstallationDirectory(),
				"Extensions/Eclipse/GhidraDev").getFile(false);
			if (ghidraDevDir == null || !ghidraDevDir.isDirectory()) {
				Msg.showError(this, null, errorTitle,
					"GhidraDev directory does not exist in Ghidra:\n" + ghidraDevDir);
				return;
			}

			File ghidraDevFile = null;
			for (File f : ghidraDevDir.listFiles(File::isFile)) {
				if (f.getName().startsWith("GhidraDev") && f.getName().endsWith(".zip")) {
					ghidraDevFile = f;
					break;
				}
			}
			if (ghidraDevFile == null) {
				Msg.showError(this, null, errorTitle,
					"GhidraDev Eclipse extension does not exist:\n" + ghidraDevFile);
				return;
			}
			
			try (ZipFile ghidraDevZip = new ZipFile(ghidraDevFile)) {
				Enumeration<? extends ZipEntry> entries = ghidraDevZip.entries();
				while (entries.hasMoreElements()) {
					ZipEntry entry = entries.nextElement();
					String entryPath = entry.getName();
					String entryName = new File(entryPath).getName();
					if (entryPath.startsWith("plugins") && entryPath.contains("ghidradev")) {
						FileUtilities.copyStreamToFile(ghidraDevZip.getInputStream(entry),
							new File(dropinsDir, entryName), false, monitor);
						break;
					}
				}
			}
			catch (IOException e) {
				Msg.showError(this, null, errorTitle,
					"Error installing GhidraDev to:\n" + dropinsDir, e);
				return;
			}
		});
	}
Plugin responsible for providing Eclipse-related services to other Ghidra plugins.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/eclipse/EclipseIntegrationPlugin.java