5

I have this tiny programm, which is intened to show windows file/folder properties dialog on the specified info.lpFile:

#include <windows.h>

main() {
   SHELLEXECUTEINFO info = {0};

   info.cbSize = sizeof(SHELLEXECUTEINFO);
   info.lpFile = "C:\\test.txt";
   info.nShow = SW_SHOW;
   info.fMask = 0x00000000;
   info.lpVerb = "properties";

   ShellExecuteEx(&info);
}

When I compile and execute it, I get the following error message:

Error message

I'm using Win7 and Mingw gcc compiler. Does anybody knows what is wrong with my code? Am I missing something?

polis
  • 795
  • 7
  • 23
  • You might try `SEE_MASK_INVOKEIDLIST` for `fMask`. – alk Nov 02 '15 at 07:39
  • I tried, but the program just hangs with this mask. – polis Nov 02 '15 at 07:41
  • Your code misses to initialise (the rest) of `info` – alk Nov 02 '15 at 07:51
  • `info.lpVerb` should be "open" or `0`, I don't think "properties" is valid. Also you should put `SHELLEXECUTEINFO info = {0};` – Barmak Shemirani Nov 02 '15 at 07:51
  • @BarmakShemirani: It is valid. See https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784%28v=vs.85%29.aspx and – alk Nov 02 '15 at 07:52
  • When `info.lpVerb` is "open" or "edit", everything works just fine, but I need windows properties dialog and the value "properties" is acceptable, according the msdn documentation. I edited my question by adding `SHELLEXECUTEINFO info = {0};` but nothing has changed in the behavior of the program. – polis Nov 02 '15 at 07:54
  • 2
    I see, add `Sleep(1000)` at the end of the code and use alk's suggestion `SEE_MASK_INVOKEIDLIST`, also you have to initialize to zero. – Barmak Shemirani Nov 02 '15 at 07:59
  • Very well, it worked! Thank you! – polis Nov 02 '15 at 08:03
  • the posted code does not cleanly compile. When declaring the main() function, there are (ignoring the optional environment parameter) just 2 valid and one optional ways to declare main(). they all have a return type of 'int' – user3629249 Nov 03 '15 at 19:54

2 Answers2

5

1st of all the code as shown does not properly initialise info.

To fix this change

  SHELLEXECUTEINFO info;

to be

  SHELLEXECUTEINFO info = {0};

2ndly use SEE_MASK_INVOKEIDLIST for SHELLEXECUTEINFO's member fMask.

For your reference: https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784%28v=vs.85%29.aspx

Please note that to see the properties window open, the invoking code must not end immediately. So add something like

  Sleep(10000);

to the end of your test code as shown.


Full code that works for me:

#include <windows.h>

int main(void) 
{
  SHELLEXECUTEINFO info = {0};

  info.cbSize = sizeof info;
  info.lpFile = L"C:\\tmp\\tmp.txt";
  info.nShow = SW_SHOW;
  info.fMask = SEE_MASK_INVOKEIDLIST;
  info.lpVerb = L"properties";

  ShellExecuteEx(&info);

  Sleep(10000);
}

Build options:

/ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Debug\SOxyzConsoleEmpty.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /TC /analyze- /errorReport:queue 

(Tested with VS2010, running Windows 7)

alk
  • 69,737
  • 10
  • 105
  • 255
  • do you mean it worked for you with this mask? For me, it hangs, and nothing else. – polis Nov 02 '15 at 08:01
  • if the user closes the opened file properties dialog, the C program still executes because of long lasting `Sleep()`. How can I terminate the execution of the C program when the properties dialog is closed? – polis Nov 07 '15 at 08:58
  • @polis Good question: An untested proposal: Pass your application's parent window's handle via `info`'s member `hwnd` and make the window identified by this handle aware the `WM_PARENTNOTIFY` message. https://msdn.microsoft.com/en-us/library/windows/desktop/hh454920%28v=vs.85%29.aspx – alk Nov 07 '15 at 09:28
  • Pass the SEE_MASK_NOASYNC (0x00000100) flag in your SHELLEXECUTEINFO to tell ShellExecuteEx that you're calling it without a message loop and not to return until it has finished. See the remarks in the SHELLEXECUTEINFO docs on MSDN at https://wmsdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx Sleep() is neither necessary nor recommended. – Rob Caplan - MSFT Nov 12 '16 at 21:52
  • @RobCaplan-MSFT: Sorry, that's not that simple. I'm calling `ShellExecuteEx` with exact same parameters as above, except I also added `CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);` and it works. If I add `info.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_NOASYNC;` it does not. In that case `ShellExecuteEx` returns immediately, as if no_async flag was not used and after a while I get a messagebox with the error `The properties for this item are not available.` I'm calling it from a GUI 64-bit application without a message loop. Opening properties for a 64-bit executable. – c00000fd Feb 02 '18 at 21:01
  • did you ever find a solution for this? I am trying to get rid of the `Sleep` as well – HelloWorld Dec 20 '21 at 04:42
-1

I'd start by initializing info:

SHELLEXECUTEINFO info = {0};

Then, I'd try a verb that actually exists in the registry under HKEY_CLASSES_ROOT\txtfile\shell

info.lpVerb = "open";

Which I strongly suspect will work. The problem is, explorer does not launch an application to show the properties of files - its built in. Not every piece of functionality on a file context menu is a verb that you can invoke via ShellExecute.

If you want to invoke the properties context menu item for a file - you will need to query for the IShellFolder that represents the files folder, call GetUIObjectOf to get the IContextMenu for the file, which you can then call InvokeCommand on.

See Getting Information About the Contents of a Folder on MSDN for information.

Chris Becke
  • 750
  • 4
  • 10