msgwaitformultipleobjects

J

Jimmy

Hey

Trying to make a program that downloads a file from the Internet and
afterwards installs this file. The file that is downloadet is a cab file,
and i use shellexecuteex to simulate a click on the file, so that i can get
it installed. The problem is that i have to use some win32api calls, and i
cannot get it to work properly. When i start the installation through
shellexecuteex the program just continues and then closes, but i want it to
wait for the installation to be complete.

Ok, so i tried to use MsgWaitForsingleObject, but read about it that if the
executing program generates windows, this was not a good idea. Instead i
should use msgwaitformultipleobjects. Whenever i try to do this i get a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED TO DO THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 
P

Paul G. Tobey [eMVP]

I'm unclear on what it is that you are doing there. Remember that
MsgWaitForXXXObject() will return when the application receives user input
messages. If you know that and are expecting any user input to your
application to indicate that the install is done, your code makes sense.
Otherwise, you should probably rethink it.

If you read the help for MsgWaitForMultipleObjects, you'll see that it is
implemented as a macro which calls MsgWaitForMultipleObjectsEx, so *that* is
what you have to P/Invoke to.

Paul T.

Jimmy said:
Hey

Trying to make a program that downloads a file from the Internet and
afterwards installs this file. The file that is downloadet is a cab file,
and i use shellexecuteex to simulate a click on the file, so that i can get
it installed. The problem is that i have to use some win32api calls, and i
cannot get it to work properly. When i start the installation through
shellexecuteex the program just continues and then closes, but i want it to
wait for the installation to be complete.

Ok, so i tried to use MsgWaitForsingleObject, but read about it that if the
executing program generates windows, this was not a good idea. Instead i
should use msgwaitformultipleobjects. Whenever i try to do this i get a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED TO DO THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 
J

Jimmy

Ok... I think i might have misunderstood it then!?!?

What i want is : When i call the shellexecutex function to start my cab file
installation. I dont want my program to continue before the installation is
complete.

No user input is given to indicate this. No wonder i was a bit confused,
hehe...

What should i look for, to do what i want?

Thanks for your help so far :)


Jimmy

--


Jimmy

Paul G. Tobey said:
I'm unclear on what it is that you are doing there. Remember that
MsgWaitForXXXObject() will return when the application receives user input
messages. If you know that and are expecting any user input to your
application to indicate that the install is done, your code makes sense.
Otherwise, you should probably rethink it.

If you read the help for MsgWaitForMultipleObjects, you'll see that it is
implemented as a macro which calls MsgWaitForMultipleObjectsEx, so *that* is
what you have to P/Invoke to.

Paul T.

Jimmy said:
Hey

Trying to make a program that downloads a file from the Internet and
afterwards installs this file. The file that is downloadet is a cab file,
and i use shellexecuteex to simulate a click on the file, so that i can get
it installed. The problem is that i have to use some win32api calls, and i
cannot get it to work properly. When i start the installation through
shellexecuteex the program just continues and then closes, but i want it to
wait for the installation to be complete.

Ok, so i tried to use MsgWaitForsingleObject, but read about it that if the
executing program generates windows, this was not a good idea. Instead i
should use msgwaitformultipleobjects. Whenever i try to do this i get a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED TO DO THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 
P

Paul G. Tobey [eMVP]

WaitForSingleObject() will wait until the application you launched has
exited or the time-out period has expired. That's what I'd use. However,
you need to make sure that your user interface is still responsive, in case
the user, brings your application to the front while the other app is still
running, so I'd be inclined to do the Wait in another thread, or set a flag
and periodically check the handle, disabling the UI it is 'set'.

Paul T.

Jimmy said:
Ok... I think i might have misunderstood it then!?!?

What i want is : When i call the shellexecutex function to start my cab file
installation. I dont want my program to continue before the installation is
complete.

No user input is given to indicate this. No wonder i was a bit confused,
hehe...

What should i look for, to do what i want?

Thanks for your help so far :)


Jimmy

--


Jimmy

Paul G. Tobey said:
I'm unclear on what it is that you are doing there. Remember that
MsgWaitForXXXObject() will return when the application receives user input
messages. If you know that and are expecting any user input to your
application to indicate that the install is done, your code makes sense.
Otherwise, you should probably rethink it.

If you read the help for MsgWaitForMultipleObjects, you'll see that it is
implemented as a macro which calls MsgWaitForMultipleObjectsEx, so
*that*
is
what you have to P/Invoke to.

Paul T.

can
get
and
i
cannot get it to work properly. When i start the installation through
shellexecuteex the program just continues and then closes, but i want
it
to
wait for the installation to be complete.

Ok, so i tried to use MsgWaitForsingleObject, but read about it that
if
the
executing program generates windows, this was not a good idea. Instead i
should use msgwaitformultipleobjects. Whenever i try to do this i get a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED TO DO THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 
J

Jimmy

Hey

So ill try to stick with WaitForSingleObject().
One thing i dont understand though, is that when i run ShellExecuteEx(see)
the WaitForSingleObject() gets the program to wait. Heres what happens.

1. My cab file installation starts.
2. It says that the file is allready installed. I just press ok, to have my
program installed anyway
3. It tries to write data to "Remove programs"

At 3 my program hangs.

Whats really confusing me is, that its like i can activate my program (the
program thats currently waiting). But i cant do anything with it. Its like
that program is locked. And that actually makes sense since it should wait
for the install to complete. But if thats the case, why does the install
freeze???
Its like its just doing the install from within my own program instead of
starting a new program that will do the install. If thats the case i can
understand why my program freezes, but i cant understand why this is the
case. Is it the ShellExecuteEx(see) that i dont understand?

Does my explanation make any sense?

Really hope that you will answer me back at this one.

Meanwhile ill try to see if i can get it to work with some thread things,
even though im not sure what ill have to do...?!?!?

Untill now: Thanks for your help :)


--


Jimmy

Paul G. Tobey said:
WaitForSingleObject() will wait until the application you launched has
exited or the time-out period has expired. That's what I'd use. However,
you need to make sure that your user interface is still responsive, in case
the user, brings your application to the front while the other app is still
running, so I'd be inclined to do the Wait in another thread, or set a flag
and periodically check the handle, disabling the UI it is 'set'.

Paul T.

Jimmy said:
Ok... I think i might have misunderstood it then!?!?

What i want is : When i call the shellexecutex function to start my cab file
installation. I dont want my program to continue before the installation is
complete.

No user input is given to indicate this. No wonder i was a bit confused,
hehe...

What should i look for, to do what i want?

Thanks for your help so far :)


Jimmy

--


Jimmy

*that* and
want
Instead
get
a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED TO DO
THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 
P

Paul G. Tobey [eMVP]

It probably freezes the install because it's waiting for some message to
arrive before it does anything and the other program is still processing
whatever message was sent on activation (since the UI thread is stuck in
WaitForSingleObject), so the installer never gets the message it was waiting
for. That's why you don't want to lock the UI thread...

Paul T.

Jimmy said:
Hey

So ill try to stick with WaitForSingleObject().
One thing i dont understand though, is that when i run ShellExecuteEx(see)
the WaitForSingleObject() gets the program to wait. Heres what happens.

1. My cab file installation starts.
2. It says that the file is allready installed. I just press ok, to have my
program installed anyway
3. It tries to write data to "Remove programs"

At 3 my program hangs.

Whats really confusing me is, that its like i can activate my program (the
program thats currently waiting). But i cant do anything with it. Its like
that program is locked. And that actually makes sense since it should wait
for the install to complete. But if thats the case, why does the install
freeze???
Its like its just doing the install from within my own program instead of
starting a new program that will do the install. If thats the case i can
understand why my program freezes, but i cant understand why this is the
case. Is it the ShellExecuteEx(see) that i dont understand?

Does my explanation make any sense?

Really hope that you will answer me back at this one.

Meanwhile ill try to see if i can get it to work with some thread things,
even though im not sure what ill have to do...?!?!?

Untill now: Thanks for your help :)


--


Jimmy

Paul G. Tobey said:
WaitForSingleObject() will wait until the application you launched has
exited or the time-out period has expired. That's what I'd use. However,
you need to make sure that your user interface is still responsive, in case
the user, brings your application to the front while the other app is still
running, so I'd be inclined to do the Wait in another thread, or set a flag
and periodically check the handle, disabling the UI it is 'set'.

Paul T.

Jimmy said:
Ok... I think i might have misunderstood it then!?!?

What i want is : When i call the shellexecutex function to start my
cab
file
installation. I dont want my program to continue before the
installation
is
complete.

No user input is given to indicate this. No wonder i was a bit confused,
hehe...

What should i look for, to do what i want?

Thanks for your help so far :)


Jimmy

--


Jimmy

"Paul G. Tobey [eMVP]" <ptobey no spam AT no instrument no spam DOT com>
skrev i en meddelelse I'm unclear on what it is that you are doing there. Remember that
MsgWaitForXXXObject() will return when the application receives user input
messages. If you know that and are expecting any user input to your
application to indicate that the install is done, your code makes sense.
Otherwise, you should probably rethink it.

If you read the help for MsgWaitForMultipleObjects, you'll see that
it
is
implemented as a macro which calls MsgWaitForMultipleObjectsEx, so *that*
is
what you have to P/Invoke to.

Paul T.

Hey

Trying to make a program that downloads a file from the Internet and
afterwards installs this file. The file that is downloadet is a cab
file,
and i use shellexecuteex to simulate a click on the file, so that
i
can
get
it installed. The problem is that i have to use some win32api
calls,
and
i
cannot get it to work properly. When i start the installation through
shellexecuteex the program just continues and then closes, but i
want
it
to
wait for the installation to be complete.

Ok, so i tried to use MsgWaitForsingleObject, but read about it
that
if
the
executing program generates windows, this was not a good idea.
Instead
i
should use msgwaitformultipleobjects. Whenever i try to do this i
get
a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData,
nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED TO DO
THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 
J

Jimmy

Ok, the following changes did the trick:

The code from the first post has changed a bit:

ShellExecuteEx(see);
waitFlag = false; //THIS VARIABLE IS STATIC
Thread waitThread = new Thread(new ThreadStart(waitT));
waitThread.Start();
while (waitFlag == false)
{
Thread.Sleep(100);
Application.DoEvents(); //THIS ACTUALLY DID THE TRICK. WITHOUT THIS LINE
IT WOULD WAIT FOREVER
}

static void waitT()
{
WaitForSingleObject(see.hProcess,INFINITE); //MADE see AND INFINITE
static SO I COULD ACCESS THEM FROM WITHIN MY THREAD
waitFlag = true;
}

So this is what i did. Thanks to you my application is now working.

Once again, thanks for your help :)


--


Jimmy


Paul G. Tobey said:
It probably freezes the install because it's waiting for some message to
arrive before it does anything and the other program is still processing
whatever message was sent on activation (since the UI thread is stuck in
WaitForSingleObject), so the installer never gets the message it was waiting
for. That's why you don't want to lock the UI thread...

Paul T.

Jimmy said:
Hey

So ill try to stick with WaitForSingleObject().
One thing i dont understand though, is that when i run ShellExecuteEx(see)
the WaitForSingleObject() gets the program to wait. Heres what happens.

1. My cab file installation starts.
2. It says that the file is allready installed. I just press ok, to have my
program installed anyway
3. It tries to write data to "Remove programs"

At 3 my program hangs.

Whats really confusing me is, that its like i can activate my program (the
program thats currently waiting). But i cant do anything with it. Its like
that program is locked. And that actually makes sense since it should wait
for the install to complete. But if thats the case, why does the install
freeze???
Its like its just doing the install from within my own program instead of
starting a new program that will do the install. If thats the case i can
understand why my program freezes, but i cant understand why this is the
case. Is it the ShellExecuteEx(see) that i dont understand?

Does my explanation make any sense?

Really hope that you will answer me back at this one.

Meanwhile ill try to see if i can get it to work with some thread things,
even though im not sure what ill have to do...?!?!?

Untill now: Thanks for your help :)


--


Jimmy

Paul G. Tobey said:
WaitForSingleObject() will wait until the application you launched has
exited or the time-out period has expired. That's what I'd use. However,
you need to make sure that your user interface is still responsive, in case
the user, brings your application to the front while the other app is still
running, so I'd be inclined to do the Wait in another thread, or set a flag
and periodically check the handle, disabling the UI it is 'set'.

Paul T.

Ok... I think i might have misunderstood it then!?!?

What i want is : When i call the shellexecutex function to start my cab
file
installation. I dont want my program to continue before the installation
is
complete.

No user input is given to indicate this. No wonder i was a bit confused,
hehe...

What should i look for, to do what i want?

Thanks for your help so far :)


Jimmy

--


Jimmy

"Paul G. Tobey [eMVP]" <ptobey no spam AT no instrument no spam DOT com>
skrev i en meddelelse I'm unclear on what it is that you are doing there. Remember that
MsgWaitForXXXObject() will return when the application receives user
input
messages. If you know that and are expecting any user input to your
application to indicate that the install is done, your code makes sense.
Otherwise, you should probably rethink it.

If you read the help for MsgWaitForMultipleObjects, you'll see
that
that
i
can
get
it installed. The problem is that i have to use some win32api calls,
and
i
cannot get it to work properly. When i start the installation through
shellexecuteex the program just continues and then closes, but i want
it
to
wait for the installation to be complete.

Ok, so i tried to use MsgWaitForsingleObject, but read about it that
if
the
executing program generates windows, this was not a good idea. Instead
i
should use msgwaitformultipleobjects. Whenever i try to do this
i
get
a
system.nullreferenceexception and the calling function throws a
missingmethodexception. Please can anyone help me getting this to
work?

PLEASE

Ive made comments in the following code:

private bool Install_Filer()
{
bool ret;
lab_status.Text = "Installing " + tempsti;
Application.DoEvents();
try
{
Int32 INFINITE;
unchecked {INFINITE = (int)0xFFFFFFFF;}
Int32 retcode;
unchecked {retcode = 746;}
string docname = tempsti;
int nSize = docname.Length * 2 + 2;
IntPtr pData = LocalAlloc(0x40, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData,
nSize -
2);
SHELLEXECUTEEX see = new SHELLEXECUTEEX();
see.cbSize = 60;
see.dwHotKey = 0;
see.fMask = 0x00000040;
see.hIcon = IntPtr.Zero;
see.hInstApp = IntPtr.Zero;
see.hProcess = IntPtr.Zero;
see.lpClass = IntPtr.Zero;
see.lpDirectory = IntPtr.Zero;
see.lpIDList = IntPtr.Zero;
see.lpParameters = IntPtr.Zero;
see.lpVerb = IntPtr.Zero;
see.nShow = 0;
see.lpFile = pData;
ShellExecuteEx(see);
//THE FOLLOWING THREE LINES SHOULD DO THE TRICK
IntPtr[] pHandles = new IntPtr[1];
pHandles[0] = see.hProcess;
MsgWaitForMultipleObjects(1, pHandles, false, (uint)INFINITE,
0x007F); //THIS IS WHERE I GET MY NULLREFERENCEEXCEPTION AND THE
CALLING
FUNCTION GIVES ME A MISSINGMETHODEXCEPTION
//WaitForSingleObject(see.hProcess,INFINITE); //I TRIED
TO
DO
THIS,
BUT THIS MAKES IT ALL HANG, JUST WAITING FOREVER.
LocalFree(pData); //IM ACTUALLY NOT SURE WHAT THIS IS
ret = true;
}
catch (Exception testfejl)
{
MessageBox.Show(testfejl.ToString());
MessageBox.Show("Error installing " + tempsti);
ret = false;
}
return ret;
}


#region
class SHELLEXECUTEEX
{
public UInt32 cbSize;
public UInt32 fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpFile;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public IntPtr hInstApp;
// Optional members
public IntPtr lpIDList;
public IntPtr lpClass;
public IntPtr hkeyClass;
public UInt32 dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}

[DllImport("coredll")]
extern static int ShellExecuteEx( SHELLEXECUTEEX ex );

[DllImport("coredll")]
extern static IntPtr LocalAlloc( int flags, int size );

[DllImport("coredll")]
extern static void LocalFree( IntPtr ptr );

[DllImport("CoreDll.dll")]
private extern static
Int32 WaitForSingleObject( IntPtr Handle,
Int32 Wait);

[DllImport("Mscorlib.dll")]
private extern static
UInt32 MsgWaitForMultipleObjects(
UInt32 nCount, // number of handles in array
IntPtr[] pHandles, // object-handle array
bool bWaitAll, // wait option
UInt32 dwMilliseconds, // time-out interval
UInt32 dwWakeMask); // input-event type

#endregion
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top