通常,当我需要在网站上填写表格时,我会使用“打印屏幕”按钮并运行 mspaint.exe 并将其粘贴到该过程的每个步骤的屏幕截图中。 最后,我用相同的名称保存所有图像,并以连续的数字结尾。
现在的问题是是否可以编写一个 C# 程序,按照进程号的顺序识别 RAM 中的 mspaint.exe 实例,并使用 OLE (OCX) 或 COM 或任何其他方法访问其内容,并使用“另存为”保存它“ 菜单。或者运行“全选”和“复制”菜单,然后保存剪贴板的内容?
在 Windows 11 上 Visual Studio 2022 的“添加引用”菜单中,我没有看到 mpssaint.exe 的 COM 对象。
上面提到的案例就是该程序的应用示例。它的另一个用途是,如果您打开了多个 mspaint.exe 并且您没有时间,您可以将它们全部保存在一起,以便在有时间时为照片指定适当的名称。
当然,我并不是指以下替代方法:
1- 编写一个带有 PictureBox 的 C# 程序,该程序显示剪贴板并在运行时自动保存,而不是 mspaint.exe
2- 一个程序,循环 RAM 中的进程并最大化 mspaint 进程并保存屏幕截图并终止该进程。
3- 使用“paint 3d”执行此操作的程序,...而不是 mspaint.exe
4-将屏幕截图保存在文件中的程序(“PrtSc”键的更好替代品)
事实上,我的意思是实际的 C# Win-Form 代码示例来执行此操作,一般解释可能没有帮助。
例如,如下代码:
public static void TryToSaveAllOpenMsPaintFiles()
{
TryToExecuteMenuOnMsPaint("SaveAs", @"d:\photos\Step.png");
}
public static void TryToExecuteMenuOnMsPaint(string MenuName, string MenuParameters = "")
{
var PaintProcesses = Process.GetProcessesByName("mspaint").OrderBy(p => p.Id);
int Counter = 0;
foreach (var process in PaintProcesses)
TryToExecuteMenuOnMsPaintByProcessId(process.Id, MenuName, MenuParameters, ++Counter);
}
public static void TryToExecuteMenuOnMsPaintByProcessId(int ProcessId, string MenuName, string MenuParameters = "", int Counter = 1)
{
// @"d:\photos\Step.png" will be replace with $"d:\photos\Step_{Counter}.png"
Console.WriteLine($"Menu '{MenuName}' with parameter '{MenuParameters}' was executed on process with ID: {ProcessId}");
}
更多示例来澄清问题:
其他例子:
众所周知,在 Windows 11 中,如果在 notepad.exe 中编辑文本文件并且关闭 Windows,则下次打开 notepad.exe 时,我们会看到它打开了最后一个正在编辑的文件,并且没有任何丢失。是否可以用C#程序做一些事情,以便在关闭之前我们可以保存所有正在编辑的图像在mspaint.exe中并在下次打开它们?
或:
假设我们要为网络编写一个程序,在下班后关闭系统之前保存用户所有打开的 mspaint,然后关闭或终止 Paint 进程。 (例如,如果员工不小心忘记关闭办公室计算机,出于安全考虑并防止系统通过互联网被黑客攻击,那就完了。)
最后,我通过查看 Stackoverflow 上其他有用的帖子找到了问题的答案
public enum SaveMethodType
{
UsingSaveAs = 1,
UsingCopyToClipboard = 2
}
private static void TryToSaveMSPaintFiles(string CommonFileName = @"D:\Photos\Step.png", SaveMethodType SaveMethod = SaveMethodType.UsingCopyToClipboard)
{
var PaintProcesses = Process.GetProcessesByName("mspaint").OrderBy(p => p.Id);
int Counter = 0;
foreach (var MSPaintProcess in PaintProcesses)
if (MSPaintProcess != null)
{
Counter++;
SetForegroundWindow(MSPaintProcess.MainWindowHandle);
var FullFileNameIncludingCounter = GetChangedFileNameAfterValidatingFileAndFolder(CommonFileName, Counter, true);
if (FullFileNameIncludingCounter != string.Empty)
if (SavingFileInActiveForm(FullFileNameIncludingCounter, SaveMethod))
CloseProcess(MSPaintProcess);
}
}
private static void CloseProcess(Process TheProcess)
{
if (TheProcess != null)
{
TheProcess.Kill();
TheProcess.WaitForExit();
TheProcess.Dispose();
}
}
private static bool SavingFileInActiveForm(string FullFileName, SaveMethodType SaveMethod)
{
switch (SaveMethod)
{
case SaveMethodType.UsingSaveAs:
SendKeys.SendWait(@"^{s} ");
SendKeys.SendWait(FullFileName + " {ENTER}");
return true;
case SaveMethodType.UsingCopyToClipboard:
SendKeys.SendWait(@"^{a}^{c}");
SaveClipboardAsPNG(FullFileName);
return true;
}
return false;
}
private static void SaveClipboardAsPNG(string FullFileName)
{
FullFileName = Path.ChangeExtension(FullFileName, "png");
var ImageInClipboard = Clipboard.GetImage();
if (ImageInClipboard != null)
ImageInClipboard.Save(FullFileName, ImageFormat.Png);
}
private static string GetChangedFileNameAfterValidatingFileAndFolder(string FullFilePath, int Counter, bool DeleteExistingFile = false)
{
var Dir = Path.GetDirectoryName(FullFilePath) + Path.DirectorySeparatorChar;
var FileName = Path.GetFileNameWithoutExtension(FullFilePath);
var Ext = Path.GetExtension(FullFilePath);
var NewFullFilePath = Dir + FileName + $"_{Counter}" + Ext;
try
{
if (!Directory.Exists(Dir))
Directory.CreateDirectory(Dir);
}
catch
{
return string.Empty;
}
if (File.Exists(NewFullFilePath))
{
if (DeleteExistingFile)
try
{
File.Delete(NewFullFilePath);
}
catch
{
return string.Empty;
}
else
return string.Empty;
}
return NewFullFilePath;
}