首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

PowerShell 呼叫 Windows API 查詢文件預設開啟程式:FindExecutable 實戰

     編輯:更多程式設計知識

前言

在 Windows 中,文件副檔名與可執行程式的關聯存儲於註冊表,但手動解析註冊表需處理 32/64 位重定向、用戶選擇覆蓋等複雜情況。更簡單且可靠的方式是直接呼叫 Shell32.dll 的 FindExecutable API,讓作業系統幫你完成關聯解析。本文示範如何在 PowerShell 中透過 C# 簽名呼叫該 API。

核心代碼:內嵌 C# 定義 P/Invoke 簽名

$Source = @"
using System;
using System.Text;
using System.Runtime.InteropServices;

public class Win32API
{
    [DllImport("shell32.dll", EntryPoint = "FindExecutable", CharSet = CharSet.Auto)]
    public static extern long FindExecutableA(string lpFile, string lpDirectory, StringBuilder lpResult);

    public static string FindExecutable(string filePath)
    {
        var buffer = new StringBuilder(1024);
        long result = FindExecutableA(filePath, string.Empty, buffer);
        // 返回值 >= 32 表示成功
        return result >= 32 ? buffer.ToString() : $"Error: ({result})";
    }
}
"@

Add-Type -TypeDefinition $Source -ErrorAction SilentlyContinue

實際調用範例

$file = "C:\Windows\windowsupdate.log"
$exe = [Win32API]::FindExecutable($file)
Write-Host "$file 將由 $exe 開啟"

輸出範例:

C:\Windows\windowsupdate.log 將由 C:\Windows\System32\notepad.exe 開啟

重要限制與已知問題

  • 文件必須存在:FindExecutable 需要實體文件,無法僅用副檔名查詢。
  • MMC 嵌入式管理單元:如 .cer、.pfx 憑證文件由 MMC 管理,呼叫此 API 可能導致程式崩潰(社群回報)。
  • UserChoice 覆蓋:若用戶在「開啟方式」中自訂關聯,API 會正確返回用戶選擇的程式,這通常是期望行為。

替代方案:註冊表查詢(無需文件存在)

若需「不依賴實體文件」查詢副檔名關聯,可解析 HKEY_CLASSES_ROOT\.ext → ProgID → shell\open\command,但需自行處理 32/64 位視圖與參數展開(%1 等)。

總結

對於「已有文件,想知道雙擊會開啟什麼程式」的需求,FindExecutable 是最省力、最準確的方案。PowerShell 配合 Add-Type 內嵌 C# P/Invoke,幾行代碼即可調用原生 API,極大拓展了腳本能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved