Link Checker With ShellExecute? - c++

I've been tasked with going through a database and checking all of the links, on a weekly schedule. I normally work in PHP, but doing this in PHP would be very slow (it actually would timeout the page after about 100 URLs), so I decided to make a quick C++ app.
Admitidly, I haven't used C++ since college, so I'm a bit rusty.
I found the ShellExecute function, and that it would open the page no problem. Here is what I have so far:
#include <shlobj.h>
#include <iostream>
using namespace std;
int main()
{
if( ShellExecute(NULL,"find","http://example.com/fdafdafda.php",NULL,NULL,SW_SHOWDEFAULT) )
{
cout << "Yes";
} else {
cout << "No";
}
cout << endl;
system("PAUSE");
return 0;
}
The problem is that it always returns true, whether it is opening a valid page or not. It appears to be checking if the associated app (a browser in this case) is able to open the document with no problems, then returns true. It isn't looking to see if the browser is getting a 404 or not, it simply sees it open and run and is fine.
Is there a better way to do this? Am I missing a step?
As an aside, I have attempted to use the cURLcpp stuff, but can't seem to figure it out. All of the examples point to header files that don't exist in the download. I have a feeling cURLcpp is the better way to do this.
Thanks for any help.

I think you answered your own question. ShellExecute is really not appropriate for this task, and something like CURL would be better.

or if you don't want to use an external library you can check directly with InternetOpen, InternetOpenURL etc.

Documentation on the return value of ShellExecute :
If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. It can be cast only to an int and compared to either 32 or the following error codes below.
See ShellExecute documentation.
And yes, CURL would be better.

Related

fstream fails to open file

I have a very weird problem. The setup is the following:
Library A uses Library B
Both libraries are installed as shared library independently and A links to B using CMake packages.
When I create an executable that directly links to B, everything works fine.
When I create an executable that links to A however, which is using B, then for some reason my fstream in B fails to open a specific file. I am 100% certain the file exists, is not requiring authorization and is not currently used. The error thrown by strerror(errno) is "No such file or directory".
I really have no clue what might go wrong. This is the code snippet I use for opening:
ifstream f;
f.open(filename.c_str(), ios_base::in|ios::binary);
if (f.fail()) {
std::cout << "Opening Vocabulary failed: " << std::strerror(errno) << std::endl;
return false;
}
I triple checked the path in filename is correct. These are the last resorts I can think of:
Maybe Library A uses another C++ Standard as B, which is why the call to fstream fails?
Maybe filename string is somehow corrupted, even though the path seems to be correct?
Maybe some memory leak corrupts my c_str() command?
Is there anything else that I could check?
Edit: Ah, one thing I forgot: The fstream command is in a templated function in a header file. Maybe this has something to do with it?
Edit2: Here is the stack trace. "ORBVoc.bin" is the file I wanted to open. The only information I get out of this is, it does not exist...though it does exist.
https://www.file-upload.net/download-14359408/strace.log.html
Okay, apparently a reboot was all it takes. Today everything works flawlessly. No permissions, file or line of code was changed. I assume either something went terribly wrong, when my Laptop came back from hibernation. Or it was some pending ubuntu update? I really have no idea. I could swear it was shutdown at least once the past 2-3 days. But jeah, I have no other explanation. Maybe someone smarter can answer this with his glass ball...
Anyway, thanks for the answers, appreciate it! At least I learned about strace $:^)

Fastest way to make console output "verbose" or not

I am making a small system and I want to be able to toggle "verbose" text output in the whole system.
I have made a file called globals.h:
namespace REBr{
extern bool console_verbose = false;
}
If this is true I want all my classes to print a message to the console when they are constructing, destructing, copying or doing pretty much anything.
For example:
window(string title="",int width=1280,int height=720):
Width(width),Height(height),title(title)
{
if(console_verbose){
std::cout<<"Generating window #"<<this->instanceCounter;
std::cout<<"-";
}
this->window=SDL_CreateWindow(title.c_str(),0,0,width,height,SDL_WINDOW_OPENGL);
if(console_verbose)
std::cout<<"-";
if(this->window)
{
this->glcontext = SDL_GL_CreateContext(window);
if(console_verbose)
std::cout<<".";
if(this->glcontext==NULL)
{
std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_OPENGLCONTEXT: "<<SDL_GetError()<<std::endl;
}
}
else std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_WINDOW: "<<SDL_GetError()<<std::endl;
if(console_verbose)
std::cout<<">done!"<<endl;
}
Now as you can see I have a lot of ifs in that constructor. And I REALLY dont want that since that will slow down my application. I need this to be as fast as possible without removing the "loading bar" (this helps me determine at which function the program stopped functioning).
What is the best/fastest way to accomplish this?
Everying in my system is under the namespace REBr
Some variants to achieve that:
Use some logger library. It is the best option as it gives you maximum flexibility and some useful experience ;) And you haven't to devise something. For example, look at Google GLOG.
Define some macro, allowing you to turn on/off all these logs by changing only the macro. But it isn't so easy to write such marco correctly.
Mark your conditional flag as constexpr. That way you may switch the flag and, depending on its value, compiler will optimise ifs in compiled program. But ifs will still be in code, so it looks kinda bulky.
Anyway, all these options require program recompilation. W/o recompilation it is impossible to achieve the maximum speed.
I often use a Logger class that supports debug levels. A call might look like:
logger->Log(debugLevel, "%s %s %d %d", timestamp, msg, value1, value2);
The Logger class supports multiple debug levels so that I can fine tune the debug output. This can be set at any time through the command line or with a debugger. The Log statement uses a variable length argument list much like printf.
Google's logging module is widely used in the industry and supports logging levels that you can set from the command line. For example (taken from their documentation)
VLOG(1) << "I'm printed when you run the program with --v=1 or higher";
VLOG(2) << "I'm printed when you run the program with --v=2 or higher";
You can find the code here https://github.com/google/glog and the documentation in the doc/ folder.

System() function, and calling internet explorer from it, DevC++

I tried making a program that'd take website info, then feed it to system() to start website. I'm aware that characters like (\, ",') don't get fed to the output directly, so I used escape sequences.
I wrote this program, but the command prompt just refuses to go past C:\ path. But if I copy paste the command displayed by my program, internet explorer gets launched. But the case isn't so for my program. Can anybody tell me where is the error?
Here is my code:
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
cout<<"Please enter the website you wish to visit: ";
string website,web;
cin>>web;
web= " " + web;
website = "\"%ProgramFiles%\\Internet Explorer\\iexplore\""+web;
cout<<"\n"<<website<<endl<<endl<<endl;
system(website.c_str());
return 0;
}
You are using an environment variable, %ProgramFiles%, in your system command-line; these are specific to the MS-DOS prompt environment, and generally not available in system implementations.
I suggest replacing that with the full path, such as \"C:\Program Files\Internet Explorer\iexplore\", and see if that works.
If that works, then your implementation doesn't implicitly replace environment variables the way a full Command Prompt does, so you will need to query the environment variable separately and construct the path before you run system. See getenv for one possible way (I'm not sure what mingw32 supports, so you may have other options as well).
If that doesn't remedy the problem, I suggest checking if you can launch something simpler, like notepad.exe, to verify that there is nothing interfering with launching an application in general, such as your environment path or permissions.
Pass it in double double quotes:
website = "\"\"%ProgramFiles%\\Internet Explorer\\iexplore\"\""+web;
The system("something") call actually runs the command interpreter cmd in a way similar (but probably not identical) to cmd /c something. This has implications when there are spaces in the command name, see e.g this. I cannot tell exactly why single double quotes work when there's no environment variable involved, and do not work otherwise, but the fact is, double double quotes do work.
If you want to launch the user's preferred browser, consider calling
system("start http://" + websitename);
instead.
Get that environment variable value first.
#include <iostream>
#include <ShlObj.h>
int main() {
char pathToPf[MAX_PATH];
if (S_OK == SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, pathToPf))
std::cout << pathToPf << std::endl;
return 0;
}
See SHGetFolderPath documentation...
Note that I was lazy and using the ASCII version of this function. Use it without the A postfix and deal with the conversation ;)

C++ output screen disappears

Why does my C++ output screen disappear immediately? I'm a beginner in cpp. Can anyone help me to find the problem please?
You should either launch your application inside of a terminal, or add a line of code that waits for the input in order for the window to not close. E.g. add in the end of the function main a line:
std::cin.get();
And also add at beginning of the file the include that holds that function.
#include <iostream>
This is hard to answer since there can be many things that can cause your output box to close immediately. First try having a cout statement and then a cin statement. Something like:
cout<<"Hello"<<endl;
cin>>input>>endl;
Also make sure to have the necessary include statement at the top and whatever you want to return at the bottom.
#include<iostream>
return 0;
As you have said that you are beginner in C++, you should keep in mind ,three major things while coding in C++. You've mentioned that your screen disappears , then following things you should try.
1). in C++ conventionally main returns value of type int.And the format of your program should be like...
int main()
{
-------
//body of your program
-------
return 0;
}
If the function returns 0, that means it ran successfully.
2). You have to inlcude #include<iostream> on the top of your program.
3).check whether the IDE you are using is compatibale to your operating system or not.
Hope this will help you.

Boomerang decompiler fails

I need to decompile a windows program which the source code was lost for a long time.
I am using boomerang in Windows 7 for this. However, it looks broken, gives this message and quits:
Could not open dynamic loader library Win32BinaryFile.dll (error #998)
Googling about it gives no useful results. Looking in the boomerang source code, it is apparently coming from this:
00137 hModule = LoadLibraryA(libName.c_str());
00138 if(hModule == NULL) {
00139 int err = GetLastError();
00140 fprintf( stderr, "Could not open dynamic loader library %s (error #%d)\n", libName.c_str(), err);
00141 fclose(f);
00142 return NULL;
00143 }
I.e. LoadLibraryA is failing with the status 998.
What could I do to fix that?
Edit, four hours later:
The program that I want to decompile is a work that me and a friend implemented in 2005. The source just gone in the mean time without we seeing that. Now, in 2013, when we searched it, nothing was found. In retrospect, it was probably lost in 2008 or in 2010, two occasions where my computer hardware crashed and I needed to get a new computer (and lost a lot of data with that). We had several backups scattered in several places, but after an exhaustive search, I found nothing.
I know that since boomerang is open source, I could just get its source code and hack it around. However, that sort of task is not what I originally intended to do, since the focus is just to decompile my program and I guess that I am missing something simple, since it can't load the DLL while it is clearly there.
I don't need the exact code back, just a sketch of what were the exact details of the algorithm that were implemented. Having that, I can rewrite the rest again.