1

If a user enters a URL into a Windows Forms OpenFileDialog then the dialog box (on more modern versions) of Windows will download the file and open it from a temporary directory. Is there any way to get at the entered URL? Could the new-fangled IFileDialog help?

Please note that I am not looking for the file:// equivalent of a local file. This is for when the user enters the location of something on the Internet into the file dialog. e.g. http://example.com/path.

This asks essentially the same question, but didn't get a useful answer, perhaps because he asks that the result appear in the FileName property.

Community
  • 1
  • 1
Oliver Bock
  • 4,829
  • 5
  • 38
  • 62
  • Can you add source link about "Windows will download the file and open it from a temporary directory"? Looks like behaviour implemented in some app, not OS/framework functionality. Also, have you tried `FileName` property? – CodingFeles Sep 21 '15 at 02:42
  • @CodingFeles, it is something I have observed using my own application on a Windows 10 computer, but it doesn't happen on my Windows 7 computer. The FileName property contains the temporary path, which the file has been downloaded to. – Oliver Bock Sep 21 '15 at 03:16
  • 1
    possible duplicate of [URL as FileName in OpenFileIDialog C#](http://stackoverflow.com/questions/19809936/url-as-filename-in-openfileidialog-c-sharp) – Abhishek Sep 21 '15 at 04:11

2 Answers2

1

It's possible to set a windows hook to listen for text changes. This code currently picks up value changes from all fields, so you will need to figure out how to only detect the ComboBox filename field.

    public class MyForm3 : Form {

        public MyForm3() {
            Button btn = new Button { Text = "Button" };
            Controls.Add(btn);
            btn.Click += btn_Click;
        }

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
        [DllImport("user32.dll")]
        private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);


        private const int WINEVENT_OUTOFCONTEXT = 0;
        private const uint EVENT_OBJECT_VALUECHANGE = 0x800E;

        void btn_Click(object sender, EventArgs e) {
            uint pid = 0;
            uint tid = 0; 
            using (var p = Process.GetCurrentProcess())
                GetWindowThreadProcessId(p.MainWindowHandle, out pid);

            var hHook = SetWinEventHook(EVENT_OBJECT_VALUECHANGE, EVENT_OBJECT_VALUECHANGE, IntPtr.Zero, CallWinEventProc, pid, tid, WINEVENT_OUTOFCONTEXT);

            OpenFileDialog d = new OpenFileDialog();
            d.ShowDialog();
            d.Dispose();
            UnhookWinEvent(hHook);

            MessageBox.Show("Original filename: " + OpenFilenameText);
        }

        private static String OpenFilenameText = "";
        private static WinEventProc CallWinEventProc = new WinEventProc(EventCallback);
        private delegate void WinEventProc(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime);
        private static void EventCallback(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime) {
            StringBuilder sb1 = new StringBuilder(256);
            GetClassName(hWnd, sb1, sb1.Capacity);
            if (sb1.ToString() == "Edit") {
                StringBuilder sb = new StringBuilder(512);
                GetWindowText(hWnd, sb, sb.Capacity);
                OpenFilenameText = sb.ToString();
            }
        }
    }
Loathing
  • 5,109
  • 3
  • 24
  • 35
0

If you only want to get URL (not download file), set CheckFileExists flag to false. Example code below

        string urlName = null;
        using (var dlg = new OpenFileDialog())
        {
            dlg.CheckFileExists = false;

            dlg.ShowDialog();
            urlName = dlg.FileName;
            urlName = Path.GetFileName(urlName);

        }
Sumit Deo
  • 2,196
  • 2
  • 15
  • 12
  • This works in a sense, but it makes the dialog useless for selecting files, which is its main purpose, because it won't do any validation on the file name. – Oliver Bock Sep 21 '15 at 23:10