使用 Java 设置 Windows 系统变量
有没有办法将特定目录添加到 Windows 系统变量 %PATH% 中? 这似乎不起作用:
String[] cmd = { "cmd", "/c", "set", "PATH=\"%PATH%;c:\\test\"" };
Runtime.getRuntime().exec( cmd );
c:\test\ 没有出现在 System.getenv("PATH"); 中 输出中
String[] cmd = { "cmd", "/c", "echo", "%PATH%" };
Runtime.getRuntime().exec( cmd );
或者在我需要的是修改 Windows 下当前 Java 进程的 %PATH% 变量的 。原因是,我需要加载一些相互交叉引用的本机 dll 文件。所以我想将应用程序路径添加到Windows环境中。
我尝试的下一件事是 C 函数“putenv”的一个小型 JNI 包装器,如下所示:
JNIEXPORT void JNICALL Java_com_splitscreen_AppletTest_PutEnv_putEnv
(JNIEnv *env, jobject jobj, jstring val) {
jboolean iscopy;
const char *mvalue = (*env)->GetStringUTFChars(
env, val, &iscopy);
putenv(mvalue);
}
这就是我所说的:
final String curPath = System.getenv( "PATH" );
final PutEnv pe = new PutEnv();
pe.putEnv( "PATH=" + curPath + ";c:\test" );
final String newPath = System.getenv( "PATH" );
System.out.println( newPath );
但路径是相等的。我不确定 Java 系统环境图是否未更新或者 putenv 是否不起作用。有办法检查吗?
is there a way to add a specific directory to the Windows systemvariable %PATH%?
This doesn't seem to work:
String[] cmd = { "cmd", "/c", "set", "PATH=\"%PATH%;c:\\test\"" };
Runtime.getRuntime().exec( cmd );
c:\test\ doesn't appear in System.getenv("PATH"); or in the output of
String[] cmd = { "cmd", "/c", "echo", "%PATH%" };
Runtime.getRuntime().exec( cmd );
What I need is to modify the %PATH%-variable for the current Java-Process under Windows. The reason is, that I need to load some native dll-files which cross-reference each other. So I'd like to add the application-path to the Windows environment.
The next thing I tried was a small JNI-Wrapper for the C-Function "putenv" which looks like this:
JNIEXPORT void JNICALL Java_com_splitscreen_AppletTest_PutEnv_putEnv
(JNIEnv *env, jobject jobj, jstring val) {
jboolean iscopy;
const char *mvalue = (*env)->GetStringUTFChars(
env, val, &iscopy);
putenv(mvalue);
}
This is how I call it:
final String curPath = System.getenv( "PATH" );
final PutEnv pe = new PutEnv();
pe.putEnv( "PATH=" + curPath + ";c:\test" );
final String newPath = System.getenv( "PATH" );
System.out.println( newPath );
But the pathes are equal. I'm not sure whether the Map of the Java-System-Environment isn't updated or whether putenv didn't work. Is there a way to check this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这不起作用的原因是两个
exec()
调用启动了两个不同的 shell;您设置路径的路径不是您签入路径的路径。很难更改永久的系统范围路径设置。但您可以在调用一个或多个您需要的程序期间更改路径。
具体来说,要做的就是给自己写一个批处理文件(
.CMD
或.BAT
,随你喜欢),将PATH
设置在附近首先,跟随您想要使用该路径执行的任何 DOS/Windows 命令,然后exec()
该脚本文件。更新当前 Java 进程的 PATH 似乎毫无意义。 Java一旦运行,就不再关心路径了。或者你正在运行一些库代码吗?
如果您使用 exec() 从 Java 运行 DOS/Windows 命令,则上述技巧将起作用。
更新: 好的,您的库代码由于其自身的原因需要如此设置 PATH,并且您希望为其提供所需的内容。
我在这里考虑的是启动一个新的 JVM。您可以使用 exec(cmd, envp) 来启动一个新的 Java 应用程序(在紧要关头,“您自己”),并使用 envp 中的一组自定义环境变量。只需复制已有的内容并操作
PATH
的内容(如果有)。启动新 Java 应用程序的标准方法是创建新的 ClassLoader,并且有各种关于如何完成此操作的描述。但我不确定您是否可以使用该过程来创建一个新环境 - 因此 exec JVM 可能不仅更简单,而且可能是唯一的方法。
The reason this doesn't work is that the two
exec()
invocations start two different shells; the one you set the path in isn't the one you check it in.It's difficult to change the permanent, systemwide path setting. But you can change the path for the duration of the invocation of one or more programs that you need it for.
Specifically, the thing to do is to write yourself a batch file (
.CMD
or.BAT
, as you please), set thePATH
near the beginning, follow that with whatever DOS/Windows commands you'd like executed with that path, and thenexec()
that script file.Updating the PATH for the current Java process seems pretty pointless. Java, once running, doesn't care about the path. Or are you running some library code that does?
If you are running DOS/Windows commands from Java using
exec()
, the above trick will work.Update: OK, you have library code that for reasons of its own wants the PATH set just so, and you want to give it what it wants.
What I would consider here is to fire up a new JVM. You can use
exec(cmd, envp)
to start up a new Java application ("yourself," in a pinch) with a custom set of environment variables inenvp
. Just copy the ones that are already there and manipulate the contents ofPATH
, if any.The standard way to start up a new Java app is to create a new
ClassLoader
, and there are various descriptions on how to accomplish that. But I'm not sure you can use that procedure to come up with a new environment - soexec
-ing the JVM may not only be simpler, but possibly the only way.仅运行批处理文件是不可能实现这一点的。请参阅此处了解详细信息。
您的解决方案不起作用,因为它只修改进程级别的环境变量,而不是系统级别的环境变量。
This is not possible with just running a batch file. See here for details.
Your solution doesn't work, because it only modifies the environmental variable in the process level and not in system level.
如果您使用 JNI 扩展,您可以通过 -Djava.library.path 选项将路径传递到本机库所在的位置,这也可能适用于您的 exec 情况。另一个选项是从批处理文件启动 java 应用程序,并在启动 java 应用程序“之前”在命令解释器中编辑 PATH 设置,java 应用程序将继承此 PATH 设置。
NASA WorldWind 使用本机库,可以作为 Applet 运行,这里是使用 JNLPAppletLauncher。它的主要作用是检测操作系统,获取适当的本机库,将它们保存在默认 jvm 路径中的某个位置并执行。从 Java 小程序调用 exec 违反了各种合理的安全性和沙箱原则,我真的会避免它。
You can pass paths to where the native libraries are located via the -Djava.library.path option if you are using JNI extensions, this may also work for your exec case. The other option is to launch the java app from a batch file and edit the PATH settings in the command interpreter "before" you launch the java app, the java app will inherit this PATH settings.
NASA WorldWind uses native libraries and can be run as an Applet, here is a howto on setting this up with JNLPAppletLauncher. What this basically does is detect the OS, fetch appropriate native libraries, save them in a location in default jvm path and execute. Calling exec from a Java applet violates all sorts of sane security and sandboxing principles and I would really avoid it.