|
I am guessing no then.
Sincerely,
Max Pastchenko
|
|
|
|
|
I have a Win32 application that, for reasons that are beyond the point I'm raising here, needs to execute a Win16 application. The Win16 EXE is copied to the TEMP folder and run from there.
The program (the Win32 one, that is) first determines the TEMP folder with GetTempPath(). In a lot of cases, I get something like C:\Documents and Settings\[profile]\Local Settings\Temp.
CreateProcess() fails if I specify a Win16 name if the EXE is in a path that doesn't respect the old 8.3 rules. To work around this "problem", I call GetShortPathName() to have the TEMP path converted to C:\DOCUME~1\[profile]\LOCALS~1\TEMP, to which I append the EXE name and call CreateProcess() -- this works.
Here's one problem:
I have a customer who runs the Win32 application (on XP SP2), which copies the EXE to the appropriate TEMP folder (I've confirmed this). Then he gets an OS dialog box (NOT generated by my program) with a caption saying "Can't run 16-bit Windows program" and the message saying "Cannot find file C:\DOCUME~1\[profile]\Local Settings\Temp\MYAPP.EXE".
Notice the "Local Settings" part--that, somehow, didn't get translated, and CreateProcess() fails.
I can't reproduce this problem on my end--when I call GetShortPathName(), every part of the path correctly gets converted to 8.3 format. If I hardcode the FUBARed path in a test program ("C:\DOCUME~1\[profile]\Local Settings\Temp"), then CreateProcess() fails (returns FALSE), but I CANNOT, under any circumstances, get the OS to display that dialog box.
I've also confirmed with the customer that re-pointing the TEMP variable to something like C:\TEMP fixes the problem.
- Has anyone ever seen GetShortPathName() fail in this fashion?
- If I can't rely on that API to return a correct path, what can I use (*RELIABLY*) as a temporary folder? My users have mixed OS environments, from Win95 to 2003, with different users having different permissions on different drives--some have a totally locked down system and I can't even temporarily create my own folder and delete it later. In essence, *where* am I guaranteed to be able to temporarily write files to and then delete files from, if I can't rely on %TEMP%?
Hints appreciated...or better yet, a KB article that shows Microsoft acknowledging this as a problem addressed with a hotfix I can show to the customer...
|
|
|
|
|
Daniel Desormeaux wrote:
Then he gets an OS dialog box (NOT generated by my program) with a caption saying "Can't run 16-bit Windows program" and the message saying "Cannot find file C:\DOCUME~1\[profile]\Local Settings\Temp\MYAPP.EXE".
So does this imply that GetShortPathName() succeeded in shortening the path to C:\DOCUME~1\[profile]\LOCALS~1\TEMP but that CreateProcess() has interpreted it as C:\DOCUME~1\[profile]\Local Settings\Temp instead? If, however, GetShortPathName() is failing, what does GetLastError() return?
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
I'm not entirely certain at this point, but I would have to wonder why CreateProcess() would take an 8.3 path and interpret it differently. There is currently no check for the value returned by GetShortPathName() (bad, I know), so I'll have to send the customer a special build to have it logged.
Graham's suggestion (that the NtfsDisable8dot3 registry setting might be disabled) is an interesting one, although if that was the case, I wouldn't expect the "Documents and Settings" part to get converted to DOCUME~1 (it was)...
|
|
|
|
|
Daniel Desormeaux wrote:
I'm not entirely certain at this point...
Ok, if it is then you know the problem is not with GetShortPathName() .
That still leaves an oddity with CreateProcess() . Have you ruled out AV software getting in the way?
Also, is MSDN article Q198429 of any help?
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
> Ok, if it is then you know the problem is not with GetShortPathName().
Actually, if GetShortPathName() failed, I wouldn't expect the output buffer to contain anything at all upon return, which isn't the case. I know that's an assumption, but still...
In any case, after further investigation, it looks like Graham's hint was right on the money. If I prevent the OS from creating 8.3 names, then any folder created *after* changing the registry value (and rebooting) will *not* get translated by GetShortPathName() (eg, "Local Settings" will be returned as just that, and not LOCALS~1).
Even with Explorer itself--if I copy a 16-bit EXE into a folder that doesn't have an 8.3 equivalent, and then double-click the EXE, Windows displays a message saying it can't find the file...
Next step is to ask the customer if he's messed with that registry value (predeployed disk image, SYSPREP tool, etc)...
|
|
|
|
|
[Wild Guess]
The customer has the NtfsDisable8dot3 registry setting enabled?
[/Wild Guess]
|
|
|
|
|
I found a very useful guide to Windows programming from the ground up here. I followed it pretty closely, changing around a little bit by functionizing the initialization. The problem is when I run my app, it consumes all CPU power but I don't have it doing anything when the window pops up, just a window with a menu on top. Can someone go through that page and tell me if I or he missed something to create this problem? Thanks in advance.
|
|
|
|
|
Without seeing what code you actually put in place, it's kind of hard to say what might be wrong.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
I tried to not put code on here because of it's size, but if it must be done. Here's all I wrote, it creates a simple white window.
#define WIN32_LEAN_AND_MEAN<br />
<br />
#include <windows.h><br />
#include <windowsx.h><br />
<br />
LRESULT CALLBACK MessageHandler (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {<br />
return DefWindowProc (hWnd, Msg, wParam, lParam);<br />
}<br />
<br />
ATOM InitializeWindowClass (HINSTANCE hInstance) {<br />
WNDCLASSEX wndClass;<br />
<br />
wndClass.cbSize = sizeof(WNDCLASSEX);<br />
wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;<br />
wndClass.lpfnWndProc = MessageHandler;<br />
wndClass.cbClsExtra = 0;<br />
wndClass.cbWndExtra = 0;<br />
wndClass.hInstance = hInstance;<br />
wndClass.hIcon = LoadIcon (NULL, IDI_WINLOGO);<br />
wndClass.hCursor = LoadCursor (NULL, IDC_ARROW);<br />
wndClass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);<br />
wndClass.lpszMenuName = NULL;<br />
wndClass.lpszClassName = "Win32 Test";<br />
wndClass.hIconSm = LoadIcon (NULL, IDI_WINLOGO);<br />
<br />
return RegisterClassEx(&wndClass);<br />
}<br />
<br />
HWND CreateRootWindow (HINSTANCE hInstance) {<br />
HWND hWnd = CreateWindowEx(NULL, <br />
"Win32 Test",<br />
"Sample Window",<br />
WS_POPUP | WS_VISIBLE,<br />
300, 300, 800, 600,<br />
NULL,<br />
NULL,<br />
hInstance,<br />
NULL);<br />
<br />
return hWnd;<br />
}<br />
<br />
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {<br />
LPMSG msg = NULL;<br />
<br />
InitializeWindowClass (hInstance);<br />
HWND hWnd = CreateRootWindow (hInstance);<br />
<br />
while (true) {<br />
if (PeekMessage(msg, NULL, 0, 0, PM_REMOVE)) {<br />
TranslateMessage(msg);<br />
DispatchMessage(msg);<br />
}<br />
<br />
}<br />
|
|
|
|
|
maybe you sould take a look at WaitMessage(VOID);
|
|
|
|
|
I had a suspicion something like that was there but I just couldn't find it. Thanks. Now to try to figure out the menus.
|
|
|
|
|
Try replacing:
<br />
while( true )<br />
{<br />
if( PeekMessage(...) )<br />
with
<br />
while( GetMessage(...) )<br />
GetMessage stops the program for running while waiting for a message, while PeekMessage doesn't, and you have a loop running at full speed.
HTH
|
|
|
|
|
Good call, I was wary of the `while(true)' loop.
|
|
|
|
|
Shouldn't that message loop be:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
Yes, as long as this window message handling loop is not responsible for any dialog boxes.
Otherwise, and you need to know the dialog box's window handle:
while (GetMessage(&msg, NULL, 0, 0)){
if( !IsDialogMessage(hWndDialogBox, &msg) ){
TranslateMessage(&msg);
DispatchMessage (&msg);
}
}
You also might want to break if the message is WM_QUIT.
Now, the new and improved suggestions, from MSDN is:
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
if( !IsDialogMessage(hWndDialogBox, &msg) ){
TranslateMessage(&msg);
DispatchMessage (&msg);
}
}
}
|
|
|
|
|
Hi all,
I was wondering if anyone could refer me to some c++ class that can be used to generate xml code from a dtd file. If not, then if someone knows of a class that can be used to validate a dtd file and/or tokenize it; not validate xml using dtd, but make sure that a dtd file is "valid".
Thanks in advance,
-----------------
Genaro
\\\|
_ _
@ @
_\\
--|
_/
|
|
|
|
|
I'm not sure, but I'd lean towards the IXMLDOMDocument interface and its methods.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
I looked into this class, but I am pretty sure it doesn't provide this functionality. I have not been able to find any class that will generate a basic valid xml document from a dtd file.
-----------------
Genaro
\\\|
_ _
@ @
_\\
--|
_/
|
|
|
|
|
HI
I am getting error in executing a program ..It says that a dll file is not found.
How do I fix that?
Thanks
Preeti9
|
|
|
|
|
Preeti9 wrote:
How do I fix that?
Supply the missing DLL, perhaps, or at least ensure that the DLL is located in one of the paths pointed to by the PATH environment variable. Without any more detailed information than what you've provided, I can't offer much more.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
Thanks for reply
I don't understand how to ask...But let's see....
I don't know how to add that DLL file. I don't know why it is looking for that DLL file.
What do you mean when it says that
"Installing the file can fix the problem" ?
Thanks
Preeti9
|
|
|
|
|
Preeti9 wrote:
I don't know why it is looking for that DLL file.
Use Dependency Walker or Dumpbin to find out what DLLs are required by the application. Those DLLs, and possibly others, must exist on the target machine.
Preeti9 wrote:
What do you mean when it says that
"Installing the file can fix the problem" ?
Isn't that self-explanatory? If the file existed and could be located by the OS, the problem would not exist.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
I know that's self explanatory but I didn't know where from install the DLL file.
Thanks
Preeti9
|
|
|
|
|
Preeti9 wrote:
...but I didn't know where from install the DLL file.
And you assumed someone here would, given that you did not provide the name of the application or the missing DLL?
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|