Program doesn't run - it opens and closes - c++

I have a problem with my main program to which after all the calls I make after running the program it just opens then closes. It doesn't find any error in my code or anything, so I tried creating a new project and it does the same thing with no error.
I even tried example code:
int APIENTRY WinMain (HINSTANCE ...)
ShellExecute(NULL, (LPCWSTR)"open", (LPCWSTR)"cmd.exe", NULL, NULL, SW_SHOW);
and it still just opens and closes. What is the issue here? I can provide the output log if necessary but I have no idea.

I'm not sure I understand what you mean about opening and closing. But this code is very wrong:
ShellExecute(NULL, (LPCWSTR)"open", (LPCWSTR)"cmd.exe",
NULL, NULL, SW_SHOW);
The casts are no good. The two string literals are pointers to arrays of char casting them to const wchar_t* doesn't change what they are. It just asks the compiler to trust that you know better than it does. You don't. They are really not const wchar_t*. All your cast achieves is to allow you to break type safety and convert an informative compile time error into a cryptic run time failure. Until you have a deep understanding of the language you should refrain from casting.
You need to use wide literals:
ShellExecute(NULL, L"open", L"cmd.exe", NULL, NULL, SW_SHOW);
You also appear to be doing no error checking. That's quite hard with ShellExecute. Try ShellExecuteEx instead and take heed of the value it returns.

Related

ShellExecuteW not working well on Windows 8.1?

I call standard ShellExecuteW call on Windows8.1 to open PPS (powerpoint slide) file.
This works just fine on Windows 7. On Windows 8.1. it reports "There is no program associated to open the file". Of course, the file association is set and if file is saved and run from Explorer (double clicked) it opens just fine. I also tried to change association and to associate another program and then associate back to PPS viewer, no improvement. It just doesn't work for W8.1 but the same call works on earlier Windows.
Can anyone give me a clue what might be wrong here?
The code used to open file is very simple and I see no errors with it:
HINSTANCE hinst = ShellExecuteW(NULL, L"open", L"C:\\path\\to\\file.pps", NULL, NULL, SW_SHOWNORMAL);
// Check if result is error
if ((int)hinst <= 32)
{
wchar_t buf[512] = { 0 };
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 512, NULL);
MSGBOX(buf);
}
I use free PPS viewer as found here:
http://www.microsoft.com/en-us/download/details.aspx?id=13
I found something similar which points to that this could be a bug in Win8.1. Can anyone confirm this? Or reveal a workaround?
I found the solution myself.
The problem on W8.1 was that the verb open was not registered to the application so it used different default verb. So if the ShellExecute call is replaced with:
HINSTANCE hinst = ShellExecuteW(NULL, NULL, L"C:\\path\\to\\file.pps", NULL, NULL, SW_SHOWNORMAL);
Then the system looks for a default verb which may or may not be open (usually is), so by not using this verb explicitly it leaves this decision to the system.

show variant type value in MessageBox

huh i got a small prob in fact i want to be able to see list of my plugged devices
i want to see them at the first place in MessageBox()
but this variant irks me (^_^) i have tried many ways but without result
IMoniker *tmpMonk=NULL;
ULONG done;
VARIANT varName;
while(this->deviceClassEnum->Next(1,&tmpMonk,&done)==S_OK)
{
IPropertyBag *tmpBag=NULL;
tmpMonk->BindToStorage(0,0,IID_IPropertyBag,(void **)&tmpBag);
VariantInit(&varName);
checkIt(tmpBag->Read(L"FriendlyName",&varName,0));
// this i wana see what is inside but huuuuuuuuuuuuuh
MessageBox(this->app,TEXT((LPCSTR)varName.bstrVal),"",NULL);
VariantClear(&varName);
tmpBag->Release();
}
secondly how to be able to switch from device to another . from
whatever menu or list
You need to call MessageBoxW instead of MessageBox. And remove the casts. So it will look like:
MessageBoxW(this->app, varName.bstrVal , L"", NULL);
This is a problem in character encoding; strings used in COM are of type BSTR, which can be used the same as PWSTR / PCWSTR types. This is incompatible with PCSTR.
Remember that casts simply tell the compiler "hey I know what I'm doing, shut up". Except the compiler's messages were actually trying to help you, you told them to go away. Next time listen to them.

Windows API - Beginner help

I try to create a very simple app using windows API.
I've done some small apps in console. This is the first time I do with Win32 apps.
I've searched and found a document from forgers which is recommended in this site. But I try to write very first line:
#include <stdafx.h>
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBoxW(NULL, "Good bye Cruel World", "Note", MB_OK);
return 0;
}
But it doesn't work (erased lines from default project created by VS 2008 and write these lines).
There are two versions of most windows API calls, one which takes single byte string and one which takes 2 byte unicode strings. The single byte one has an A on the end of the name and the 2 byte one has a W. There are macros defined in windows.h so that if you leave the letter out it picks one or the other depending on compiler macros.
In your code you write -
MessageBoxW (NULL, "Good bye Cruel World", "Note", MB_OK );
You are calling the wide character version of the API with single byte strings which won't work. Either change to MessageBoxA or change your strings to wide strings -
MessageBoxW (NULL, L"Good bye Cruel World", L"Note", MB_OK );
Remove the first line. What remains is a valid Windows program, which should compile under any IDE. Your problem is the stdafx.h header which is an artefact of VS, and you may have other problems if you try to "reuse" an existing VS project. If you want to nkow how compilation really works, it's a good idea to build some simple apps not using an IDE, but a command line compiler like MinGW.
And in future, post what error messages you are getting using copy and paste.
You need at least a message loop to run, in order for the application to process messages:
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
There are many tutorials on the message loop on the web, such as here:
http://www.winprog.org/tutorial/message_loop.html
If you're just starting GUI programming, you're best off reading a book, and working through the examples. Petzold is a classic. Learning programming by collecting snippets of partially working code cribbed from random web pages is going to be time-consuming, difficult and patchy. A well-written book will lead you through the fundamentals and explain things in stages. Have fun!

Launch IE from a C++ program

I have a program written in C++ which does some computer diagnostics. Before the program exits, I need it to launch Internet Explorer and navigate to a specific URL. How do I do that from C++?
Thanks.
Here you are... I am assuming that you're talking MSVC++ here...
// I do not recommend this... but will work for you
system("\"%ProgramFiles%\\Internet Explorer\\iexplore.exe\"");
// I would use this instead... give users what they want
#include <windows.h>
void main()
{
ShellExecute(NULL, "open", "http://stackoverflow.com/questions/982266/launch-ie-from-a-c-program", NULL, NULL, SW_SHOWNORMAL);
}
if you really need to launch internet explorer you should also look into using CoCreateInstance(CLSID_InternetExplorer, ...) and then navigating. depending on what else you want to do it might be a better option.
include <windows.h>
int main()
{
ShellExecute(0, "open",
"C:\\progra~1\\intern~1\\iexplore.exe",
"http://www.foo.com",
"",
SW_MAXIMIZE);
return 0;
}
Do you really need to launch IE or just some content in a browser? The ShellExecute function will launch whatever browser is configured to be the default. Call it like this:
ShellExecute(NULL, "open", szURL, NULL, NULL, SW_SHOW);
Using just standard C++, if iexplore is on the path then
#include <stdlib.h>
...
string foo ("iexplore.exe http://example.com");
system(foo.c_str());
If it's not on the path then you need to work out the path somehow and pass the whole thing to the system call.
string foo ("path\\to\\iexplore.exe http://example.com");
system(foo.c_str());
I'm with Glen and John, except I'd prefer to use CreateProcess instead. That way you have a process handle you can do something with. Examples might be Kill IE when you are done with it, or have a thread watching for IE to terminate (WaitForSingleObject with the process handle) so it could do something like restart it, or shut down your program too.
Try this
system("\"C:\Program Files\Internet Explorer\iexplore\" http://www.shail.com");
Works perfectly..

Why is this code losing handles on Windows 7 Beta?

I'm looking for some random crashes in an old c++ application. Using sysinternals process explorer, I noticed the app losing handles, and extracted the exact situation, where the program is losing handles to a very short piece of code.
DWORD WINAPI MyTestThread( void* PThread)
{
_endthreadex(0);
return 0;
}
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR PParameter, int)
{
for (int i=0;i<10000;i++)
{
unsigned int threadID;
HANDLE hThread= (HANDLE)_beginthreadex( (void*)NULL, (unsigned int)32768, (unsigned int (__stdcall *)(void *))MyTestThread, (void*)NULL, (unsigned int)0, &threadID);
WaitForSingleObject((HANDLE)hThread, 1000);
CloseHandle((HANDLE)hThread);
}
return 0;
}
My problem: I can't figure out what's wrong with this code. It loses exactly 5 handles on every iteration, but it looks OK to me.
Funny thing: it seems not to lose handles on windows vista, but I'd be very surprised if this should be a bug in windows 7.
[Update] I tried using _beginthread/_endthread and CreateThread/ExitThread instead, those two are losing 5 handles, too, just like _beginthreadex.
[2nd Update] the code does run as expected. All return values are good. It is 'just' losing handles like there is no tomorrow.
[3rd Update] Big new Info The code only loses handles, if compiled with /clr! And more, if I call GC::Collect() on each iteration the handles will be reclaimed!
So, how do I find what clr-objects are being collected there?
Check whether some DLL which is linked to your exe is doing something strange in its DLLMain in response to DLL_THREAD_ATTACH notifications.
Have you checked if the functions succeed? The return values and GetLastError() could give some hints what's going wrong.
From http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx
"If successful, each of these functions returns a handle to the newly created thread; however, if the newly created thread exits too quickly, _beginthread might not return a valid handle (see the discussion in the Remarks section). _beginthread returns -1L on an error, in which case errno is set to EAGAIN if there are too many threads, to EINVAL if the argument is invalid or the stack size is incorrect, or to EACCES in the case of insufficient resources (such as memory). _beginthreadex returns 0 on an error, in which case errno and _doserrno are set. "
Your thread does exit kind of quickly doesn't it.
Have you tried testing this with Win32's CreateThread? That could possibly narrow down the problem to the CRT.