0

I am trying to find the File extension, path and file size using user32 or kernal32 in c#.

My scenario : While uploading some files in web (email,application etc..) I need to fetch the filename, its path and size of the file (size of the file is optional). I am using OpenFileDialog handle and I can able to retrieve the filename of the selected file to be uploaded. Could you please help me to retrieve the path and size of the file using the same. I can able to find the handle for OpenFileDialog how to proceed to retrieve information using those handle

please find my below code (some of the dll reference will not be useful):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;
using System.Security.Principal;
using `enter code here`System.Diagnostics;

namespace Opendailoghandle
{
    class Program
    {
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, int wParam, StringBuilder lParam);

        //  [DllImport("user32.dll", CharSet = CharSet.Auto)]
        //  public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetDlgItem(IntPtr hwnd, int childID);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int SendMessage(HandleRef hwnd, int wMsg, int wParam, String s);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern String SendMessage(HandleRef hwnd, uint WM_GETTEXT);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);
        // to get file size import
        [DllImport("kernel32.dll")]
        static extern bool GetFileSizeEx(IntPtr hFile, out long lpFileSize);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CreateFile(
     [MarshalAs(UnmanagedType.LPTStr)] string filename,
     [MarshalAs(UnmanagedType.U4)] FileAccess access,
     [MarshalAs(UnmanagedType.U4)] FileShare share,
     IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
     [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
     [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
     IntPtr templateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

        public struct  WIN32_FIND_DATA
        {
            public int dwFileAttributes;
            public FILETIME ftCreationTime;
            public FILETIME ftLastAccessTime;
            public FILETIME ftLastWriteTime;
            public int nFileSizeHigh;
            public int nFileSizeLow;
            public int dwReserved0;
            public int dwReserved1;
            public string cFileName; //mite need marshalling, TCHAR size = MAX_PATH???
            public string cAlternateFileName; //mite need marshalling, TCHAR size = 14
        }
        public struct WIN32_FIND_DATA1
        {
            public int dwFileAttributes;
            public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
            public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
            public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
            public int nFileSizeHigh;
            public int nFileSizeLow;
            public int dwReserved0;
            public int dwReserved1;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string cFileName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
            public string cAlternateFileName;
        }

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

        [DllImport("kernel32.dll")]
        static extern IntPtr FindFirstFile(IntPtr lpfilename, ref WIN32_FIND_DATA findfiledata);

        [DllImport("kernel32.dll")]
        static extern IntPtr FindClose(IntPtr pff);



        [DllImport("User32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        public static Process[] myProcess = Process.GetProcessesByName("program name here");


        const uint WM_GETTEXT = 0x0D;
        const uint WM_GETTEXTLENGTH = 0X0E;
        const int BN_CLICKED = 245;
        private const int WM_SETTEXT = 0x000C;

        static void Main()
        {
            IntPtr hWnd = FindWindow(null, "Open");

            if (hWnd != IntPtr.Zero)
            {
                Console.WriteLine("Open File Dialog is open");


                IntPtr hwndButton = FindWindowEx(hWnd, IntPtr.Zero, "Button", "&Open");
                Console.WriteLine("The handle of the Open button is " + hwndButton);

                IntPtr FileDialogHandle = FindWindow(null, "Open");
                IntPtr iptrHWndControl = GetDlgItem(FileDialogHandle, 1148);
                HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
                //SendMessage(hrefHWndTarget, WM_SETTEXT, 0, "your file path");

                IntPtr opnButton = FindWindowEx(FileDialogHandle, IntPtr.Zero, "Open", null);

                SendMessage((int)opnButton, BN_CLICKED, 0, IntPtr.Zero);

                int len = (int)SendMessage(hrefHWndTarget, WM_GETTEXTLENGTH, 0, null);
                var sb = new StringBuilder(len + 1);

                SendMessage(hrefHWndTarget, WM_GETTEXT, sb.Capacity, sb);
                string text = sb.ToString();
                //FileInfo f = new FileInfo(text);
                DirectoryInfo hdDirectoryInWhichToSearch = new DirectoryInfo(@"c:\");
                FileInfo[] filesInDir = hdDirectoryInWhichToSearch.GetFiles("*" + text + "*.*");

                foreach (FileInfo foundFile in filesInDir)
                {
                    string fullName = foundFile.FullName;
                    Console.WriteLine(fullName);
                }

                var newName = DateTime.Now;

                var Username = (WindowsIdentity.GetCurrent().Name);
                //var contentArray = GetFileSizeB(text);


                Console.WriteLine("The Edit box contains " + text+"\tsize:"+contentArray + "\nUser Name "+Username +"\tTime : "+newName );
            }
            else
            {
                Console.WriteLine("Open File Dialog is not open");
            }

            Console.ReadKey();
        }
        //public static uint GetFileSizeB(string filename)
        //{
        //    IntPtr handle = CreateFile(
        //        filename,
        //        FileAccess.Read,
        //        FileShare.Read,
        //        IntPtr.Zero,
        //        FileMode.Open,
        //        FileAttributes.ReadOnly,
        //        IntPtr.Zero);
        //    if (handle.ToInt32() == -1)
        //    {
        //        return 1;
        //    }
        //    long fileSize;
        //    GetFileSizeEx(handle, out fileSize);
        //    CloseHandle(handle);
        //    return (uint)fileSize;

        //}

    }
}*
Balagurunathan Marimuthu
  • 2,927
  • 4
  • 31
  • 44

2 Answers2

0

Check your FileInfo class it contains properties like Length,path,extension..

Example in the loop through the files in filesInDir...

You can get the fileName, Path, Length etc., like below

int LengthInBytes = foundFile.Length;

Hope This Helps...

string path = "C:\\Test";
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] filesInDir = di.GetFiles();
foreach (FileInfo foundFile in filesInDir)
{
  string fullName = foundFile.FullName;
  long fileLength = foundFile.Length;
  string fileName = foundFile.Name;
  string extension = foundFile.Extension;
  /// etc
  Console.WriteLine(fullName);
}

Using an OpenFileDialog

OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
    string fileName = ofd.FileName;
    MessageBox.Show("FName: " + fileName);
}

This will be a string of the full path to the file. If you have MultiSelect set on the OpenDialogBox it will return a string array of full filenames.

JohnG
  • 9,259
  • 2
  • 20
  • 29
  • thanks for reply i tried fileinfo but i could only get manifest of the filename such as Output: Open File Dialog is open The handle of the Open button is 1377394 The Edit box contains DialyUpdates_shayidha_090816 DIR:c:\users\732468\documents\visual studio 2015\Projects\Opendailoghandle\Opendailoghandle\bin\Debug but actual path is from C:\Documents.how to get actual path ???? and size – shayidha begum Sep 28 '16 at 10:01
  • also whatever code i used to fetch fielpath and filesize those codes are not working for me – shayidha begum Sep 28 '16 at 10:09
  • Hello shayidha. In your code above… in the loop foreach (FileInfo foundFile in filesInDir)… the foundFile is the FileInfo object… you are grabbing it’s FullName property in the loop and outputting it to the console. It is in that loop that you can get ALL the properties of the current foundFile. – JohnG Sep 28 '16 at 10:11
  • Thanks @JohnG yes i could understand i tried the code to fetch the file info only from "C:\" directory it is working fine for that particular directory. Suppose if i would select file from "D:\" then i can access only the file name. i cannot get any details because of this reason'DirectoryInfo hdDirectoryInWhichToSearch = new DirectoryInfo(@"c:\");' If there any possible way to search file path using file name in all directory or using user32 or kernel32 for handling method to trace the address bar of this open window handle – shayidha begum Sep 28 '16 at 10:36
  • @shayidha I am a little confused... are you using the OpenFileDilog? Or searching for a file? I updated the Answer to include a little code that will return all the files in the directory of the path string. You can change that string to D: or any other valid drive/path to get the files in the path. Again I am a little confused as to what you are actually trying to do... if your code above compiles all the info you need is in the loop foreach (FileInfo foundFile in filesInDir)... I think I am not fully understanding what you want to do. – JohnG Sep 28 '16 at 10:49
  • If you are searching for a particular file...[Searching for file in directories recursively](http://stackoverflow.com/questions/9830069/searching-for-file-in-directories-recursively) – JohnG Sep 28 '16 at 11:00
  • i can take file name of any type and from any directory but as a result i need to get the file path with input as file name i didn't mention as particular directory it can be from any directory (in above comments i had given for example) @balagurunathan-marimuthu Suppose file i am selecting is from "c:\user\document\test.txt" if i give input as "test" i need to get output as "c:\user\document\test.txt".Suppose file i am selecting is from "D:\user\document\user.doc" if i give input as "user" i need to get output as "D:\user\document\user.doc" – shayidha begum Sep 28 '16 at 11:13
  • @shayidha Using an OpenFileDialog class... when you select the file and click OK... the result returned will include the path string. From there you can examine it to see where the file needs to be saved. I updated my Answer to include a simple OpenFileDialog... the FileName property is the full path to the file. I am confused by 'if i give input as ''user''' how is this used in the OpenFileDialog? – JohnG Sep 28 '16 at 11:26
  • @shayidha _“Suppose file i am selecting is from ‘c:\user\document\test.txt’ if i give input as ‘test’ i need to get output as ‘c:\user\document\test.txt"_ … If the selected file is a file called text.txt and is from a directory called ‘c:\user\document\’… when user clicks OK the OpenFileDialog's property FileName will be the string ‘c:\user\document\test.txt’. This string will tell you “Where” it came from. if this is an OpenFileDialog the user inputs (selects) the file to open. Even if you supply a filename to the OpenDialogBox… that will give it a default name but the user can change it. – JohnG Sep 28 '16 at 12:05
  • unfortunately i am not using windows form to use openfiledialog i am having USER32 kERNAL 32 handling open file dialog in console application. could u suggest me in console C#??? – shayidha begum Sep 29 '16 at 07:14
  • @shayidha Is there some reason you have to use a console application? It seems odd that you would use a console app to access a windows control... I mean if you "need" to have the Win API OpenFileDialog... why not use a win app? Also... I am confused by the loop where you are accessing the info returned from "your" win handle to the OpenFileDialog... If the line... 'string fullName = foundFile.FullName;' does not return the full path, then something is wrong there. I would assume the handle. Can you put the code into a win app (without you handling the ODB) and see if you get the same results? – JohnG Sep 29 '16 at 08:04
  • @shayidha I would assume from the project name that your goal it to access a win component. And this is where I think the problem is. Juggling the windows pointers and nutty syntax can be very challenging. Like I said... if you run the code in a win app and it works... then put the code into the console app (with you handling the reference to the WIN API OpenFileDialog) and it doesn't work... then I would look at how you are handling your reference to the Win OpenFileDialog. – JohnG Sep 29 '16 at 08:25
0

Edited as per OP's further specs

You can able to get file information using System.IO.FileInfo class. Here below the sample code.

private static void ShowFileDetails()
{
    List<string> lstFiles = System.IO.Directory.GetFiles(@"D:\downloads").ToList(); //Need to pass the folder path to get the files.

    foreach (string file in lstFiles)
    {
        System.IO.FileInfo fi = new System.IO.FileInfo(file);
        Console.WriteLine(string.Format("Extension={0}\tFile Name={1}\tFile Size={2} bytes\tFile Path={3}\tCreated On={4}\tModified On={5}",
                            fi.Extension,
                            fi.Name,
                            fi.Length,
                            fi.FullName,
                            fi.CreationTime,
                            fi.LastWriteTime));
    }
    Console.ReadLine();
}
Balagurunathan Marimuthu
  • 2,927
  • 4
  • 31
  • 44
  • Thanks for the reply. i was forgot to mention that i am using C# console application develop. this code will not be able to fetch my required details as "OpenfileDialog" (using system.windows.form). if i am wrong please guide me with extended result of this – shayidha begum Sep 28 '16 at 10:12
  • May I know, from where you will get the file name? is your file name look like `C:\Users\User1\test.txt`? – Balagurunathan Marimuthu Sep 28 '16 at 10:22
  • i tried the code to fetch the file info only from "C:\" directory it is working fine for that particular directory (but not for the inner folder). Suppose if i would select file from "D:\" the code will not applying to it but i need to find the file path using file name independent of directories.i had tried to upload file from eg. D:\downloads\JAL.doc @balagurunathan-marimuthu – shayidha begum Sep 28 '16 at 10:42
  • Thanks for update i would appreciate the effort but this is not i am actually needed :(. i can add any type of file from any directory but as a result i need to get the file path with input as file name i didn't mention as particular directory it can be from any directory (in above comments i had given for example) @balagurunathan-marimuthu Suppose file i am selecting is from "c:\user\document\test.txt" if i give input as "test" i need to get output as "c:\user\document\test.txt".if from "D:\user\document\user.doc" if i give input as "user" i need to get output as "D:\user\document\user.doc" – shayidha begum Sep 28 '16 at 11:09