0

When running the code below on windows server 2003, there are intermittent slowdowns while GetOpenFileName common dialog initializes. the startup time varies at around ~30 seconds. The code below is a scratch program I made to exemplify the problem I'm having in my larger project but the problem exists in both.

One important note, is that when the network interfaces are all disabled, the time taken to initialize is much closer to normal - typically ~2 seconds. As soon as they are enabled again, the problem returns.

I have put the initialization time up against other programs with file open common dialogs (like Notepad) which do not have the same problem, with or without the network interfaces enabled.

Code:

getNewFileName.h:

#define _tWinMain wWinMain

#include "windows.h"
#include <string>
#include "resource.h"
using std::wstring;

#define ISOLATION_AWARE_ENABLED 1
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif 

getNewFileName.cpp:

#include "getNewFileName.h"

HINSTANCE           hInst;
BOOL                InitInstance(HINSTANCE);
HWND                hWnd;
wstring             lastfile;
BOOL                getNewFileName(HWND owner, wstring title, wstring defaultfile, LPWSTR filetypes, OPENFILENAME &ofn, wstring lastdir, wstring lastfile, int mode, wstring extension);

int APIENTRY _tWinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR    lpCmdLine,
    int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MSG msg;
    HACCEL hAccelTable;

    if (!InitInstance (hInstance))
    {
        return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(hWnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

BOOL InitInstance(HINSTANCE hInstance)
{
    hInst = hInstance;
    OPENFILENAME ofn;
    wstring newfn;
    hWnd = CreateWindow(NULL, L"test", NULL,
        0, 0, 0, 0, NULL, NULL, hInst, NULL);
    BOOL ret = getNewFileName(hWnd, L"test", L"*.xml", L"XML Files\0*.xml\0", ofn, L"C:\\", lastfile, 1, L"xml");
    if (ret) { 
        newfn = ofn.lpstrFile;
        MessageBox(hWnd,newfn.c_str(),L"test",MB_OK);
    }
    ExitProcess(0);
    return TRUE;
}

void addPrefix(wstring &path) {
    wstring test = path.substr(0,4);
    if (path.substr(0,8) == L"\\\\?\\UNC\\" || path.substr(0,4) == L"\\\\?\\") { return; }
    wstring prefix = path.substr(0,2);
    if (prefix.compare(L"\\\\") == 0) { path.assign(L"\\\\?\\UNC\\"+path.substr(2,wstring::npos)); } else { path.assign(L"\\\\?\\"+path); }
    return;
}

UINT_PTR CALLBACK OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
    HICON hIcon;
    int width, height, xLeft, yTop;
    RECT rectToCenterOn, rectSubDialog;
    switch (uiMsg) {
    case WM_INITDIALOG:
        hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_PMMICO));
        SendMessage(GetParent(hdlg), WM_SETICON, ICON_BIG, (LPARAM)hIcon); 
        SendMessage(GetParent(hdlg), WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 
        GetWindowRect(GetDesktopWindow(), &rectToCenterOn);
        GetWindowRect(GetParent(hdlg), &rectSubDialog);
        width = rectSubDialog.right-rectSubDialog.left;
        height = rectSubDialog.bottom-rectSubDialog.top;
        xLeft = rectToCenterOn.right / 2 - 
            (width) / 2;
        yTop = rectToCenterOn.bottom / 2 - 
            (height) / 2;
        BOOL test  = SetWindowPos(GetParent(hdlg), NULL, xLeft, yTop, width, height, SWP_NOSIZE);
        return (INT_PTR)FALSE;
        break;
    }
    return (INT_PTR)FALSE;
}

BOOL getNewFileName(HWND owner, wstring title, wstring defaultfile, LPWSTR filetypes, OPENFILENAME &ofn, wstring lastdir, wstring lastfile, int mode, wstring extension) {
    wstring lastdir_pre(lastdir);
    addPrefix(lastdir_pre);
    if (lastfile.compare(L"") == 0) { lastfile = defaultfile; }
    BOOL ret = false;
    wchar_t Buffer[30000];
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = owner;
    ofn.lpstrFile = Buffer;
    lastfile.copy(ofn.lpstrFile,lastfile.size(),0);
    ofn.lpstrFile[lastfile.size()] = '\0';
    ofn.nMaxFile = 30000;
    ofn.Flags = OFN_OVERWRITEPROMPT | OFN_ENABLEHOOK | OFN_EXPLORER;
    ofn.lpfnHook = OFNHookProc;
    ofn.lpstrFilter = filetypes;
    ofn.lpstrCustomFilter = NULL;
    ofn.nFilterIndex = 0;
    ofn.lpstrInitialDir = lastdir_pre.c_str();
    ofn.lpstrFileTitle = NULL;
    ofn.lpstrDefExt = extension.c_str();
    ofn.lpstrTitle = title.c_str();
    if (mode == 1) {
        ofn.Flags = ofn.Flags | OFN_PATHMUSTEXIST;
        ret = GetOpenFileName(&ofn); 
    } else if (mode == 2) {
        ret = GetSaveFileName(&ofn); 
    }
    if (ret == false) { ofn.lpstrFile[0] = '\0'; }
    return ret;
}
  • Operating system continually horrendously unsafe on 2003 server – Puppy Jul 14 '15 at 15:16
  • @Puppy Completely agreed. However, I have no power or authority over the client/user's choice of OS :( – Trent Torkelson Jul 14 '15 at 15:27
  • The dialog displays an Explorer Shell, and loads COM objects and Shell objects. If those objects interact with the network, and the network is acting slow, that will affect the dialog. – Remy Lebeau Jul 14 '15 at 17:51
  • @RemyLebeau That makes sense, only if we disregard that Notepad.exe and other programs' file open dialogs are not affected by the network lag. Knowing this, it must be possible to bypass the network lag problems as other programs do, correct? – Trent Torkelson Jul 14 '15 at 18:03
  • There are plenty of Win32 API monitor apps available, see if any of them are able to display the parameters that Notepad is passing to `GetOpenFileName()`. The slowdown can also be caused by misbehaving Antivirus software. And it has been reported in the past that `GetOpenFileName()` slowness can even be linked to the app's filename! (probably related to the AV issue, though). So try changing your app's filename and see if it helps. – Remy Lebeau Jul 14 '15 at 18:29
  • No A/V software on the test machine, so that's ruled out. I've heard about the filename change test, which I instantly thought would be a windows - behind the scenes caching issue, as it does with icons sometimes. This didn't turn out to be the case for my tests, changing the name did nothing different, and even if it did it wouldn't be a solid solution to delay - rename my program on every use. – Trent Torkelson Jul 14 '15 at 18:35

0 Answers0