CreateProcess for Running JAR File Starts with Window Minimized - java

I'm using a CreateProcess call within a C++ program to execute a JAR file that runs a Java Swing GUI application. All works fine with the exception that the Java app starts off minimized and I want it to start with the window displayed. Here's the relevant code snippet:
// Construct the command string to be used for the CreateProcess call,
//including a parameter string
sprintf(cmdStr, "javaw -jar \"AppDir\\App.jar\" %s", parmStr);
// Create and initialized startup-info structure for use with CreateProcess call
STARTUPINFO startInfo;
ZeroMemory(&startInfo, sizeof(startInfo));
startInfo.wShowWindow = SW_NORMAL;
startInfo.dwFlags = STARTF_USESHOWWINDOW;
startInfo.cb = sizeof(startInfo);
PROCESS_INFORMATION procInfo;
ZeroMemory(&procInfo, sizeof(procInfo));
if (!CreateProcess(NULL, cmdStr, NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &procInfo))
{
MessageBox( dialogOwner, "Create Process Error", "Application not instantiated", MB_OK);
}
According to the MSDN literature, setting the wShowWindow flag to SW_NORMAL and dwFlags to STARTF_USESHOWWINDOW ought to do the trick but some of the comments I've read in this and other forums imply that sometimes those flags are ignored (e.g. for console apps) so I was wondering if that was the case here. For the record, I've had this problem before then it went away on its own and now it's back after I made some code changes. But I wasn't setting any flags in the startupinfo structure before, so I was hoping to achieve some consistency in behaviour by doing so. Any tips or pointers would be appreciated...
Sheldon R.

Okay, I've been working on a solution to my problem and I'm finally ready to talk about it, since it appears to be working :) I call my Java app one of two ways: either by popping up a dialog box first to collect login credentials, or by calling the app directly using saved credentials. For the login-dialog case, I call CreateProcess with the parameter "javaw...", whereas the saved-credential case appears to need "java..." to avoid the app starting up minimized. Aside from the difference in the parameter string, everything else about the CreateProcess call is the same. I don't know why I would use "java" in one case and "javaw" in the other, but since it's working, I won't question it :) But, of course, if someone wants to enlighten on the subject, I'd be happy to learn more. Thanks to #Jim Garrison for the suggestion, even if it wasn't ultimately the solution to my issue...
Sheldon R.

This is an update to my previous answer: The reason I had to call my java applet two different ways (i.e. "java" or "javaw") depending on the context, had to do with a bug in the C++ application from which I was calling my applet. The reason I know this is because a few months after fixing my issue, a newer version of this application was released, and this version didn't have the underlying bug, which essentially caused a new bug in my applet due to the "java" command doing what you'd expect i.e. instantiating a console window in addition to the applet window, much to the surprise of my business users :). So for the new bug-free version of the C++ application, I call my applet using the "javaw" command regardless of whether or not a dialog box is instantiated first to enable the user to enter login credentials...
Sheldon

Related

java - How do I prevent CTRL+ALT+DEL? [duplicate]

I'm writing a screen saver type app that needs to stop the user from accessing the system without typing a password. I want to catch/supress the various methods a user might try to exit the application, but all research I do seems to point me to "you can't".
Anything in C# or C++ would be great.
I've thought of disabling the keyboard, but then I would have other issues.
You can't. The whole point of Ctrl+Alt+Del is that only the system gets to handle it, 'cause that way the system can always handle it.
Fortunately, Windows has built-in support for password-protected screensavers (available as the "On resume, password protect" option in Display Properties, or via group policy). Just use that.
To add to what Shog9 said, if your application could intercept ctrl+alt+del, then your application would be able to pretend to be the Windows Login dialog, and by doing so trick the end-user into typing their credentials into your application.
If you do want to replace the Windows Login dialog, see Winlogon and GINA (but this says, "GINA DLLs are ignored in Windows Vista", and I haven't heard what's what for Vista).
if someone asked I'd not tell them they can't.
More specifically, your "application software" can't: instead, by design, only "system software" can do this; and it isn't that you're not allowed to or not able to write system software, but your OP seemed to be quite clearly asking how to do it without writing system software ... and the answer to that is that you can't: because the system is designed to prevent an application from hooking these key combinations.
Can you give me direction to writing the system things.. I actually think this would be better if it were system level.. It's for an OEM so kind of the point really. Also if I wrote it system level, I could write an app to control it.
A keyboard filter device driver, or a GINA DLL, for example, would be considered system software: installed by an administrator (or OEM) and run as part of the O/S.
I don't know about GINA beyond its name; and I've already (above) given a link it in MSDN. I expect that it's Win32 user-mode code.
Device drivers are a different topic: e.g. Getting Started on Driver Development.
Is there a way to remap the keyboard so that delete isn't where it was?
I still not sure that you and/or your boss have the right idea. IMHO you shouldn't be an application which prevents the user from pressing Ctrl-Alt-Del. If you want to stop the user from accessing the system without typing a password, then you ought to lock (password-protect) the system, as if the user had pressed Ctrl Alt Del and then selected "Lock this computer". To unlock the computer they would then need to press Ctrl Alt Del and enter their credentials into WinLogon.
However, ignoring what you ought to do and concentrating instead on what you're capable of doing, if you want to intercept the keyboard, apparently it can be done. I haven't studied keyboards myself, but this post and this post claim success, by writing a "Keyboard Filter Driver" (which is a kind of kernel-mode, not Win32, device driver). If you write one of these though you may get some push-back, e.g. like this reaction from a DDK MVP, or this reaction from an anti-snooping product.
I have not tested it but what about using SetWindowsHookEx()
From MSDN documentantion:
WH_KEYBOARD_LL
Windows NT/2000/XP:
Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.
It is possible to intercept crtl+alt+del, though obviously Microsoft made it very difficult to do, because then you could pop-up a fake lock dialog, and record people's passwords.
The answer is to write a device driver. I can't remember if you can just use a plain old keyboard filter, or if you have to write a keyboard ISR. Either way, its certainly possible, but with great pain if you have no driver experience.
As this seems to be a good collection spot for the accrual of various means with which to "intercept" the three key psuedo-break
control alt delete, here is something I encountered yesterday that may be of use.
http://cuinl.tripod.com/Tips/enablectrldel.htm
In my opinion, when it seems that the only practical and timely option is to cut the power (i.e. MECHANICAL removal of the battery of an overloaded android-like handheld computer) to halt whatever procession or malfunction results in rather solid and complete ( or long enduring) irresponsiveness-- it appears that a dangerous and frustrating lineage continues--- and continues to get worse.
Especially with the removal of sensible and straightforward things like mechanical speaker volume controls. ( sure, bulky, more material, but of course that is just the thing, what good to an individual or being is infinite and perfect consciousness without a handle on it or it's experience?)
It is a lineage of approaches to designing the -environment that is responsible for the responsiveness to the user- part of a critical and truly meaningful technological interface. ( The only?)
I say put some buttons --direct-to-hardware-control-- back on the things --at least until the software aspects of these technologies become fully adapted to artificial soft interfacing, which I account for in an exhaustive accounting of all heuristical provisionings.
Even in the mechanics of the universe I bet there's a handy reset, restore, suspend, halt type of function(s) for the safety and fundamental viability of the presence of what would constitute as the designer of all that follows the initiating perpetual mystery of existence: INTELLIGENT AWARENESS and WILL.
"Process Explorer" by Mark Russinovich (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) does it, and it had been doing before Sysinternals was bought by Microsoft.
This article from 2002 updated in 2006 explains one way to do it without writing a keyboard driver.
http://www.codeproject.com/KB/system/preventclose.aspx?msg=1666328
starting taskmgr.exe in hidden window would do the job if you just wanted to suppres the call to task manager
ProcessStartInfo taskmgr = new ProcessStartInfo()
{
FileName = "taskmgr.exe",
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(taskmgr);
You could achieve that in XP and before, but with Vista not anymore.
Try investigating if you could write an application that starts itself as a password protected screensaver.
Screensavers can do more than just display pretty pictures - I've seen interactive screensavers before that used the mouse and keyboard to provide a simple game, though I can't remember which version of windows I saw this running on... It could well have been windows 95. (In which case all bets are off).
What about intercepting ctrl and alt keypresses while your program is running, and .cancel'ing those keypresses?
I don't know how well this would work, if at all in Vista, but it's worth a try.
I remember doing something like this around the year 2001, so it was probably running on 98. Been too long since I've even tried to mess with anything like locking out ctrl-alt-del.
Ok.. I'm not going to post the code here
But the gyst is this
create a keyboard hook.
when the user presses ctrl || alt || delete set bools to true.. if they press anything else set them all to false.
switch (p_key)
{
default: Clear(); break;
case Keys.LMenu: altHit = true; break;
case Keys.RMenu: altHit = true; break;
case Keys.LControlKey: ctrlHit = true; break;
case Keys.RControlKey: ctrlHit = true; break;
case Keys.Delete: delHit = true; break;
when the screen has focus looses it to the task manager, close the bloody thing.
The screen flashes so fast the user never notices it.
And I can do what ever I want.
I'll admit this is a kludge, but it does result in the desired effect. (OH I wish I didn't have to do this)
I was reading this doc page, and some thought and searching brought me to this question.
https://learn.microsoft.com/en-us/windows/win32/learnwin32/keyboard-input
I have not tested it, but there is this excerpt:
As the name implies, system key strokes are primarily intended for use
by the operating system. If you intercept the WM_SYSKEYDOWN message,
call DefWindowProc afterward. Otherwise, you will block the operating
system from handling the command.
Seems like a security hole to me if it actually works like it says.
You can still intercept Ctrl + Alt + Del in windows 7.
This is the way Process explorer does it:
http://mygreenpaste.blogspot.com/2005/07/image-file-execution-options-good-evil.html

How do I find the name of the program that would launch a given file?

I am looking for a way to find the name of the program (in my code) that will launch when an operating system tries to open a given file. I will not be launching the application I'm just looking for its name. Ideally the routine I'm looking for/building would take a filename and return a string. I am programming in Java 8 on Eclipse and need my jar file to stay cross platform.
Simplest solution I can find is to use SWT's class 'Program'. Although this assumes that I can correctly identify filetype which is another big can of worms I'm not going to into here.
String ext = extractFileType(filename);
Program p2 = Program.findProgram(ext);
if (p2 != null) programName = p2.toString();
But for a number of reasons I DON'T WANT TO USE the SWT library if at all possible. I'm using Swing and and I really don't want my clients to need to download a different application (jar) dependent on their operating system. I'm well aware that the underlying code is operating system/Window Manager dependent.
Anyone know of any other package besides SWT that already does this? I can't find one. Or similar enough I can strip the results to get what I want? Even if it's only for one platform? I'm experimenting with Apache Tika but I don't see anything helpful there.
Any hints on where to look to start write this myself? I know this entails reading the registry on Windows. I need this code to work on the most recent versions of Windows, and OS X. And eventually Linux but Linux windowing systems are not a priority.
Is there a way to link/load SWT in Eclipse to make the cross-dependent part of using SWT this code a little more lightweight and invisible to the end user? I'm not new to coding but am to using Eclipse.
Here is a quick description of my solution. I did a fair amount of hunting around and I deciding on simply using the JNA library. https://github.com/java-native-access/jna and writing my own native library on a Macintosh to get it to work.
Windows: Fairly straight forward usage of JNA. I'm calling FindExecutable & PathFindExtension from JNA.
public interface MyShell32 extends Shell32 {
MyShell32 INSTANCE = (MyShell32) Native.loadLibrary("shell32", MyShell32.class, W32APIOptions.DEFAULT_OPTIONS);
WinDef.HINSTANCE FindExecutable(String lpFile, String lpDirectory, char[] lpResult);
}
{
...
char[] returnBuffer = new char[WinDef.MAX_PATH];
shell.FindExecutable(filename, null, returnBuffer);
app = Native.toString(returnBuffer);
...
}
PathFindExtention() call is similar but returns a pointer so it's more straight forward.
Macintosh: I tried all sorts of things and finally decided to write my own tiny native library to call in objective C
rtnValue = [[NSWorkspace sharedWorkspace] getInfoForFile:filenameNS
application:&AStr
type:&TStr];
This library is tiny (but I may add to it if I need other native calls) but I need to write a C/C++ shell as well as the Objective C to get it to work. I then call this library JNA. Not that different from writing straight JNI but I found it easier to code.
public interface NSWWraper extends Library {
/** The instance **/
NSWWraper INSTANCE = (NSWWraper) Native.loadLibrary("NSWWraper", NSWWraper.class);
// CP_NSWWraper
Pointer FindFileInfo(String filename);
void FreeMem(Pointer memory);
}
I honestly haven't tested this calling this a large number of files so I don't know how much it slows down my code. JNA calls are supposed to be expensive. It's interesting timing on someone asking for my solution as I'd had to put this on back burner and only got it working on Windows yesterday. I was going to incorporate this into the rest of my project today.
Edited to add. I didn't use JINI because I found it's not being very well supported on a Macintosh anymore and JNA was the better solution for Windows and I had to use it anyway.

Hotswap/DCEVM doesn't work in Intellij IDEA (Community Version)

I have troubles in making use of the hotswap function in Intellij IDEA Community Version. Mine is v 14.1.4.
Each time after I fired off debugging and change the java code, I have already click rebuild project and press "Yes" on confirming reload classes. Intellij reports that changed classes are reloaded, but the application outcome is the same as before. I'm just trying the simplest Java application (i.e. not in scenarios like Tomcat, applet etc) with stuffs simply like System.out.println, string concats etc. What I've changed during debug mode is just method body codes, but not the method signature/name. I can't get it.
In Eclipse I just directly change the code and press save, then it just works.
What went wrong?
(Remarks:
In fact I'm attempting to use DCEVM which makes structure change possible (e.g. change class name, method name, add methods etc), thought that it would solve the problem of the hotswap problem found in Intellij. Needless to say, it didn't work.
In eclipse, I succeed in using DCEVM and can change the method names during debugging.
I further try hotswap-agent and it still didn't work; I've come across an article saying that the IDE must JDPA-connect to the JVM thru port 5000, but no matter how I tried, Intellij console shows that it is still connecting thru a random port (51018 below):
"C:\Program Files\Java\jdk1.8.0_60\bin\java" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:51018...."
Connected to the target VM, address: '127.0.0.1:51018', transport: 'socket'
Is it possible to force it to connect thru one specific port?
Adding the DEBUG_OPT environment variable in the Run/Debug Config doesn't work)
Found out that it is Intellij's by-design behaviour after finding one feedback from Jetbrains to an issue request:
In other words, the problem is related to how I test out the hotswapping:
public class Main {
// /*
public static String getName() {
return "James"; // <=== (2)
}
//*/
public static void main(String[] args) {
System.out.println("Hello " + getName()); // <=== (1)
}
}
As Intellij's behaviour is that "the old code is still used until the VM exits the obsolete stack frame" (a different behaviour comparing to Eclipse), if you change "Hello" to "Bye" at (1), the new code will never be executed - the new code can be executed again only when main() is called the second time, which is impossible as the application is terminated already
If it is (2) that is changed (say, replacing "James" w/ "Sean") instead of (1), during the time when the execution cursor is being stopped by a breakpoint placed at (1) (therefore haven't entered to getName() yet), and you reload the class, you will get the new code being run (printing "Sean")
DCEVM worked perfectly too, using the same way to test the hotswapping
You can also use "drop frame" in the stack trace window to make the current statement roll back to the method's beginning (except main()) - in fact it's the same behaviour in Eclipse.

How can I know when a javax.jnlp.PrintService is done printing my Printable object

I'm using JNLP to print some images inside an applet. I pass a Printable object to a javax.jnlp.PrintService instance and call PrintService.print(). Is there any way to know when this operation completes?
Looking at line 116 of the PrintService source code, it seems to start a thread for printing and not attach anything to keep track of it.
There seems to be mechanisms for tracking print operations in other parts of Java, but I have not had success using other printing mechanisms in the context of a browser applet. (the user is constantly nagged about security)
Is it possible to print something in a signed java applet, not have the user be nagged about security, and know when the print operation finishes?
I managed to solve this problem by switching from using javax.jnlp.PrintService to using javax.print.PrintService. Using the later allows you to attach a PrintJobAdapter to monitor the status of the print job. See this Stack Overflow question.
All of this is perfectly acceptable in a JNLP deployed applet, provided the applet is signed.

How to capture result from a rundll32 invocation?

I've been bitten by this old bug/missing feature in Java:
http://bugs.sun.com/view_bug.do;jsessionid=b2ac8ea11f05c16d948e24d36fb5?bug_id=4673406
The thing is that the "Properties" button in Java's standard print dialog is seemingly always disabled on Windows. The button is only enabled if PrintService.getServiceUIFactory() returns something that isn't null. Unfortunately Win32PrintService instances always return null. Always.
By googling, I discovered that you can invoke Windows' own print properties dialog thingy by calling rundll32:
rundll32 printui.dll,PrintUIEntry /e /n "name of printer here"
I'm hoping I can use this to circumvent the bug/missing feature in Win32PrintService. However, I don't know how I can query the PrintUIEntry-dialog for the user's choices.
In other words, how can I get a result of the above rundll32-invocation? (If I have to write something in C/JNI and use the Windows API directly, so be it. I'd rather not, though.)
Or is there a better way to solve this problem?
rundll32 does not give you any return value, its exit code is always zero.
I think you'll have to find another way.

Categories