問題描述
當雙擊打開自定義格式的檔案時,希望使用當前正在運行的行程,而不是另起一個行程,
本文介紹一種方式解決如上問題,方案參考user3582780的解答
設定自定義檔案格式的默認打開方式
參考鏈接,具體步驟如下:
- 在HKEY_CLASSES_ROOT中新建項,命名為自定義檔案格式(如.custom),設定其默認值(如mycustom);
- 在HKEY_CLASSES_ROOT中新建項,命名為步驟1中的默認值,即mycustom;
- 在mycustom中新建項,命名為DefaultIcon,設定默認值(Icon路徑);
- 在mycustom中新建項,命名為shell,在shell中繼續新建項open,在open中新建項command,設定其默認值(格式:程式路徑 "%1")
使用當前實體打開檔案
首先,當雙擊自定義格式檔案進行打開時,會將該檔案的路徑作為引數傳遞給程式,因此打開程式應回應啟動引數,
在WPF應用程式中,Application的OnStartup方法會攜帶程式的啟動引數(通過Environment也可獲取啟動引數),
當雙擊自定義格式檔案時,若有一個實體正在運行,并不會直接使用該實體打開檔案,而是會重新打開一個實體,此時需要將新實體的啟動引數傳遞給當前實體并關閉新實體,
本文使用發送視窗訊息的方式處理該問題,即使用Win32的SendMessage介面發送引數給當前實體視窗,當前實體回應訊息處理即可,具體實作方案如下:
// App
private static Mutex mutex;
protected override void OnStartup(StartupEventArgs e)
{
mutex = new Mutex(true, "myapp", out bool ret);
if(!ret)
Reopen(e);
// ...
}
private void Reopen(StartupEventArgs e)
{
// IntPtr hwnd = FindWindow(null, "window title");
if(e.Args.Length > 0)
SendMessage();
Environment.Exit(0);
}
private void SendMessage(IntPtr hwnd, string data)
{
CopyDataStruct cds = new CopyDataStruct();
try
{
cds.cbData = https://www.cnblogs.com/louzixl/archive/2021/04/14/(data.Length + 1) * 2; // number of bytes
cds.lpData = Win32.LocalAlloc(0x40, cds.cbData); // known local-pointer in RAM
Marshal.Copy(data.ToCharArray(), 0, cds.lpData, data.Length); // Copy data to preserved local-pointer
cds.dwData = (IntPtr)1;
SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, ref cds);
}
finally
{
cds.Dispose();
}
}
// Window
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if(msg == WM_COPYDATA)
{
CopyDataStruct st = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
string strData = Marshal.PtrToStringUni(st.lpData);
OpenFile(strData);
Activate();
}
return IntPtr.Zero;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/276140.html
標籤:.NET技术
