Copy the file in chunks on one thread and use callbacks to set the progress bar value.
On my own laptop through trial and error I found that the lowest amount I could read but still be io efficient was about half a meg.

Code:
//Code was not complied\checked, more of guide, notice I havnt even closed the streams

        void Copy()
        {
            int halfAMeg = (int)(1024 * 1024 * 0.5);

            FileStream strIn = new FileStream("filePathIn", FileMode.Open);
            FileStream strOut = new FileStream("filePathOut", FileMode.Create);

            byte[] buf = new byte[halfAMeg];
            while (strIn.Position < strIn.Length)
            {
                int len = strIn.Read(buf, 0, buf.Length);
                strOut.Write(buf, 0, len);

                SetProBar(strIn.Position, strIn.Length);
            }
        }

        private delegate void SetProBar_CallBack(long val,long max);
        private void SetProBar(long val, long max)
        {
            if (progressBar.InvokeRequired)
            {
                SetProBar_CallBack callBack = new SetProBar_CallBack(SetProBar);
                this.Invoke(callBack, new object[] { val, max });
            }
            else
            {
                progressBar.Maximum = Int32.MaxValue;
                progressBar.Value = (int)(Int32.MaxValue / (max / val));
            }
        }