- [C#] Cách Sử Dụng DeviceId trong C# Để Tạo Khóa Cho Ứng Dụng
- [SQLSERVER] Loại bỏ Restricted User trên database MSSQL
- [C#] Hướng dẫn tạo mã QRcode Style trên winform
- [C#] Hướng dẫn sử dụng temp mail service api trên winform
- [C#] Hướng dẫn tạo mã thanh toán VietQR Pay không sử dụng API trên winform
- [C#] Hướng Dẫn Tạo Windows Service Đơn Giản Bằng Topshelf
- [C#] Chia sẻ source code đọc dữ liệu từ Google Sheet trên winform
- [C#] Chia sẻ source code tạo mã QR MOMO đa năng Winform
- [C#] Chia sẻ source code phần mềm lên lịch tự động chạy ứng dụng Scheduler Task Winform
- [Phần mềm] Tải và cài đặt phần mềm Sublime Text 4180 full version
- [C#] Hướng dẫn download file từ Minio Server Winform
- [C#] Hướng dẫn đăng nhập zalo login sử dụng API v4 trên winform
- [SOFTWARE] Phần mềm gởi tin nhắn Zalo Marketing Pro giá rẻ mềm nhất thị trường
- [C#] Việt hóa Text Button trên MessageBox Dialog Winform
- [DEVEXPRESS] Chia sẻ code các tạo report in nhiều hóa đơn trên XtraReport C#
- [POWER AUTOMATE] Hướng dẫn gởi tin nhắn zalo từ file Excel - No code
- [C#] Chia sẻ code lock và unlock user trong domain Window
- [DEVEXPRESS] Vẽ Biểu Đồ Stock Chứng Khoán - Công Cụ Thiết Yếu Cho Nhà Đầu Tư trên Winform
- [C#] Hướng dẫn bảo mật ứng dụng 2FA (Multi-factor Authentication) trên Winform
- [C#] Hướng dẫn convert HTML code sang PDF File trên NetCore 7 Winform
[C#] Giới thiệu thư viện Pinvoke.NET demo ứng dụng Copy File with progress bar
Xin chào các bạn, bài viết hôm nay mình sẽ tiếp tục hướng dẫn đến các bạn thư viện Pinvoke.NET trong lập trình C# winform.
[C#] How to use library Pinvoke.NET
Pinvoke.NET là gì?
Pinvoke.NET là một website giống như cuốn từ điển, cho phép chúng ta tìm kiếm các hàm sử dụng thư viện Win32 để tích hợp vào trong ứng dụng lập trình .NET.
Ở website Pinvoke này, cung cấp cho chúng ta code cả hai ngôn ngữ (VB.NET và C#).
API (Application Programming Interface) là cách thức dùng để gọi hàm bên trong thư viện liên kết động DLL.
Thực hiện các tác vụ Windows như tạo và huỷ các cửa sổ ứng dụng, các control và menu; truy xuất các dịch vụ hệ thống màn hình, bàn phím và chuột, máy in và nhiều chức năng khác.
Các hàm API thường được viết bằng C++
Các bạn có thể truy cập vào website: pinvoke.net để tham khảo nhé.
Và bài viết dưới đây, mình sẽ demo sử dụng Pinvoke.NET và viết ứng dụng nhỏ Copy File với Progress bar sử dụng thư viện Win32.
Trong .NET framework, có cung cấp cho chúng ta hàm File.Copy(source, dest, override)
nằm trong thư viện System.IO
(thư viện này không hỗ trợ trả về cho chúng ta progress bar phần trăm hoàn thành).
Nếu trong Net muốn lấy phần trăm progress, chúng ta phải sử dụng Stream và read byte để tính toán phần trăm.
Các bạn có thể tham khảo bài viết Copy File with Progressbar C# tại đây
HƯỚNG DẪN COPY FILE SỬ DỤNG PINVOKE
Các bạn truy cập vào website Pinvoke.net và gõ ở ô tìm kiếm với keyworks: copy file, các bạn sẽ được hình ảnh bên dưới.
Giao diện demo ứng dụng copy File Win32 C#:
Đầu tiên các bạn tạo cho mình một class XCopy.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Pinvoke_Copyfile
{
class XCopy
{
public static void Copy(string source, string destination, bool overwrite, bool nobuffering)
{
new XCopy().CopyInternal(source, destination, overwrite, nobuffering, null);
}
public static void Copy(string source, string destination, bool overwrite, bool nobuffering, EventHandler<ProgressChangedEventArgs> handler)
{
new XCopy().CopyInternal(source, destination, overwrite, nobuffering, handler);
}
private event EventHandler Completed;
private event EventHandler<ProgressChangedEventArgs> ProgressChanged;
private int IsCancelled;
private int FilePercentCompleted;
private string Source;
private string Destination;
private XCopy()
{
IsCancelled = 0;
}
private void CopyInternal(string source, string destination, bool overwrite, bool nobuffering, EventHandler<ProgressChangedEventArgs> handler)
{
try
{
CopyFileFlags copyFileFlags = CopyFileFlags.COPY_FILE_RESTARTABLE;
if (!overwrite)
copyFileFlags |= CopyFileFlags.COPY_FILE_FAIL_IF_EXISTS;
if (nobuffering)
copyFileFlags |= CopyFileFlags.COPY_FILE_NO_BUFFERING;
Source = source;
Destination = destination;
if (handler != null)
ProgressChanged += handler;
bool result = CopyFileEx(Source, Destination, new CopyProgressRoutine(CopyProgressHandler), IntPtr.Zero, ref IsCancelled, copyFileFlags);
if (!result)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
catch (Exception)
{
if (handler != null)
ProgressChanged -= handler;
throw;
}
}
private void OnProgressChanged(double percent)
{
// only raise an event when progress has changed
if ((int)percent > FilePercentCompleted)
{
FilePercentCompleted = (int)percent;
var handler = ProgressChanged;
if (handler != null)
handler(this, new ProgressChangedEventArgs((int)FilePercentCompleted, null));
}
}
private void OnCompleted()
{
var handler = Completed;
if (handler != null)
handler(this, EventArgs.Empty);
}
#region PInvoke
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CopyFileEx(string lpExistingFileName, string lpNewFileName, CopyProgressRoutine lpProgressRoutine, IntPtr lpData, ref Int32 pbCancel, CopyFileFlags dwCopyFlags);
private delegate CopyProgressResult CopyProgressRoutine(long TotalFileSize, long TotalBytesTransferred, long StreamSize, long StreamBytesTransferred, uint dwStreamNumber, CopyProgressCallbackReason dwCallbackReason,
IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData);
private enum CopyProgressResult : uint
{
PROGRESS_CONTINUE = 0,
PROGRESS_CANCEL = 1,
PROGRESS_STOP = 2,
PROGRESS_QUIET = 3
}
private enum CopyProgressCallbackReason : uint
{
CALLBACK_CHUNK_FINISHED = 0x00000000,
CALLBACK_STREAM_SWITCH = 0x00000001
}
[Flags]
private enum CopyFileFlags : uint
{
COPY_FILE_FAIL_IF_EXISTS = 0x00000001,
COPY_FILE_NO_BUFFERING = 0x00001000,
COPY_FILE_RESTARTABLE = 0x00000002,
COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004,
COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008
}
private CopyProgressResult CopyProgressHandler(long total, long transferred, long streamSize, long streamByteTrans, uint dwStreamNumber,
CopyProgressCallbackReason reason, IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData)
{
if (reason == CopyProgressCallbackReason.CALLBACK_CHUNK_FINISHED)
OnProgressChanged((transferred / (double)total) * 100.0);
if (transferred >= total)
OnCompleted();
return CopyProgressResult.PROGRESS_CONTINUE;
}
#endregion
}
}
Và tiếp theo là code c# cho form chính copy file:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pinvoke_Copyfile
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void btn_Copy_Click(object sender, EventArgs e)
{
var source = txtSource.Text;
var dest = txtDest.Text;
var progress = new Progress<int>(percent =>
{
progressBar1.Value = percent;
lbl_percent.Text = percent + "%";
});
await Task.Run(() => TaskCopy(source, dest, progress));
}
public void TaskCopy(string source, string dest, IProgress<int> progress)
{
XCopy.Copy(source, dest, true, true, (o, pce) =>
{
progress.Report(pce.ProgressPercentage);
});
}
}
}
Thanks for watching!