C# 捕获 Microsoft 打印到 PDF 对话框
C# Capture Microsoft Print to PDF dialog
我想捕获并禁止在非 Office 应用程序中使用 Microsoft Print to PDF 驱动程序时显示的保存文件对话框。然后以编程方式输入文件路径,可能使用 System.Windows.Automation。
我似乎找不到显示 SaveFileDialog 的句柄。我相信我可以处理 Windows.Automation 部分。
我想使用 Microsoft 驱动程序,因为它随所有 windows 10.
还有其他方法可以 capture/suppress 这个对话框吗?我目前通过注册表在本地机器上使用另一个 pdf 驱动程序来执行此操作。但我想转到 Microsoft PDF,因为它是标准格式。
话题:
How to programmatically print to PDF file without prompting for filename in C# using the Microsoft Print To PDF printer that comes with Windows 10 - 没有解决我的问题,当从 Revit API 中 运行 时打印空白页。 Autodesk Revit 必须启动打印(并通过其 api 完成)。
尝试从 user32.dll
中查找对话框的代码
public static List<IntPtr>GetChildWindows( IntPtr parent) {
List<IntPtr>result=new List<IntPtr>();
GCHandle listHandle=GCHandle.Alloc(result);
try {
EnumWindowProc childProc=new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally {
if (listHandle.IsAllocated) listHandle.Free();
}
return result;
}
public static string GetText(IntPtr hWnd) {
int length=GetWindowTextLength(hWnd);
StringBuilder sb=new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
private void Test() {
Process[] revits=Process.GetProcessesByName( "Revit");
List<IntPtr>children=GetChildWindows( revits[0].MainWindowHandle);
var names=new List<string>();
foreach (var child in children) {
names.Add(GetText(child));
}
}
我 运行 在我自己的系统上进行了一些测试,似乎枚举顶层 windows 会找到“保存文件”对话框。我尝试从多个程序打印到 MS PDF 打印机,结果都是一样的。下面是一些改编自 MS Docs window 枚举示例的代码。我在代码中添加了获取进程 ID 的代码,因此您可以检查以确保它是您的 window.
// P/Invoke declarations
protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
// Callback for examining the window
protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
{
int size = GetWindowTextLength(hWnd);
if (size++ > 0 && IsWindowVisible(hWnd))
{
StringBuilder sb = new StringBuilder(size);
GetWindowText(hWnd, sb, size);
if (sb.ToString().Equals("Save Print Output As", StringComparison.Ordinal))
{
uint procId = 0;
GetWindowThreadProcessId(hWnd, out procId);
Console.WriteLine($"Found it! ProcID: {procId}");
}
}
return true;
}
void Main()
{
EnumWindows(new EnumWindowsProc(EnumTheWindows), IntPtr.Zero);
}
我想捕获并禁止在非 Office 应用程序中使用 Microsoft Print to PDF 驱动程序时显示的保存文件对话框。然后以编程方式输入文件路径,可能使用 System.Windows.Automation。
我似乎找不到显示 SaveFileDialog 的句柄。我相信我可以处理 Windows.Automation 部分。
我想使用 Microsoft 驱动程序,因为它随所有 windows 10.
还有其他方法可以 capture/suppress 这个对话框吗?我目前通过注册表在本地机器上使用另一个 pdf 驱动程序来执行此操作。但我想转到 Microsoft PDF,因为它是标准格式。
话题: How to programmatically print to PDF file without prompting for filename in C# using the Microsoft Print To PDF printer that comes with Windows 10 - 没有解决我的问题,当从 Revit API 中 运行 时打印空白页。 Autodesk Revit 必须启动打印(并通过其 api 完成)。
尝试从 user32.dll
中查找对话框的代码public static List<IntPtr>GetChildWindows( IntPtr parent) {
List<IntPtr>result=new List<IntPtr>();
GCHandle listHandle=GCHandle.Alloc(result);
try {
EnumWindowProc childProc=new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally {
if (listHandle.IsAllocated) listHandle.Free();
}
return result;
}
public static string GetText(IntPtr hWnd) {
int length=GetWindowTextLength(hWnd);
StringBuilder sb=new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
private void Test() {
Process[] revits=Process.GetProcessesByName( "Revit");
List<IntPtr>children=GetChildWindows( revits[0].MainWindowHandle);
var names=new List<string>();
foreach (var child in children) {
names.Add(GetText(child));
}
}
我 运行 在我自己的系统上进行了一些测试,似乎枚举顶层 windows 会找到“保存文件”对话框。我尝试从多个程序打印到 MS PDF 打印机,结果都是一样的。下面是一些改编自 MS Docs window 枚举示例的代码。我在代码中添加了获取进程 ID 的代码,因此您可以检查以确保它是您的 window.
// P/Invoke declarations
protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
// Callback for examining the window
protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
{
int size = GetWindowTextLength(hWnd);
if (size++ > 0 && IsWindowVisible(hWnd))
{
StringBuilder sb = new StringBuilder(size);
GetWindowText(hWnd, sb, size);
if (sb.ToString().Equals("Save Print Output As", StringComparison.Ordinal))
{
uint procId = 0;
GetWindowThreadProcessId(hWnd, out procId);
Console.WriteLine($"Found it! ProcID: {procId}");
}
}
return true;
}
void Main()
{
EnumWindows(new EnumWindowsProc(EnumTheWindows), IntPtr.Zero);
}