SourceCode/PROMS/LBWordLibrary/LBObjectExtension.cs
2011-06-16 10:25:28 +00:00

744 lines
24 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace LBWordLibrary
{
public partial class LBApplicationClass : LBComObject
{
/// <summary>
/// This gives the option of specifying Background = false to print in the foreground.
/// </summary>
/// <param name="Background">boolean BackGround
/// If true - document will be printed in the background
/// If false - document will be printed in the foreground</param>
public void PrintOut(Boolean Background)
{
InvokeMethod("PrintOut", Background, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
}
public void Quit(bool save)
{
InvokeMethod("Quit", save, Missing.Value, Missing.Value);
}
public bool VolianPDFInstalled
{
get
{
foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
if (printer == "VolianPDF Writer") return true;
return false;
}
}
public bool WordPDFExporterInstalled
{
get
{
// this is for ExportAsFixedFormat MSOffice AddIn
RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"Installer\Components\12B306B24E250DD428FC7016B6FB4BD8");
if (key != null)
{
key.Close();
return true;
}
return false;
}
}
private bool CanCreatePDFFile(string pdfFileName)
{
System.IO.FileInfo file = new System.IO.FileInfo(pdfFileName);
if (!file.Exists) return true;
try
{
file.Delete();
return true;
}
catch (System.IO.IOException exio)
{
if (exio.Message.StartsWith("The process cannot access the file")) return false;
throw new Exception(string.Format("Cannot Delete PDF file {0}", pdfFileName), exio);
}
catch (Exception ex)
{
throw new Exception(string.Format("Cannot Delete PDF file {0}", pdfFileName), ex);
}
}
private string AvailableFileName(string pdfFileName)
{
if (CanCreatePDFFile(pdfFileName)) return pdfFileName;
string prefix = pdfFileName.Replace(".pdf", "");
for (int i = 1; i < 1000; i++)
{
string newname = string.Format("{0}_{1:000}.PDF", prefix, i);
if (CanCreatePDFFile(newname)) return newname;
}
throw new Exception("Cannot find a name to use");
}
public string CreatePDF(string pdfFileName, bool openPDF)
{
pdfFileName = CreatePDF(pdfFileName);
if (openPDF) OpenPDF(pdfFileName);
return pdfFileName;
}
static List<System.Diagnostics.Process> _AcrobatProcesses=new List<System.Diagnostics.Process>();
private static void OpenPDF(string pdfFileName)
{
_AcrobatProcesses.Add(System.Diagnostics.Process.Start(pdfFileName));
}
public static void ClosePDFs()
{
foreach(System.Diagnostics.Process proc in _AcrobatProcesses)
if (!proc.HasExited)
KillAndWait(proc);
}
private static void KillAndWait(System.Diagnostics.Process proc)
{
Console.WriteLine("{0:s.ffff} Killing Adobe", DateTime.Now);
DateTime tStart = DateTime.Now;
proc.Kill();
DateTime tEnd = DateTime.Now.AddMilliseconds(100);
while (DateTime.Now < tEnd)
{
Application.DoEvents();
}
Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss.ffff} {1:yyyy-MM-dd HH:mm:ss.ffff} {2}", DateTime.Now, proc.ExitTime
,TimeSpan.FromTicks(proc.ExitTime.Ticks - tStart.Ticks).TotalMilliseconds);
}
public string CreatePDF(string pdfFileName)
{
pdfFileName = AvailableFileName(pdfFileName);
if (Convert.ToSingle(Version) >= 12.0F && WordPDFExporterInstalled)
return CreatePDF2007(pdfFileName);
else if (VolianPDFInstalled)
return CreatePDF2003BG(pdfFileName);
else
throw new Exception("No PDF Writer support installed for MS Word sections");
}
public string CreatePDF2003FG(string pdfFileName, bool openPDF)
{
pdfFileName = CreatePDF2003FG(pdfFileName);
if (openPDF) OpenPDF(pdfFileName);
return pdfFileName;
}
public string CreatePDF2003FG(string pdfFileName)
{
pdfFileName = AvailableFileName(pdfFileName);
if (!VolianPDFInstalled)
throw new Exception("VolianPDF Writer is not installed properly");
try
{
string printer = ActivePrinter;
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\VolianPDF Writer");
key.SetValue("OutputFile", pdfFileName, RegistryValueKind.String);
key.SetValue("BypassSaveAs", "1", RegistryValueKind.String);
key.Close();
ActivePrinter = "VolianPDF Writer";
PrintOut(false);
ActivePrinter = printer;
Registry.CurrentUser.DeleteSubKeyTree(@"Software\VolianPDF Writer");
return pdfFileName;
}
catch (Exception ex)
{
throw new Exception("Error creating PDF - LBApplicationClass.CreatePDF2003FG", ex);
}
}
public string CreatePDF2003BG(string pdfFileName, bool openPDF)
{
pdfFileName = CreatePDF2003BG(pdfFileName);
if (openPDF) OpenPDF(pdfFileName);
return pdfFileName;
}
public string CreatePDF2003BG(string pdfFileName)
{
pdfFileName = AvailableFileName(pdfFileName);
if (!VolianPDFInstalled)
throw new Exception("VolianPDF Writer is not installed properly");
try
{
string printer = ActivePrinter;
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\VolianPDF Writer");
key.SetValue("OutputFile", pdfFileName, RegistryValueKind.String);
key.SetValue("BypassSaveAs", "1", RegistryValueKind.String);
key.Close();
ActivePrinter = "VolianPDF Writer";
PrintOut(true);
do
{
// Console.WriteLine("Background Printing Status = {0}", _MyApp.BackgroundPrintingStatus);
Application.DoEvents();
} while (BackgroundPrintingStatus == 1);
ActivePrinter = printer;
Registry.CurrentUser.DeleteSubKeyTree(@"Software\VolianPDF Writer");
return pdfFileName;
}
catch (Exception ex)
{
throw new Exception("Error creating PDF - LBApplicationClass.CreatePDF2003BG", ex);
}
}
public string CreatePDF2007(string pdfFileName, bool openPDF)
{
pdfFileName = CreatePDF2007(pdfFileName);
if (openPDF) OpenPDF(pdfFileName);
return pdfFileName;
}
public string CreatePDF2007(string pdfFileName)
{
pdfFileName = AvailableFileName(pdfFileName);
if (!WordPDFExporterInstalled)
throw new Exception("MS Word PDF Exporter is not installed");
try
{
ActiveDocument.ExportAsFixedFormat(pdfFileName, LBWdExportFormat.wdExportFormatPDF);
return pdfFileName;
}
catch (Exception ex)
{
throw new Exception("Error creating PDF - LBApplicationClass.CreatePDF2007", ex);
}
}
}
public partial class LBDocuments
{
public LBDocumentClass Open(string fileName, Boolean addToRecentFiles)
{
return Open(fileName, Missing.Value, Missing.Value, addToRecentFiles);
}
private LBDocumentClass Open(params object[] myParams)
{
return new LBDocumentClass(InvokeMethod("Open", myParams));
}
}
public partial class LBDocumentClass : LBComObject
{
public void SaveAs2000(string fileName)
{
if (fileName.ToUpper().EndsWith("DOC"))
SaveAs2000(fileName, LBWdSaveFormat.wdFormatDocument);
else if (fileName.ToUpper().EndsWith("RTF"))
SaveAs2000(fileName, LBWdSaveFormat.wdFormatRTF);
else
SaveAs2000(fileName);
}
public void SaveAs2000(params object[] myParams)
{
InvokeMethod("SaveAs2000", myParams);
}
public void SaveAs(string fileName)
{
if (fileName.ToUpper().EndsWith("DOC"))
SaveAs2(fileName, LBWdSaveFormat.wdFormatDocument, Missing.Value, Missing.Value, false);
else if (fileName.ToUpper().EndsWith("RTF"))
SaveAs2(fileName, LBWdSaveFormat.wdFormatRTF, Missing.Value, Missing.Value, false);
else if (fileName.ToUpper().EndsWith("TXT"))
SaveAs2(fileName, LBWdSaveFormat.wdFormatDOSText, Missing.Value, Missing.Value, false);
else if (fileName.ToUpper().EndsWith("DOCX"))
SaveAs2(fileName, LBWdSaveFormat.wdFormatXMLDocument, Missing.Value, Missing.Value, false);
else
SaveAs2(fileName, Missing.Value, Missing.Value, Missing.Value, false);
}
public void SaveAs2(params object[] myParams)
{
InvokeMethod("SaveAs", myParams);
}
public void SaveAs(string fileName, LBWdSaveFormat format)
{
SaveAs2(fileName, format, Missing.Value, Missing.Value, false);
}
public LBRange Range(int Start, int End)
{
return new LBRange(InvokeMethod("Range", Start, End));
}
/// <summary>
/// Length is Pages and Partial Pages
/// The integral part is the number of full pages
/// The decimal part is the size of the last page divided by 7200
/// (the first two digits should be the number of inches)
/// </summary>
public float Length
{
get
{
ActiveWindow.ActivePane.View.Type = LBWdViewType.wdPrintView;
ActiveWindow.View.Type = LBWdViewType.wdPrintView;
LBPages myPages = ActiveWindow.ActivePane.Pages;// Start with pages
float retval = (float)myPages.Count - 1;
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
float partial = (float) myRange.get_Information(LBWdInformation.wdVerticalPositionRelativeToTextBoundary);
partial += myRange.Font.Size;
retval += partial / 7200;
return retval;
}
}
public string Ascii
{
get
{
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
myRange.Start = 0;
return ReplaceSymbolCharacters(GetRangeText(myRange));
}
}
private static string[] SymbolFontName = { "VolianDraw", "WingDings", "VESymb", "VESymbFix", "Symbol" };
private static bool IsSymbolFont(string fontName)
{
foreach (string symbolFont in SymbolFontName)
if (fontName.ToUpper().StartsWith(symbolFont.ToUpper()))
return true;
return false;
}
/// <summary>
/// If document contains symbol characters, returns problem font.
/// </summary>
public string FontHasSymbolCharacters
{
get
{
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
myRange.Start = 0;
int end = myRange.End;
string myText = GetRangeText(myRange);
//return _RegFindSymbol.IsMatch(myText);
MatchCollection problems = _RegFindSymbol.Matches(myText);
int offset = 0;
foreach (Match problem in problems)
{
myRange.Start = problem.Index + offset;
myRange.End = problem.Index + problem.Length + offset;
int newOffset = FindRangeOffset(myRange, problem, offset, end);
if (IsSymbolFont(myRange.Font.Name))
{
Console.WriteLine("Font '{0}' has Symbols", myRange.Font.Name);
//return true;
}
else
return myRange.Font.Name;
offset = newOffset;
}
return null;
}
}
/// <summary>
/// Debug Tool - Return a string containing a list of the fonts that have symbol characters.
/// </summary>
public string FontsHaveSymbolCharacters
{
get
{
string sep = "";
StringBuilder sb = new StringBuilder();
List<string> fonts=new List<string>();
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
myRange.Start = 0;
int end = myRange.End;
string myText = GetRangeText(myRange);
//return _RegFindSymbol.IsMatch(myText);
MatchCollection problems = _RegFindSymbol.Matches(myText);
int offset = 0;
foreach (Match problem in problems)
{
myRange.Start = problem.Index + offset;
myRange.End = problem.Index + problem.Length + offset;
int newOffset = FindRangeOffset(myRange, problem, offset, end);
if (!fonts.Contains(myRange.Font.Name))
{
fonts.Add(myRange.Font.Name);
sb.Append(sep + "'" + myRange.Font.Name + "'");
sep = ",";
}
offset = newOffset;
}
if (sb.Length > 0) return sb.ToString();
return null;
}
}
/// <summary>
/// Debug Tool - Return a list of symbol characters using VESYMB font.
/// </summary>
public string FontsHaveSymbolCharacters2
{
get
{
try
{
Dictionary<string, List<int>> fonts = new Dictionary<string, List<int>>();
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
myRange.Start = 0;
int end = myRange.End;
string myText = GetRangeText(myRange);
//return _RegFindSymbol.IsMatch(myText);
MatchCollection problems = _RegFindSymbol.Matches(myText);
int offset = 0;
foreach (Match problem in problems)
{
myRange.Start = problem.Index + offset;
myRange.End = problem.Index + problem.Length + offset;
int newOffset = FindRangeOffset(myRange, problem, offset, end);
string sFont = myRange.Font.Name;
if (sFont.ToUpper().StartsWith("VESYM"))
{
if (!fonts.ContainsKey(sFont))
{
fonts.Add(sFont, new List<int>());
}
List<int> symbols = fonts[sFont];
string myTextSymb = GetRangeText(myRange);
foreach (char c in myTextSymb)
{
if (!symbols.Contains((int)c))
symbols.Add((int)c);
}
}
offset = newOffset;
}
if (fonts.Count > 0)
{
string sep = "";
StringBuilder sb = new StringBuilder();
foreach (string font in fonts.Keys)
{
sb.Append(sep + "'" + font + "'");
sep = ",";
foreach (int i in fonts[font])
{
sb.Append(sep);
sb.Append(i);
}
}
return sb.ToString();
}
}
catch (Exception ex)
{
Console.WriteLine("{0},{1},{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
}
return null;
}
}
/// <summary>
/// Checks to see if the document contains symbol characters
/// </summary>
/// <returns></returns>
public bool HasSymbolCharacters
{
get
{
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
myRange.Start = 0;
int end = myRange.End;
string myText = GetRangeText(myRange);
//return _RegFindSymbol.IsMatch(myText);
MatchCollection problems = _RegFindSymbol.Matches(myText);
int offset = 0;
foreach (Match problem in problems)
{
myRange.Start = problem.Index + offset;
myRange.End = problem.Index + problem.Length + offset;
int newOffset = FindRangeOffset(myRange, problem, offset, end);
if (IsSymbolFont(myRange.Font.Name))
{
Console.WriteLine("Font '{0}' has Symbols", myRange.Font.Name);
//return true;
}
else
return true;
offset = newOffset;
}
return false;
}
}
Regex _RegFindSymbol = new Regex("[\\uF000-\\uF0FF]+");
/// <summary>
/// FixSymbolCharacters - Fix any symbol characters in the document
/// </summary>
public void FixSymbolCharacters()
{
// Set up range object to be used to process text
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
int end = myRange.End;
myRange.Start = 0;
string myText = GetRangeText(myRange);
MatchCollection problems = _RegFindSymbol.Matches(myText);
int offset = 0;
foreach (Match problem in problems)
{
myRange.Start = problem.Index + offset;
myRange.End = problem.Index + problem.Length + offset;
int newOffset = FindRangeOffset(myRange, problem, offset, end);
ReplaceSymbolCharacters(myRange);
offset = newOffset;
}
}
/// <summary>
/// Try to fix the first character in the symbol range F000 to F0FF. If it cannot be
/// fixed, it is an indicator that the font is not installed properly. Regardless of
/// whether there is success, the change is undone so that the document will not be
/// considered dirty, i.e. will not prompt user for save.
/// </summary>
/// <returns></returns>
public bool AttemptToFixASymbolCharacter()
{
// Set up range object to be used to process text
LBRange myRange = Range();
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
int end = myRange.End;
myRange.Start = 0;
string myText = GetRangeText(myRange);
MatchCollection problems = _RegFindSymbol.Matches(myText);
if (problems.Count>0)
{
Match problem = problems[0];
myRange.Start = problem.Index;
myRange.End = myRange.Start + 1;
if (IsSymbolFont(myRange.Font.Name)) return true; // if it's a symbol font already, no issue.
string before = GetRangeText(myRange);
string updated = ReplaceSymbolCharacters(before);
myRange.Text = updated;
string after = GetRangeText(myRange);
Undo(1);
//Console.WriteLine("Undo1 results = {0}", tst);
//tst = Undo(1);
//Console.WriteLine("Undo2 results = {0}", tst);
//tst = Undo(1);
//Console.WriteLine("Undo3 results = {0}", tst);
return (updated == after);
}
return true;
}
/// <summary>
/// Get the Range Text with error handling. myRange.Text sometimes will get a null reference exception.
/// </summary>
/// <param name="myRange"></param>
/// <returns></returns>
internal static string GetRangeText(LBRange myRange)
{
string text="";
try
{
if (myRange.Start == myRange.End)// If Start and End equal return an empty string.
text = "";
else
text = myRange.Text;
}
catch (Exception ex)
{
Console.WriteLine("GetRangeText {0} - {1}", ex.GetType().Name, ex.Message);
}
return text;
}
/// <summary>
/// Looks for the problem string and adjusts the range as necessary
/// </summary>
/// <param name="myRange"></param>
/// <param name="problem"></param>
/// <param name="offset"></param>
/// <param name="end"></param>
/// <returns></returns>
private int FindRangeOffset(LBRange myRange, Match problem, int offset, int end)
{
// try to find the string
string text = GetRangeText(myRange);
if (text != problem.Value)
{
// Get the entire text starting at the offset of the first match
myRange.Start = problem.Index + offset;
myRange.End = end;
text = GetRangeText(myRange);
while (!text.StartsWith(problem.Value))
{
int newStart = text.IndexOf(problem.Value);// Find the string if it is not at the beginning
myRange.Start += myRange.Start == newStart ? newStart + 1 : newStart; // adjust the starting location
text = GetRangeText(myRange);// get the text to check
}
myRange.End = myRange.Start + problem.Length; // assume that the end should be the start plus the length
text = GetRangeText(myRange);
while (text.Length < problem.Length) // If the result is too short increase the length
{
myRange.End += (problem.Length - text.Length);
text = GetRangeText(myRange);
}
}
return myRange.Start - problem.Index;
}
/// <summary>
/// ReplaceSymbolCharacters Replaces any symbol characters in the specified range
/// </summary>
/// <param name="myRange"></param>
private static void ReplaceSymbolCharacters(LBRange myRange)
{
try
{
if (IsSymbolFont(myRange.Font.Name))
return;
string before = GetRangeText(myRange);
string updated = ReplaceSymbolCharacters(before);
myRange.Text = updated;
string after = GetRangeText(myRange);
if (after != updated) // If the Word text doesn't match try including a character before and after and do it again.
{
Console.WriteLine("'TryEntireRange Failed',{0},{1},'{2}','{3}','{4}'", myRange.Start, myRange.End, before, updated, after);
int end = myRange.End;
myRange.Start = myRange.Start - 1;
myRange.End = end + 1;
myRange.Text = ReplaceSymbolCharacters(GetRangeText(myRange));
Console.WriteLine("'TryEntireRange Failed',{0},{1},'{2}'", myRange.Start, myRange.End, GetRangeText(myRange));
}
}
catch (Exception ex)
{
Console.WriteLine("'TryEntireRange Exception',{0},{1},'{2}'", myRange.Start, myRange.End, ex.Message);
}
}
/// <summary>
/// ReplaceSymbolCharacters processes the string returned and changes any symbols (0xF0??) to normal characters
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private static string ReplaceSymbolCharacters(string str)
{
StringBuilder results = new StringBuilder();
foreach (char c in str)
{
if ((c & 0xFF00) == 0xF000)
results.Append((char)(c & 0xFF));
else
results.Append((char)(c));
}
return results.ToString();
}
/// <summary>
/// Close the document
/// </summary>
/// <param name="SaveChanges">Save Changes</param>
public void Close(bool SaveChanges)
{
InvokeMethod("Close", SaveChanges, Missing.Value, Missing.Value);
}
}
public partial class LBFind
{
public void ReplaceAll()
{
this.Execute(Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, LBWdReplace.wdReplaceAll, Missing.Value,
Missing.Value, Missing.Value, Missing.Value);
}
}
public partial class LBFontClass : LBComObject
{
public int TextColor
{
get { return (int)GetProperty("Color"); }
set { SetProperty("Color", value); }
}
}
public partial class LBRange : LBComObject
{
public Object get_Information(LBWdInformation info)
{
return GetProperty("Information", info);
}
public LBRange GoTo(LBWdGoToItem What, LBWdGoToDirection Which, int Count)
{
return new LBRange(InvokeMethod("GoTo", What, Which, Count, Missing.Value));
}
}
public partial class LBSelection : LBComObject
{
public Object get_Information(LBWdInformation info)
{
return GetProperty("Information", info);
}
public int MoveStart(LBWdUnits Unit, int Count)
{
return InvokeMethod("MoveStart", Unit, Count) as int? ?? 0;
}
public int MoveEnd(LBWdUnits Unit, int Count)
{
return InvokeMethod("MoveEnd", Unit, Count) as int? ?? 0;
}
public int EndKey(LBWdUnits Unit, bool Extend)
{
return InvokeMethod("EndKey", Unit, Extend) as int? ?? 0;
}
public bool LastWasUpper
{
get
{
LBRange myRange = Range;
int start = myRange.Start - 1;
while (start >= 0)
{
myRange.Start = start;
myRange.End = start + 1;
string previous = LBDocumentClass.GetRangeText(myRange);
if (Regex.IsMatch(previous, "[A-Z]")) return true;
if (Regex.IsMatch(previous, "[a-z]")) return false;
start = start - 1;
}
return false;
}
}
}
public partial class LBInlineShapes : LBComObjectList<LBInlineShapes, LBInlineShape> /* Collection */
{
public LBInlineShape AddPicture(string FileName, LBRange Range)
{
return new LBInlineShape(InvokeMethod("AddPicture", FileName, false, true, Range));
}
}
public partial class LBShapes : LBComObjectList<LBShapes, LBShape> /* Collection */
{
public LBShape AddPicture(string FileName, float Left, float Top, LBRange Anchor)
{
return new LBShape(InvokeMethod("AddPicture", FileName, false, true, Left, Top, Missing.Value, Missing.Value, Anchor));
}
public LBShape AddPicture(string FileName, float Left, float Top)
{
return new LBShape(InvokeMethod("AddPicture", FileName, false, true, Left, Top, Missing.Value, Missing.Value, Missing.Value));
}
}
public enum LBMsoTriState
{
msoCTrue = 1,
msoFalse = 0,
msoTriStateMixed = -2,
msoTriStateToggle = -3,
msoTrue = -1
}
//public partial class ProcessKiller
//{
// System.Diagnostics.Process _MyProcess;
// private bool _Exited = false;
// public ProcessKiller(System.Diagnostics.Process myProcess)
// {
// _MyProcess = myProcess;
// _MyProcess.Exited += new EventHandler(_MyProcess_Exited);
// _MyProcess.Kill();
// DateTime next = DateTime.Now.AddMilliseconds(200);
// while (DateTime.Now < next)
// Application.DoEvents();
// while (!_Exited)
// Application.DoEvents();
// }
// void _MyProcess_Exited(object sender, EventArgs e)
// {
// Console.WriteLine("Exited");
// _Exited = true;
// }
//}
}