views:

1904

answers:

3

I've tried shellexecute, I've tried createprocess, I can't seem to get this to do anything.

Running the command line manually (at the actual command prompt in a console window) works, but nothing I've tried so far will run it from within a c++ builder app.

Obviously (filename) is just a place holder. It would be given a valid file name, such as

explorer /n, /select,c:\123.doc

+2  A: 

Are you using escaped backslashes in your filename? For example:;

"c:\123.doc"

should be:

"c:\\123.doc"

Edit:

  execlp("explorer", "/n, /select,c:\\foo.txt", 0)

works for me.

To avoid replacing the the current process, use spawnlp instead

anon
The filename string is handled by built in file handling components so it is automatically implemented with double backslashes. but neither types work. I tried both.
MrVimes
Another thought - isn't it supposed to be a directory name, not a file name?
anon
Oops, no strike that
anon
Your edit (execlp) worked for me. Had to include the process header but that's not a problem. Thanks! I was tearing my hair out, and I nearly had createprocess working when I decided to check back here.
MrVimes
On second thoughts. execlp works except that it kills the calling process!
MrVimes
A: 

I'm sure there's someway to make CreateProcess and ShellExecute work with this, but I suspect the simplest way to do this will be good old system, e.g. system("explorer /n, /select,c:\\123.doc").

Just because it was bugging me, I went ahead and wrote a simple program that does this with CreateProcess:

 #define UNICODE
 #include <windows.h>
 #include <string>

 void SimpleWriteConsole(std::wstring msg) {
    DWORD written = 0;
    WriteConsole( GetStdHandle(STD_OUTPUT_HANDLE),
          msg.c_str(), msg.length(), &written, NULL);
 }


 int wmain(int argc, wchar_t **argv, wchar_t **envp) {
    SimpleWriteConsole(L"Opening explorer...\n");
    std::wstring commandLine = L"explorer /n, /select,";
    if( argc < 2 ) {
       SimpleWriteConsole(L"Please include a file to select.\n");
       return EXIT_FAILURE;
    }
    commandLine += argv[1];
    STARTUPINFO startupInfo;
    ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
    PROCESS_INFORMATION procInfo;

    if( ! CreateProcess(NULL, const_cast<wchar_t*>(commandLine.c_str()), 
             NULL, NULL, 0, 0, NULL, NULL, &startupInfo, &procInfo) ) {
       SimpleWriteConsole(L"Couldn't create process :(\n");
       return EXIT_FAILURE;
    }
    CloseHandle( procInfo.hThread );
    CloseHandle( procInfo.hProcess );
    SimpleWriteConsole(L"Hooray launched explorer.\n");
    return EXIT_SUCCESS;
 }

It takes the C:\abc.txt part as a parameter on the command line. There's no extra dos box, and doesn't eat your existing process (exec is supposed to do that, btw) and it doesn't use a deprecated API.

Logan Capaldo
Works, but leaves a dos box open. I'd rather not have that.
MrVimes
A: 

OK these replies have been useful but unfortunately they both have drawbacks which I would rather not have in my app...

execlp() causes the calling process to close.

system() shows a dos box which stays until I close the explorer window.

I am greatful for your your answers though.

I've got it to work with winexec. Even though winexec's help file says this - "Note This function is provided only for compatibility with 16-bit Windows. Applications should use the CreateProcess function." I can't get createprocess to work, so I'm going to stick with winexec for now...

WinExec(String("explorer /n, /select,"+ FileName).c_str(),SW_SHOWDEFAULT);

MrVimes