"Joseph M. Newcomer" <newcomer@flounder.com> schrieb im Newsbeitrag
On Wed, 28 Mar 2007 14:30:35 +0200, "Kerem G?mr?kc?"
<kareem114@hotmail.com> wrote:
Hi,
i have some Code, that gives me a GetlastError()=1008.
"1008 An attempt was made to reference a token that does not exist."
*****
Having read all the code below, I do not see a single instance where you
do a
::GetLastError. So why are you showing irrelevant code?
****
The interesting thing is, that the first call to the function does work
as
expected,
*****
Note that you cannot do something like
SomeAPI(...);
DWORD err = ::GetLastError();
if(err != ERROR_SUCCESS) ...
this code would be erroneous, although, from your description, it is the
code I expected
to see.
The correct code would be
if(!SomeAPI(...))
{
DWORD err = ::GetLastError();
...deal with error
}
::GetLastError, with a few exceptions, is defined ONLY if the API
failed.
****
but the second does not and throws this exception.
****
What do you man "thows an exception"? ::GetLastError returning a value
is
not related to
any concept of exception. If an exception is thrown, that is a
different
issue. Since
you did not bother to show any of the code involved in this question,
exactly what are we
supposed to diagnose? If an exception IS thrown, you would, of course,
have information
that told you exactly what line was involved, and you would have a
description of the
exact exception, and you have not told us either one of these. Are we
supposed to guess
what is happening here?
****
Sometimes it even makes
the application fail and crushes it. Behaves really "Exceptional"... :-(
What the Code does:
It starts a cmd.exe with parameters "chkdsk.exe" and if
"this->m_StartWithOutputRedirection" is set to TRUE
then it redirects the Output to a file with the ">" Operator. I only get
the
1008 when the cmd.exe is startet with the output redirection to some
file.
Then the first call works fine and the second fails with 1008. Why?
*****
I see no instance of ::GetLastError in the code below. So how are we
supposed to figure
out how you get this mysterious value?
I dont know why this happens, but maybe someone can help me. Here is the
"misbehaving" code (error handling will be done in higher
level!)section:
VOID CCheckDiskShellDlg::CreateChkDskProcess(CString sCMD, CString
sCommandLine,BOOL bWithOutputRedirection)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
CString sFullCommand;
CString sCurrentTime;
CTime cCurrentTime;
TCHAR lpszDesktopPath[MAX_PATH];
LPTSTR lpszCommand;
ZeroMemory(&lpszDesktopPath[0],MAX_PATH);
if(!SUCCEEDED(SHGetSpecialFolderPath(this->m_hWnd,
lpszDesktopPath,
CSIDL_DESKTOPDIRECTORY,
FALSE))){
GetCurrentDirectory(MAX_PATH,lpszDesktopPath);
}
strcat(lpszDesktopPath,"\\");
****
You should not be using strcat; it is dangerous and obsolete. You
should
use _T() around
all literals, and use something like _tcscat_s (in VS2005) or
StringCchCat
(in strsafe.h)
****
cCurrentTime = CTime::GetCurrentTime();
sCurrentTime = cCurrentTime.Format(_T("Started: %H:%M:%S"));
CString sTimeForLogFile = cCurrentTime.Format(_T("%d_%m_%y_%H_%M_%S"));
ZeroMemory(&sa,sizeof(sa));
sa.nLength = sizeof(sa);
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
sFullCommand = sCMD + " " + sCommandLine;
****
Some important questions:
(a) what is sCMD?
(b) what is the EXACT syntax of the command line you are trying to
create?
(c) given the answer to (b), have you tried the command line you are
creating simply by
launching a command shell and typing this command in to it?
I suspect your basic command line is erroneous.
****
lpszCommand = new TCHAR[sFullCommand.GetLength()+1];
*****
And what is wrong with a CString? You can use GetBuffer to get the
LPTSTR
you need for
CreateProcess.
****
if(this->m_StartWithOutputRedirection == TRUE){
*****
NEVER, EVER, UNDER ANY CIRCUMSTANCES IMAGINABLE, WRITE AN EXPRESSION
LIKE
THE ABOVE! EVER!
A boolean value is, well, a boolean value. It ALREADY represents true
or
false state.
Comparing to the literal TRUE or FALSE is absolutely silly. Do ;you
write
if( (A > 0) == TRUE)
as an expression? No, of course not. A > 0 is a boolean expression.
So
a boolean
variable is tested by writing
if(m_StartWithOutptRedirection)
you don't need this-> and the inclusion of == TRUE is erroneous. Note
that a non-false
value is not necessarily == TRUE.
Also, I'm curious why you are passing a boolean variable in as a
parameter
which has a
name that suggests it would indicate if redirection should be used, and
then test a member
variable.
*****
sFullCommand += " > \"";
sFullCommand += lpszDesktopPath;
sFullCommand += "chkdsk result ";
sFullCommand += sTimeForLogFile + ".txt";
sFullCommand += "\"";
****
I think I see quoting errors here. However, lacking your specification
of
what you are
trying to accomplish, I can't be sure. It looks like you are creating a
command string
that should read
cmd /c "chkdsk > ""desktoppath.chkdsk result.txt"""
but that is not the syntax I am seeing here. So given you are creating
a
command that is
erroneous and it sounds like as a consequence you are being told your
command line is
erroneous. So why are you surprised? It is also clear you never tested
the command you
are trying to issue. So you are constructing an untested, erroneous
command (note that I
have to guess that sCMD is "cmd /c" since you didn't give this critical
information), and
are confused when CreateProcess tells you it is erroneous? Do I have
this
right?
****
}
//return;
_tcscpy(lpszCommand,sFullCommand);
****
Why do you use strcat and _tcscpy? This odd blend of non-Unicode and
Unicode constructs
is very weird. Also, don't use _tcscpy, it is obsolete and dangerous.
Use _tcscpy_s or
StringCchCopy
*****
si.lpTitle = lpszCommand;
this->m_CheckedDrivesList.InsertString(-1,"Drive: " + sCommandLine + ",
"
+
sCurrentTime);
****
You don't need to keep repeating this->; it is redundant and conveys
little useful
information. If you are going to write code that is Unicode-aware (the
_tcscpy, bad
choice as indicated above) then you have to use Unicode-aware constants,
so each string
should have _T() around it.
****
this->m_ClearListButton.EnableWindow(TRUE);
this->m_SaveToFile.EnableWindow(TRUE);
*****
See my essay on control management. Once you start scattering
EnableWindow calls around
in a dialog-based app, you are heading down a path of maintenance
nightmare.
****
CreateProcess(NULL,
lpszCommand,
NULL,
NULL,
FALSE,
CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&si,
&pi);
****
And why aren't you testing the result to see if the process was actually
created?
****
Sleep(1000);
****
This program is incorrect. You can be reasonably certain that any
program
that throws a
gratuitous "Sleep" in the hopes that the program will work right is
fundamentally wrong.
It might give the illusion of working, but it is wrong. There will come
a
time when it
won't work, due to timing considerations.
*****
if(this->m_StartConsolesAsTopmostWindows == TRUE){
*****
See the previous warning
You should test this variable by writing
if(m_StartConsoleAsTopmostWindows)
you don't need this-> and the inclusion of == TRUE is erroneous.
*****
this->SetThreadWindowToTopmost(pi.dwProcessId);
*****
You don't need this->
****
}
****
You did a 'new'. Where is the corresponding 'delete'?
****
}
Thanks in advance,...
Best regards
Kerem G?mr?kc?
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
i solved the Problem. It was a piece of memory that
of a function i used. I found this out with Debugging
Disassembler. Everything is just fine inside the
application and it works well, just as expected. Every
single function call has its reasonable purpose. There
as possible, using delete, closing handles, etc,...
but it does not any longer. The Application will be
for some "good" reasons i cant use the Express Editions.
you are a really good Programmer and very helpful.
This is really rare! Thanks...