在 Eclipse RCP 应用程序中创建新工作区时出错
Error in creating new workspace in Eclipse RCP application
在 Eclipse RCP 应用程序中创建新工作区时出现问题。
启动 RCP 应用程序时,会提示一个对话框询问工作区位置。
给出位置后,会出现错误 “无法启动产品,因为无法创建指定的工作区。
指定的工作区目录无效或只读。
我遵循了来自 eclipse IDEApplication.java 的代码,但我仍然面临同样的问题。
申请代码:
@SuppressWarnings("restriction")
public class MyRcpApplication implements IApplication
{
private static final String METADATA_PROJECTS_PATH = "/.plugins/org.eclipse.core.resources/.projects";
private static final String METADATA_ROOT = ".metadata";
private static final String COMMAND_ARG = "--container";
private static final String SYSTEM_PROPERTY_EXIT_CODE = "eclipse.exitcode";
private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime";
private static final String VERSION_FILENAME = "version.ini";
private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$
public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
private Shell shell;
/*
* (non-Javadoc)
*
* @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
@Override
public Object start(final IApplicationContext context)
{
Display display = PlatformUI.createDisplay();
Shell shell = display.getActiveShell();
try
{
// for backward compatibility we need to clear the workspace before start also
cleanUpTheWorkSpace();
boolean instanceLocationCheck = checkInstanceLocation(shell, context.getArguments());
if (!instanceLocationCheck)
{
MessageDialog.openError(shell, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle,
"Could not launch the product because the associated workspace is currently in use by another My Application.");
return IApplication.EXIT_OK;
}
int returnCode = PlatformUI.createAndRunWorkbench(display, new MyApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART)
{
// eclipse.exitcode system property may be set to re-launch
if (IApplication.EXIT_RELAUNCH.equals(Integer.getInteger(SYSTEM_PROPERTY_EXIT_CODE)))
{
return IApplication.EXIT_RELAUNCH;
}
return IApplication.EXIT_RESTART;
}
// if application return code is exit clean up the workspace
// cleanUpTheWorkSpace();
return IApplication.EXIT_OK;
}
finally
{
if (display != null)
{
display.dispose();
}
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc != null)
{
instanceLoc.release();
}
}
}
@SuppressWarnings("rawtypes")
private boolean checkInstanceLocation(final Shell shell, final Map arguments)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc == null)
{
MessageDialog.openError(shell, "Workspace is Mandatory", "IDEs need a valid workspace.");
return false;
}
// -data "/valid/path", workspace already set
if (instanceLoc.isSet())
{
// make sure the meta data version is compatible (or the user has
// chosen to overwrite it).
try
{
// Used to check whether are we launching My application from development environment or not
if (isDevLaunchMode(arguments))
{
return true;
}
// Used to check instance location is locked or not
if (instanceLoc.isLocked())
{
return false;
}
// we failed to create the directory.
// Two possibilities:
// 1. directory is already in use
// 2. directory could not be created
File workspaceDirectory = new File(instanceLoc.getURL().getFile());
if (workspaceDirectory.exists())
{
if (isDevLaunchMode(arguments))
{
return true;
}
MessageDialog.openError(
shell,
"Workspace Cannot Be Locked",
"Could not launch the product because the associated workspace at '" + workspaceDirectory.getAbsolutePath()
+ "' is currently in use by another Eclipse application");
}
else
{
MessageDialog
.openError(
shell,
"Workspace Cannot Be Created",
"Could not launch the product because the specified workspace cannot be created. The specified workspace directory is either invalid or read-only.");
}
}
catch (IOException e)
{
MessageDialog.openError(shell, "Internal Error", e.getMessage());
}
}
else
{
try
{
// -data @noDefault or -data not specified, prompt and set
ChooseWorkspaceData launchData = new ChooseWorkspaceData(instanceLoc.getDefault());
boolean force = false;
while (true)
{
URL workspaceUrl = promptForWorkspace(shell, launchData, force);
if (workspaceUrl == null)
{
return false;
}
// if there is an error with the first selection, then force the
// dialog to open to give the user a chance to correct
force = true;
try
{
// the operation will fail if the url is not a valid
// instance data area, so other checking is unneeded
if (instanceLoc.set(workspaceUrl, false))
{
launchData.writePersistedData();
writeWorkspaceVersion(workspaceUrl);
return true;
}
}
catch (IllegalStateException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetMessage);
return false;
}
// by this point it has been determined that the workspace is
// already in use -- force the user to choose again
MessageDialog.openError(shell, IDEWorkbenchMessages
.IDEApplication_workspaceInUseTitle,
IDEWorkbenchMessages.
IDEApplication_workspaceInUseMessage);
}
}
catch (IllegalStateException | IOException e)
{
}
}
return true;
}
private static void writeWorkspaceVersion(final URL defaultValue)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc.isReadOnly())
{
// MessageDialog.openError(shell,"Read-Only Dialog", "Location was read-only");
System.out.println("Instance Got Locked......");
}
if ((instanceLoc == null) || instanceLoc.isReadOnly())
{
return;
}
File versionFile = getVersionFile(instanceLoc.getURL(), true);
if (versionFile == null)
{
return;
}
OutputStream output = null;
try
{
String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE;
output = new FileOutputStream(versionFile);
output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not write version file", //$NON-NLS-1$
StatusUtil.newStatus(IStatus.ERROR, e.getMessage(), e));
}
finally
{
try
{
if (output != null)
{
output.close();
}
}
catch (IOException e)
{
// do nothing
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.equinox.app.IApplication#stop()
*/
@Override
public void stop()
{
if (!PlatformUI.isWorkbenchRunning())
{
return;
}
final IWorkbench workbench = PlatformUI.getWorkbench();
final Display display = workbench.getDisplay();
display.syncExec(new Runnable()
{
@Override
public void run()
{
if (!display.isDisposed())
{
workbench.close();
}
}
});
}
private URL promptForWorkspace(final Shell shell, final ChooseWorkspaceData launchData, boolean force)
{
URL url = null;
do
{
new ChooseWorkspaceDialog(shell, launchData, false, force).prompt(force);
String instancePath = launchData.getSelection();
if (instancePath == null)
{
return null;
}
// the dialog is not forced on the first iteration, but is on every
// subsequent one -- if there was an error then the user needs to be
// allowed to
force = true;
// create the workspace if it does not already exist
File workspace = new File(instancePath);
if (!workspace.exists())
{
workspace.mkdir();
}
try
{
// Don't use File.toURL() since it adds a leading slash that Platform does not
// handle properly. See bug 54081 for more details.
String path = workspace.getAbsolutePath().replace(File.separatorChar, '/');
url = new URL("file", null, path); //$NON-NLS-1$
}
catch (MalformedURLException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidMessage);
continue;
}
}
while (!checkValidWorkspace(shell, url));
return url;
}
private boolean checkValidWorkspace(final Shell shell, final URL url)
{
String version = readWorkspaceVersion(url);
// if the version could not be read, then there is not any existing
// workspace data to trample, e.g., perhaps its a new directory that
// is just starting to be used as a workspace
if (version == null)
{
return true;
}
final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE);
int workspace_version = Integer.parseInt(version);
// equality test is required since any version difference (newer
// or older) may result in data being trampled
if (workspace_version == ide_version)
{
return true;
}
// At this point workspace has been detected to be from a version
// other than the current ide version -- find out if the user wants
// to use it anyhow.
String title = "My App Titile"; //$NON-NLS-1$
String message = "My App Message";
MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL
| SWT.ICON_WARNING | SWT.APPLICATION_MODAL);
mbox.setText(title);
mbox.setMessage(message);
return mbox.open() == SWT.OK;
}
private static String readWorkspaceVersion(final URL workspace)
{
File versionFile = getVersionFile(workspace, false);
if ((versionFile == null) || !versionFile.exists())
{
return null;
}
try
{
// Although the version file is not spec'ed to be a Java properties
// file, it happens to follow the same format currently, so using
// Properties to read it is convenient.
Properties props = new Properties();
FileInputStream is = new FileInputStream(versionFile);
try
{
props.load(is);
}
finally
{
is.close();
}
return props.getProperty(WORKSPACE_VERSION_KEY);
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not read version file", new Status( //$NON-NLS-1$
IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
IStatus.ERROR,
e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$,
e));
return null;
}
}
private static File getVersionFile(final URL workspaceUrl, final boolean create)
{
if (workspaceUrl == null)
{
return null;
}
try
{
// make sure the directory exists
File metaDir = new File(workspaceUrl.getPath(), METADATA_FOLDER);
if (!metaDir.exists() && (!create || !metaDir.mkdir()))
{
return null;
}
// make sure the file exists
File versionFile = new File(metaDir, VERSION_FILENAME);
if (!versionFile.exists()
&& (!create || !versionFile.createNewFile()))
{
return null;
}
return versionFile;
}
catch (IOException e)
{
// cannot log because instance area has not been set
return null;
}
}
@SuppressWarnings("rawtypes")
private static boolean isDevLaunchMode(final Map args)
{
// see org.eclipse.pde.internal.core.PluginPathFinder.isDevLaunchMode()
if (Boolean.getBoolean("eclipse.pde.launch"))
{
return true;
}
return args.containsKey("-pdelaunch"); //$NON-NLS-1$
}
/**
* Deletes all the available projects in the workspace
*/
private void cleanUpTheWorkSpace()
{
// this will be the
String[] commands = Platform.getCommandLineArgs();
if (commands != null)
{
List<String> args = Arrays.asList(commands);
if (args.contains(COMMAND_ARG))
{
// if project is in the root delete it.. it will delete associated metadata
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
if (projects != null)
{
for (IProject project : projects)
{
try
{
project.delete(true, new NullProgressMonitor());
}
catch (CoreException e)
{
// msgHandler.post(MsgSeverity.ERROR, "Unable to clear the workspace");
}
}
}
// if project is not in the root but if its in the workspace delete the metadata too
File[] workSpaceFiles = Platform.getLocation().toFile().listFiles();
for (File file : workSpaceFiles)
{
if (METADATA_ROOT.equals(file.getName()))
{
File projectMeta = new File(file.getPath() + METADATA_PROJECTS_PATH);
if ((projectMeta != null) && projectMeta.exists())
{
File[] children = projectMeta.listFiles();
for (File child : children)
{
FileUtils.deleteQuietly(child);
}
}
}
/*
* else { FileUtils.deleteQuietly(file); }
*/
}
}
}
}
}
您的代码只是调用
if (instanceLoc.isLocked())
{
return false;
}
检查工作区是否被锁定,但没有采取任何措施使工作区锁定,因此这总是会导致错误代码。
IDEApplication
这样做:
if (instanceLoc.lock()) {
writeWorkspaceVersion();
return null;
}
你需要做类似的事情。
以管理员身份尝试 运行 Eclipse。
在 Eclipse RCP 应用程序中创建新工作区时出现问题。
启动 RCP 应用程序时,会提示一个对话框询问工作区位置。 给出位置后,会出现错误 “无法启动产品,因为无法创建指定的工作区。 指定的工作区目录无效或只读。 我遵循了来自 eclipse IDEApplication.java 的代码,但我仍然面临同样的问题。
申请代码:
@SuppressWarnings("restriction")
public class MyRcpApplication implements IApplication
{
private static final String METADATA_PROJECTS_PATH = "/.plugins/org.eclipse.core.resources/.projects";
private static final String METADATA_ROOT = ".metadata";
private static final String COMMAND_ARG = "--container";
private static final String SYSTEM_PROPERTY_EXIT_CODE = "eclipse.exitcode";
private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime";
private static final String VERSION_FILENAME = "version.ini";
private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$
public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
private Shell shell;
/*
* (non-Javadoc)
*
* @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
@Override
public Object start(final IApplicationContext context)
{
Display display = PlatformUI.createDisplay();
Shell shell = display.getActiveShell();
try
{
// for backward compatibility we need to clear the workspace before start also
cleanUpTheWorkSpace();
boolean instanceLocationCheck = checkInstanceLocation(shell, context.getArguments());
if (!instanceLocationCheck)
{
MessageDialog.openError(shell, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle,
"Could not launch the product because the associated workspace is currently in use by another My Application.");
return IApplication.EXIT_OK;
}
int returnCode = PlatformUI.createAndRunWorkbench(display, new MyApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART)
{
// eclipse.exitcode system property may be set to re-launch
if (IApplication.EXIT_RELAUNCH.equals(Integer.getInteger(SYSTEM_PROPERTY_EXIT_CODE)))
{
return IApplication.EXIT_RELAUNCH;
}
return IApplication.EXIT_RESTART;
}
// if application return code is exit clean up the workspace
// cleanUpTheWorkSpace();
return IApplication.EXIT_OK;
}
finally
{
if (display != null)
{
display.dispose();
}
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc != null)
{
instanceLoc.release();
}
}
}
@SuppressWarnings("rawtypes")
private boolean checkInstanceLocation(final Shell shell, final Map arguments)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc == null)
{
MessageDialog.openError(shell, "Workspace is Mandatory", "IDEs need a valid workspace.");
return false;
}
// -data "/valid/path", workspace already set
if (instanceLoc.isSet())
{
// make sure the meta data version is compatible (or the user has
// chosen to overwrite it).
try
{
// Used to check whether are we launching My application from development environment or not
if (isDevLaunchMode(arguments))
{
return true;
}
// Used to check instance location is locked or not
if (instanceLoc.isLocked())
{
return false;
}
// we failed to create the directory.
// Two possibilities:
// 1. directory is already in use
// 2. directory could not be created
File workspaceDirectory = new File(instanceLoc.getURL().getFile());
if (workspaceDirectory.exists())
{
if (isDevLaunchMode(arguments))
{
return true;
}
MessageDialog.openError(
shell,
"Workspace Cannot Be Locked",
"Could not launch the product because the associated workspace at '" + workspaceDirectory.getAbsolutePath()
+ "' is currently in use by another Eclipse application");
}
else
{
MessageDialog
.openError(
shell,
"Workspace Cannot Be Created",
"Could not launch the product because the specified workspace cannot be created. The specified workspace directory is either invalid or read-only.");
}
}
catch (IOException e)
{
MessageDialog.openError(shell, "Internal Error", e.getMessage());
}
}
else
{
try
{
// -data @noDefault or -data not specified, prompt and set
ChooseWorkspaceData launchData = new ChooseWorkspaceData(instanceLoc.getDefault());
boolean force = false;
while (true)
{
URL workspaceUrl = promptForWorkspace(shell, launchData, force);
if (workspaceUrl == null)
{
return false;
}
// if there is an error with the first selection, then force the
// dialog to open to give the user a chance to correct
force = true;
try
{
// the operation will fail if the url is not a valid
// instance data area, so other checking is unneeded
if (instanceLoc.set(workspaceUrl, false))
{
launchData.writePersistedData();
writeWorkspaceVersion(workspaceUrl);
return true;
}
}
catch (IllegalStateException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetMessage);
return false;
}
// by this point it has been determined that the workspace is
// already in use -- force the user to choose again
MessageDialog.openError(shell, IDEWorkbenchMessages
.IDEApplication_workspaceInUseTitle,
IDEWorkbenchMessages.
IDEApplication_workspaceInUseMessage);
}
}
catch (IllegalStateException | IOException e)
{
}
}
return true;
}
private static void writeWorkspaceVersion(final URL defaultValue)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc.isReadOnly())
{
// MessageDialog.openError(shell,"Read-Only Dialog", "Location was read-only");
System.out.println("Instance Got Locked......");
}
if ((instanceLoc == null) || instanceLoc.isReadOnly())
{
return;
}
File versionFile = getVersionFile(instanceLoc.getURL(), true);
if (versionFile == null)
{
return;
}
OutputStream output = null;
try
{
String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE;
output = new FileOutputStream(versionFile);
output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not write version file", //$NON-NLS-1$
StatusUtil.newStatus(IStatus.ERROR, e.getMessage(), e));
}
finally
{
try
{
if (output != null)
{
output.close();
}
}
catch (IOException e)
{
// do nothing
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.equinox.app.IApplication#stop()
*/
@Override
public void stop()
{
if (!PlatformUI.isWorkbenchRunning())
{
return;
}
final IWorkbench workbench = PlatformUI.getWorkbench();
final Display display = workbench.getDisplay();
display.syncExec(new Runnable()
{
@Override
public void run()
{
if (!display.isDisposed())
{
workbench.close();
}
}
});
}
private URL promptForWorkspace(final Shell shell, final ChooseWorkspaceData launchData, boolean force)
{
URL url = null;
do
{
new ChooseWorkspaceDialog(shell, launchData, false, force).prompt(force);
String instancePath = launchData.getSelection();
if (instancePath == null)
{
return null;
}
// the dialog is not forced on the first iteration, but is on every
// subsequent one -- if there was an error then the user needs to be
// allowed to
force = true;
// create the workspace if it does not already exist
File workspace = new File(instancePath);
if (!workspace.exists())
{
workspace.mkdir();
}
try
{
// Don't use File.toURL() since it adds a leading slash that Platform does not
// handle properly. See bug 54081 for more details.
String path = workspace.getAbsolutePath().replace(File.separatorChar, '/');
url = new URL("file", null, path); //$NON-NLS-1$
}
catch (MalformedURLException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidMessage);
continue;
}
}
while (!checkValidWorkspace(shell, url));
return url;
}
private boolean checkValidWorkspace(final Shell shell, final URL url)
{
String version = readWorkspaceVersion(url);
// if the version could not be read, then there is not any existing
// workspace data to trample, e.g., perhaps its a new directory that
// is just starting to be used as a workspace
if (version == null)
{
return true;
}
final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE);
int workspace_version = Integer.parseInt(version);
// equality test is required since any version difference (newer
// or older) may result in data being trampled
if (workspace_version == ide_version)
{
return true;
}
// At this point workspace has been detected to be from a version
// other than the current ide version -- find out if the user wants
// to use it anyhow.
String title = "My App Titile"; //$NON-NLS-1$
String message = "My App Message";
MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL
| SWT.ICON_WARNING | SWT.APPLICATION_MODAL);
mbox.setText(title);
mbox.setMessage(message);
return mbox.open() == SWT.OK;
}
private static String readWorkspaceVersion(final URL workspace)
{
File versionFile = getVersionFile(workspace, false);
if ((versionFile == null) || !versionFile.exists())
{
return null;
}
try
{
// Although the version file is not spec'ed to be a Java properties
// file, it happens to follow the same format currently, so using
// Properties to read it is convenient.
Properties props = new Properties();
FileInputStream is = new FileInputStream(versionFile);
try
{
props.load(is);
}
finally
{
is.close();
}
return props.getProperty(WORKSPACE_VERSION_KEY);
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not read version file", new Status( //$NON-NLS-1$
IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
IStatus.ERROR,
e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$,
e));
return null;
}
}
private static File getVersionFile(final URL workspaceUrl, final boolean create)
{
if (workspaceUrl == null)
{
return null;
}
try
{
// make sure the directory exists
File metaDir = new File(workspaceUrl.getPath(), METADATA_FOLDER);
if (!metaDir.exists() && (!create || !metaDir.mkdir()))
{
return null;
}
// make sure the file exists
File versionFile = new File(metaDir, VERSION_FILENAME);
if (!versionFile.exists()
&& (!create || !versionFile.createNewFile()))
{
return null;
}
return versionFile;
}
catch (IOException e)
{
// cannot log because instance area has not been set
return null;
}
}
@SuppressWarnings("rawtypes")
private static boolean isDevLaunchMode(final Map args)
{
// see org.eclipse.pde.internal.core.PluginPathFinder.isDevLaunchMode()
if (Boolean.getBoolean("eclipse.pde.launch"))
{
return true;
}
return args.containsKey("-pdelaunch"); //$NON-NLS-1$
}
/**
* Deletes all the available projects in the workspace
*/
private void cleanUpTheWorkSpace()
{
// this will be the
String[] commands = Platform.getCommandLineArgs();
if (commands != null)
{
List<String> args = Arrays.asList(commands);
if (args.contains(COMMAND_ARG))
{
// if project is in the root delete it.. it will delete associated metadata
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
if (projects != null)
{
for (IProject project : projects)
{
try
{
project.delete(true, new NullProgressMonitor());
}
catch (CoreException e)
{
// msgHandler.post(MsgSeverity.ERROR, "Unable to clear the workspace");
}
}
}
// if project is not in the root but if its in the workspace delete the metadata too
File[] workSpaceFiles = Platform.getLocation().toFile().listFiles();
for (File file : workSpaceFiles)
{
if (METADATA_ROOT.equals(file.getName()))
{
File projectMeta = new File(file.getPath() + METADATA_PROJECTS_PATH);
if ((projectMeta != null) && projectMeta.exists())
{
File[] children = projectMeta.listFiles();
for (File child : children)
{
FileUtils.deleteQuietly(child);
}
}
}
/*
* else { FileUtils.deleteQuietly(file); }
*/
}
}
}
}
}
您的代码只是调用
if (instanceLoc.isLocked())
{
return false;
}
检查工作区是否被锁定,但没有采取任何措施使工作区锁定,因此这总是会导致错误代码。
IDEApplication
这样做:
if (instanceLoc.lock()) {
writeWorkspaceVersion();
return null;
}
你需要做类似的事情。
以管理员身份尝试 运行 Eclipse。