0

I have edited the windows registry so that selected files can be opened with the program I made (from an option in context menu). Specifically, under specific file types I have added 'shell' key and under it a 'command' key with string containing "C:\MyProgram.exe %1". The file opens correctly, however my program receives the file name in old 8.3 format, and I need full file name for display. How should I fix this?

Side quest: How to open multiple files as multiple arguments in one program call instead of opening separate instances, each with only one argument(%1)?

Vladivarius
  • 498
  • 1
  • 3
  • 14
  • It is not normal. Don't obfuscate the program name, show us its manifest and the dumpbin.exe /headers output. – Hans Passant May 13 '16 at 12:10
  • Strangely it didn't happen again after next restart but I don't want to risk so I implemented IInspectable's answer. – Vladivarius May 13 '16 at 12:16
  • I suspect we'll hear back from you some day so this could become a useful Q+A. Like when the short path fits but the long path exceeds MAX_PATH, nasty failure mode. – Hans Passant May 13 '16 at 12:22
  • @HansPassant Nop, just tested it, works very fine after I implemented IInspectable's answer. – Vladivarius May 13 '16 at 14:25

2 Answers2

1

The easiest way to get to the full path name is to call GetLongPathName. In C++ you would use something like the following:

std::wstring LongPathFromShortPath(const wchar_t* lpszShortPath) {

    // Prevent truncation to MAX_PATH characters
    std::wstring shortPath = L"\\\\?\\";
    shortPath += lpszShortPath;

    // Calculate required buffer size
    std::vector<wchar_t> buffer;
    DWORD requiredSize = ::GetLongPathNameW(shortPath.c_str(), buffer.data(), 0x0);
    if (requiredSize == 0x0) {
        throw std::runtime_error("GetLongPathNameW() failed.");
    }

    // Retrieve long path name
    buffer.resize(static_cast<size_type>(requiredSize));
    DWORD size = ::GetLongPathNameW(shortPath.c_str(), buffer.data(), 
                                    static_cast<DWORD>(buffer.size()));
    if (size == 0x0) {
        throw std::runtime_error("GetLongPathNameW() failed.");
    }

    // Construct final path name (not including the zero terminator)
    return std::wstring(buffer.data(), buffer.size()-1);
}
IInspectable
  • 46,945
  • 8
  • 85
  • 181
0

For first part of question do that IInspectable suggested.

But if you want to do something more fancy, simple registry modification will not do the trick. You need Windows Shell Extension and implement Context Menu handler. Once I have made one, here are some useful links: here, here and here. And there are already similar questions like this

Community
  • 1
  • 1
ST3
  • 8,826
  • 3
  • 68
  • 92
  • Thanks, I searched for an answer but didn't find some of those answers, they are exactly what my second question was about. – Vladivarius May 13 '16 at 12:13