当我使用 Java Bloomber V3 API 时,它通常可以工作。但是,有时,尤其是在重新启动后,bbcomm.exe 不会在后台运行。我可以通过运行 blp.exe 手动启动它,但我想知道是否有办法通过 API 执行此操作?
我仍在等待帮助...
与服务台交谈后发现,在 64 位 Windows 上,在 64 位 JVM 下运行的 bbcomm 不会自动启动。这在 32 位 Java 下不会发生 - 在 32 位 bbcomm 下会自动运行。
所以我的解决方案是要么等待彭博解决问题(现在我明白了),要么检查这个具体案例。
检查具体情况:
os.arch
)java.vm.name
)bbcomm.exe
没有运行。尝试bbcomm.exe
使用Runtime.exec()
我还没有测试过上面的。它可能与彭博在 64 位 VM 上遇到的问题完全相同。
在使用 Help Help 一段时间后,似乎 bbcomm 可以在您使用 Excel API 或运行 API 演示时启动。但当从 Java API 调用时,它不会自动启动。可能的启动方法是:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
添加一个用 value 调用的 String 值bbcomm
-C:\blp\API\bbcomm.exe
但这会打开一个仍然可见的命令窗口,所以不是一个真正的选项(如果你关闭该窗口,它会终止 bbcomm 进程)START /MIN C:\blp\API\bbcomm.exe
并将注册表中的条目替换为(未经测试)以静默调用 bbcommprivate final static Logger logger = LoggerFactory.getLogger(BloombergUtils.class);
private final static String BBCOMM_PROCESS = "bbcomm.exe";
private final static String BBCOMM_FOLDER = "C:/blp/API";
/**
*
* @return true if the bbcomm process is running
*/
public static boolean isBloombergProcessRunning() {
return ShellUtils.isProcessRunning(BBCOMM_PROCESS);
}
/**
* Starts the bbcomm process, which is required to connect to the Bloomberg data feed
* @return true if bbcomm was started successfully, false otherwise
*/
public static boolean startBloombergProcessIfNecessary() {
if (isBloombergProcessRunning()) {
logger.info(BBCOMM_PROCESS + " is started");
return true;
}
Callable<Boolean> startBloombergProcess = getStartingCallable();
return getResultWithTimeout(startBloombergProcess, 1, TimeUnit.SECONDS);
}
private static Callable<Boolean> getStartingCallable() {
return new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
logger.info("Starting " + BBCOMM_PROCESS + " manually");
ProcessBuilder pb = new ProcessBuilder(BBCOMM_PROCESS);
pb.directory(new File(BBCOMM_FOLDER));
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("started")) {
logger.info(BBCOMM_PROCESS + " is started");
return true;
}
}
return false;
}
};
}
private static boolean getResultWithTimeout(Callable<Boolean> startBloombergProcess, int timeout, TimeUnit timeUnit) {
ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Bloomberg - bbcomm starter thread");
t.setDaemon(true);
return t;
}
});
Future<Boolean> future = executor.submit(startBloombergProcess);
try {
return future.get(timeout, timeUnit);
} catch (InterruptedException ignore) {
Thread.currentThread().interrupt();
return false;
} catch (ExecutionException | TimeoutException e) {
logger.error("Could not start bbcomm", e);
return false;
} finally {
executor.shutdownNow();
try {
if (!executor.awaitTermination(100, TimeUnit.MILLISECONDS)) {
logger.warn("bbcomm starter thread still running");
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
ShellUtils.java
public class ShellUtils {
private final static Logger logger = LoggerFactory.getLogger(ShellUtils.class);
/**
* @return a list of processes currently running
* @throws RuntimeException if the request sent to the OS to get the list of running processes fails
*/
public static List<String> getRunningProcesses() {
List<String> processes = new ArrayList<>();
try {
Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
int i = 0;
while ((line = input.readLine()) != null) {
if (!line.isEmpty()) {
String process = line.split(" ")[0];
if (process.contains("exe")) {
processes.add(process);
}
}
}
} catch (IOException e) {
throw new RuntimeException("Could not retrieve the list of running processes from the OS");
}
return processes;
}
/**
*
* @param processName the name of the process, for example "explorer.exe"
* @return true if the process is currently running
* @throws RuntimeException if the request sent to the OS to get the list of running processes fails
*/
public static boolean isProcessRunning(String processName) {
List<String> processes = getRunningProcesses();
return processes.contains(processName);
}
}
我知道这是一篇旧帖子,但我想我会添加我的解决方案以供参考,以防有人需要帮助从代码隐藏控制台窗口检查/启动bbcomm.exe进程。
这个片段是用 C# 编写的,但我希望你可以轻松地将它翻译成 Java。
void Main()
{
var processes = Process.GetProcessesByName("bbcomm");
if (processes.Any())
{
Console.WriteLine(processes.First().ProcessName + " already running");
return;
}
var exePath = @"C:\blp\DAPI\bbcomm.exe";
var processStart = new ProcessStartInfo(exePath);
processStart.UseShellExecute = false;
processStart.CreateNoWindow = true;
processStart.RedirectStandardError = true;
processStart.RedirectStandardOutput = true;
processStart.RedirectStandardInput = true;
var process = Process.Start(processStart);
Console.WriteLine(process.ProcessName + " started");
}
bbcomm.exe 由 V3 API 自动启动。