I am trying to programmatically open a file in notepad++ using SendMessage but I'am having no luck.
I figured that because I can drag and drop a file onto Notepad++ and it will open it, that a SendMessage would work.
Declarations:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
Method:
I launch Notepad++ using Process.Start:
IntPtr cHwnd = FindWindowEx(pDocked.MainWindowHandle, IntPtr.Zero, "Scintilla", null);
SendMessage(cHwnd, WM_SETTEXT, 0, "C:\Users\nelsonj\Desktop\lic.txt");
When SendMessage executes it will send my text into the 'edit' section of Notepad++ instead of opening the file.
Any help would be great.
If you simply want to open a file in Notepad++, you can just start a new Process:
set the path of the file you want to open to the Arguments property of the ProcessStartInfo class.
the FileName property is set to the path of the program you want to open.
UseShellExecute and CreateNoWindow are irrelevant here, leave the default.
using System.Diagnostics;
Process process = new Process();
ProcessStartInfo procInfo = new ProcessStartInfo()
{
FileName = #"C:\Program Files\Notepad++\notepad++.exe",
Arguments = Path.Combine(Application.StartupPath, "[Some File].txt"),
};
process.StartInfo = procInfo;
process.Start();
if (process != null) process.Dispose();
Related
Is it possible to close an excel file when it is already open? I have written a code that can determine if a specific excel file is already open, however I cannot close the file once it has been determined to be open. I have tried the following method (see below) to close a workbook and excel application:
// The name of my workbook is "workbook", while the Excel application is named "excel."
workbook.Close(true);
excel.Quit();
Performing the latter code does not close the already open Excel window. It may also be of assistance to know the code I am using to determine if a file is open (it is provided below):
// The following checks to see if a file is open and returns truth1 as "true" if the file is open and "false" if the file is closed.
file = new FileInfo(file_name);
truth1 = IsFileinUse(file);
// ...
protected static bool IsFileinUse(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
Again, I cannot create a program in which I "kill Excel". I just need know how to close an already open Excel window if its path is the same as the one I am trying to read and write to.
Please have a look on below sample code :-
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application exl = new Excel.Application();
# open a file
Excel.Workbook wbook = exl.Workbooks.Open("some_file.xlsx");
# To close the file
wbook.Close();
exl.Quit();
Edit 1:-
You can refer below link if above solution not works for you :-
Closing an Excel Workbook
You can use the Windows API, to close a certain Window by it's title.
This will invoke a Window-Close, so it will prompt the user if he really wants to close:
using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
const UInt32 WM_CLOSE = 0x0010;
And then
IntPtr windowPtr = FindWindowByCaption(IntPtr.Zero, "MyFile.xlsx - Excel");
if (windowPtr == IntPtr.Zero)
{
MessageBox.Show("Document not open");
return;
}
SendMessage(windowPtr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
If you need to force a close, even if the file has been modified, you only can kill the related excel-process. But keep in mind that this will forcefully kill other excel-windows as well, if they are running within the same excel-process-instance.
using System.Diagnostics;
...
Process[] processes = Process.GetProcesses();
foreach (Process p in processes)
{
if (p.MainWindowTitle == "MyFile.xlsx - Excel")
{
p.Kill();
break;
}
}
While working on a project of mine. I found the need to have the normal console aplication for changing numbers and putting them out. I found out a post that made that pretty easy, but it doesn't output anything. it opens the console aplication and the name changes, but there is no output.
This is what i use to open it
[DllImport("kernel32")]
static extern bool AllocConsole();
private void UseConsole(object sender)
{
AllocConsole();
Console.Title = "Output";
Console.Write("hello world");
}
If you know what might help to get an output. that would be great
Thanks already
Dan
I had the same problem when trying to create a console with my XNA/FNA application. All the common solutions found didn't worked: the written console lines were printed into the "Output" window of Visual Studio (Community), but when the application was started by executing the game directly (outside of Visual Studio), the console window remained empty. The following answer on a similar question worked for me: https://stackoverflow.com/a/34170767 by https://stackoverflow.com/users/1087922/zunair
The copied code:
using System;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace WindowsApplication
{
static class Program
{
[DllImport("kernel32.dll",
EntryPoint = "GetStdHandle",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll",
EntryPoint = "AllocConsole",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int AllocConsole();
private const int STD_OUTPUT_HANDLE = -11;
private const int MY_CODE_PAGE = 437;
static void Main(string[] args)
{
Console.WriteLine("This text you can see in debug output window.");
AllocConsole();
IntPtr stdHandle=GetStdHandle(STD_OUTPUT_HANDLE);
SafeFileHandle safeFileHandle = new SafeFileHandle(stdHandle, true);
FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write);
Encoding encoding = System.Text.Encoding.GetEncoding(MY_CODE_PAGE);
StreamWriter standardOutput = new StreamWriter(fileStream, encoding);
standardOutput.AutoFlush = true;
Console.SetOut(standardOutput);
Console.WriteLine("This text you can see in console window.");
MessageBox.Show("Now I'm happy!");
}
}
}
In C#, you can specify a filter on an OpenFileDialog object.
var dlg = new OpenFileDialog();
dlg.DefaultExt = ".xml";
dlg.Filter = "XML Files|*.xml";
Is there a way to automatically select files by name? For example, if I navigated to a folder of xml files, is there any filtering option that would automatically target "myxml.xml"?
Yes, just set the FileName property of the OpenFileDialog like this:
dlg.FileName = "myxml.xml";
However, it would be more appropriate if you use the name in the filter. Just place it instead of the star which acts as a wildcard:
dlg.Filter = "XML Files|myxml.xml";
And always remember you can have multiple filters like this: (It may be useful in the future):
"Image Files (*.bmp, *.jpg)|*.bmp;*.jpg"
// -- OR --
"Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
More documentation on filters at MSDN.
Yes, you can actually set the filter to a complete filename:
dlg.Filter = "myxml Files|myxml.xml";
Note that when this filter is selected, you won't be able to select other XML files. If you simply want to default to that filename while showing and allowing selection of any XML file, go with Fᴀʀʜᴀɴ Aɴᴀᴍ's (original) answer. And now that he copied my answer into his, you can just go with his.
What you can do is either set the FileName property like this:
dlg.FileName = "myxml.xml";
or set the Filter property like this:
dlg.Filter = "XML files|file.xml";
(it's important to check that there's no space at the end like this "file.xml ", because if there is, your file won't show up, in other words OpenFileDialog doesn't trim the Filter property)
if you don't know what the file name is beforehand, you can use DirectoryInfo and FileInfo like this:
DirectoryInfo dir = new DirectoryInfo("PATHHERE");
FileInfo[] files = dir.GetFiles();
and loop through the files to find the one you are looking for
Step 1: Add this method to your code:
[DllImport("shell32.dll", SetLastError = true)]
public static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags);
[DllImport("shell32.dll", SetLastError = true)]
public static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, [Out] out IntPtr pidl, uint sfgaoIn, [Out] out uint psfgaoOut);
public static void OpenFolderAndSelectItem(string folderPath, string file)
{
IntPtr nativeFolder;
uint psfgaoOut;
SHParseDisplayName(folderPath, IntPtr.Zero, out nativeFolder, 0, out psfgaoOut);
if (nativeFolder == IntPtr.Zero)
return;
IntPtr nativeFile;
SHParseDisplayName(System.IO.Path.Combine(folderPath, file), IntPtr.Zero, out nativeFile, 0, out psfgaoOut);
IntPtr[] fileArray;
if (nativeFile == IntPtr.Zero)
{
fileArray = new IntPtr[0];
}
else
{
fileArray = new IntPtr[] { nativeFile };
}
SHOpenFolderAndSelectItems(nativeFolder, (uint)fileArray.Length, fileArray, 0);
Marshal.FreeCoTaskMem(nativeFolder);
if (nativeFile != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(nativeFile);
}
}
Step 2: Call the method OpenFolderAndSelectItem(string folderPath, string file) to use.
Step 3: Enjoy!
Before you go on and flag my question as a duplicate, believe me, its
not. I have gone through virtually every solution provided here and I
still can't get to get my app to work, so please will you just be nice
and take some time to help me.
Scenario: I have a Zebra RW 420 thermal printer which I would like to use for printing vouchers with a QR Code on them. I am using C# and have followed all the help as given by Scott Chamberlain here and the code here for sending the commands to the printer. I have the EPL2 manual as well as the CPCL, and ZPL reference manuals with a whole lot of stuff on how to format my commands.
Problem:
All the commands I am sending are either printing as plain text replicas of the commands or the printer just hangs with the small message icon showing on its display. I have tried sending the same commands using the Zebra Utilitis and still getting the same result as with my sample app.
Below is the code snippets I have, please do advise me if there are any reference libraries I may require to get this to work.
private void btnPrint_Click(object sender, RoutedEventArgs e)
{
string s = "! 0 200 200 500 1\nB QR 10 100 M 2 U 10\nMA,QR code ABC123\nENDQR\nFORM\nPRINT";
// Have also tried \r\n for the line feeds with the same result.
// Allow the user to select a printer.
PrintDialog pd = new PrintDialog();
if ((bool)pd.ShowDialog())
{
var bytes = Encoding.ASCII.GetBytes(s);
// Send a printer-specific to the printer.
RawPrinterHelper.SendBytesToPrinter(pd.PrintQueue.FullName, bytes, bytes.Length);
}
}
PrinterHelper class as modified by Scott here
public class RawPrinterHelper
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)] public string pDocName;
[MarshalAs(UnmanagedType.LPStr)] public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)] public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter,
IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level,
[In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, Int32 dwCount, out Int32 dwWritten);
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter(string szPrinterName, byte[] pBytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed.
di.pDocName = "Zebra Label";
di.pDataType = "RAW";
// Open the printer.
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
// Start a document.
if (StartDocPrinter(hPrinter, 1, di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
throw new Win32Exception(dwError);
}
return bSuccess;
}
}
I did a lot of work on Zebra ZT230 and GX430t printers last year, and the thing I found out about them was using the ZPL instructions over TCP sockets via port 9100 was a LOT more reliable.
I know this is taking your conversation in a very different direction, but having tried the spool / Win32 approach I can tell you using sockets was a lot more reliable. Let me know if you need some sample code.
Wrote a kiosk application using a KR403 last year. I was able to
successfully print and poll the status of the printer to see if there
was a paper jam low paper etc via usb using the blog post below.
http://danielezanoli.blogspot.com/2010/06/usb-communications-with-zebra-printers.html
Using print spooler (Print only)
https://sharpzebra.codeplex.com/SourceControl/latest#src/Com.SharpZebra/Printing/RawPrinter.cs
I used the ZebraDesigner to do my initial layout. On the print screen
inside the zebra designer there is a print to file option that will
save your design as a txt file with ZPL in it. I then took that file
broke it up into sections and created a helper class that uses a
StringBuilder internally so I could focus on certain pieces of the zpl
since it can be overwhelming to look at more than 1-2 lines.
var kioskTicketBuilder = new KioskTicketBuilder();
kioskTicketBuilder.SetPrinterDefaults();
kioskTicketBuilder.DisplayTicketHeader();
kioskTicketBuilder.DisplayInformationHeading(data.Name, data.todaysDate, data.ClientName, data.ClientCode);
kioskTicketBuilder.DisplayMoreStuff()
kioskTicketBuilder.DisplayBarcode(data.TrackingId);
kioskTicketBuilder.EndOfJob();
return kioskTicketBuilder.GetPrintJobToArray();
Also if you go to the the printer properties > Printing Defaults > Tools
Tab There is an option to send a file of zpl to the printer or send
individual commands. This is really good for testing your zpl seperate
from your application.
I am using the code on http://support.microsoft.com/kb/322091 to send raw data to a USB printer.
This doc only explains how to send data, but some printers do also report data back.
I am wondering if it would be possible to extend that code, so it would also raise an event on received data from the printer. I don't know though if that's possible at all based on extension of that code.
//something like
[DllImport("winspool.Drv", EntryPoint = "ReadPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ReadPrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwRead);