How are assemblies located and loaded in .NET 5+? - .net-assembly

I am currently elaborating which content I should use in the different version numbers, so I read What are differences between AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion? and many other posts and articles.
Based on SemVer, I would increase the minor version number if I make backwards compatible changes. I understand and like this concept, and I want to use it.
This answer on the above linked post has good explanations on the different version numbers, but it also says that changing AssemblyVersion would require recompiling all dependent assemblies and executables.
I did a quick test:
testVersionLib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>abc.snk</AssemblyOriginatorKeyFile>
<AssemblyVersion>3.4.5.6</AssemblyVersion>
</PropertyGroup>
</Project>
project testVersionLib: class1.cs
using System;
namespace testVersionLib
{
public class Class1
{
public string m_versionText = "3.4.5.6";
}
}
project testVersionExe: program.cs
using System;
using System.Diagnostics;
namespace testVersionExe
{
class Program
{
static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
PrintFileVersion ();
PrintAssemblyFullName ();
}
private static void PrintAssemblyFullName ()
{
Console.WriteLine ("m_versionText: " + new testVersionLib.Class1 ().m_versionText);
Console.WriteLine ("DLL Assembly FullName: " + System.Reflection.Assembly.GetAssembly (typeof (testVersionLib.Class1)).FullName);
}
private static void PrintFileVersion ()
{
Console.WriteLine ("DLL FileVersion: " + FileVersionInfo.GetVersionInfo ("testVersionLib.dll").FileVersion);
}
}
}
and found that this may apply to .Net Framework, but it obviously does not apply to .NET 5 (and most likely .NET 6 and above as well, and maybe previous versions of .NET Core): I created a .NET 5 C# console app with AssemblyVersion 1.2.3.4 and strong name. This EXE references a DLL with AssemblyVersion 3.4.5.6 and strong name. The DLL compiled with different versions and is placed in the EXE's folder without compiling that one again.
The results:
The EXE fails to start if the DLL version is below 3.4.5.6 (e.g. 3.4.5.5, 3.4.4.6, 3.3.5.6), which makes sense.
The EXE successfully runs if the DLL version is equal to or above the version that was used to created the app (equal: 3.4.5.6; above: 3.4.5.7, 3.4.6.6, 3.5.5.6, 4.4.5.6).
This answer only says that
[...] .Net 5+ does not (by default) require that the assembly version used at runtime match the assembly version used at build time.
but it does not explain why and how.
How are assemblies located, resolved and loaded in .NET 5?
If someone wants to repeat my test with the compiled files, here's the 7z archive, encoded as PNG:
To decode the image, save it as PNG and use this code:
static void Main (string[] args)
{
string dataPath = #"c:\temp\net5ver.7z";
string imagePath = #"c:\temp\net5ver.7z.png";
string decodedDataPath = #"c:\temp\net5ver.out.7z";
int imageWidth = 1024;
Encode (dataPath, imagePath, imageWidth);
Decode (imagePath, decodedDataPath);
}
public static void Decode (string i_imagePath, string i_dataPath)
{
var bitmap = new Bitmap (i_imagePath);
var bitmapData = bitmap.LockBits (new Rectangle (Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
byte[] dataLengthBytes = new byte[4];
Marshal.Copy (bitmapData.Scan0, dataLengthBytes, 0, 4);
int dataLength = BitConverter.ToInt32 (dataLengthBytes);
int imageWidth = bitmap.Width;
int dataLines = (int)Math.Ceiling (dataLength / (double)imageWidth);
if (bitmap.Height != dataLines + 1)
throw new Exception ();
byte[] row = new byte[imageWidth];
List<byte> data = new();
for (int copyIndex = 0; copyIndex < dataLines; copyIndex++)
{
int rowStartIndex = imageWidth * (copyIndex + 1);
Marshal.Copy (IntPtr.Add (bitmapData.Scan0, rowStartIndex), row, 0, row.Length);
data.AddRange (row.Take (dataLength - data.Count));
}
bitmap.UnlockBits (bitmapData);
System.IO.File.WriteAllBytes (i_dataPath, data.ToArray ());
}
public static void Encode (string i_dataPath,
string i_imagePath,
int i_imageWidth)
{
byte[] data = System.IO.File.ReadAllBytes (i_dataPath);
int dataLines = (int)Math.Ceiling (data.Length / (double)i_imageWidth);
int imageHeight = dataLines + 1;
var bitmap = new Bitmap (i_imageWidth, imageHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
var palette = bitmap.Palette;
for (int index = 0; index < byte.MaxValue; index++)
palette.Entries[index] = Color.FromArgb (index, index, index);
bitmap.Palette = palette;
var bitmapData = bitmap.LockBits (new Rectangle (Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat);
Marshal.Copy (BitConverter.GetBytes (data.Length), 0, bitmapData.Scan0, 4);
for (int copyIndex = 0; copyIndex < dataLines; copyIndex++)
{
int dataStartIndex = i_imageWidth * copyIndex;
int rowStartIndex = i_imageWidth * (copyIndex + 1);
byte[] row = data.Skip (dataStartIndex).Take (i_imageWidth).ToArray ();
Marshal.Copy (row, 0, IntPtr.Add (bitmapData.Scan0, rowStartIndex), row.Length);
}
bitmap.UnlockBits (bitmapData);
bitmap.Save (i_imagePath);
}

Related

Can't find sgfplib.dll

I trying to capture fingerprint via my C# code. I have referenced the secugen FDx Pro SDK for windows version 2.3.3.0 and have installed the drivers. Though I can not see the sgfplib.dll among the other dll files.
when I run the code trying to initialize the SGFingerPrintManager which uses sgfplib.dll, it complains that "sgfplib.dll can not be found" I have read the previous suggestion on this platform, but none solved the problems.
Please I appreciate in advance any suggestion to solve this problem sonnest.
Thanks in advance.
a) I have downloaded FDx Pro SDK for windows and the secugen drivers version 6.7 (64).
b) Also, I tried to copying the sgfplid.dll to the bin folder of my project but problem persists.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using LuggageTrackingAndBillingSystem.models;
using SecuGen.FDxSDKPro.Windows;
namespace LuggageTrackingAndBillingSystem
{
public partial class TsetForSecugen : Form
{
Int32 image_width = 200;
Int32 image_height = 300;
Int32 image_dpi = 500;
public TsetForSecugen()
{
InitializeComponent();
InitializeDedive();
}
private SGFingerPrintManager m_FPM;
SGFPMDeviceName device_name = SGFPMDeviceName.DEV_FDU03;
private void InitializeDedive()
{
//Step 1
if (RuntimePolicyHelper.LegacyV2RuntimeEnabledSuccessfully)
{
// This will load a CLR 2 mixed mode assembly
m_FPM = new SGFingerPrintManager();
}
var err = m_FPM.InitEx(image_width, image_height, image_dpi);
}
private void DrawImage(Byte[] imgData, PictureBox picBox)
{
int colorval;
Bitmap bmp = new Bitmap(image_width, image_height);
picBox.Image = (Image)bmp;
for (int i = 0; i < bmp.Width; i++)
{
for (int j = 0; j < bmp.Height; j++)
{
colorval = (int)imgData[(j * image_width) + i];
bmp.SetPixel(i, j, Color.FromArgb(colorval, colorval, colorval));
}
}
picBox.Refresh();
}
private void GetImage()
{
//Capturing Finger Image Step 3
Byte[] fp_image = new Byte[image_width * image_height];
Int32 iError;
iError = m_FPM.GetImage(fp_image);
if (iError == (Int32)SGFPMError.ERROR_NONE)
{
DrawImage(fp_image, pictureBox1);
}
}
private void TsetForSecugen_Load(object sender, EventArgs e)
{
InitializeDedive();
GetDevieInfo();
}
private void GetDevieInfo()
{
#region Det Device Info step 2
//Get Device info
SGFPMDeviceInfoParam pInfo = new SGFPMDeviceInfoParam();
pInfo = new SGFPMDeviceInfoParam();
Int32 iError = m_FPM.GetDeviceInfo(pInfo);
if (iError == (Int32)SGFPMError.ERROR_NONE)
{
image_width = pInfo.ImageWidth;
image_height = pInfo.ImageHeight;
}
#endregion
}
private void button1_Click(object sender, EventArgs e)
{
GetImage();
}
}
}
Actual result:The expected result is to be able to capture fingerpring
Error Meaage: Header[FDx SDK Pro.NET] . Body[can't find sgfplib.dll]
I have solved the issue by gotten the executable file of FDx SDK Pro for windows and installed.
The problem is caused by the FDx SDK Pro For windows not being able to see the sgfplib.dll file which is automatically installed in windows/System32 and Windows/sysWOW64 directories during installation.
Thanks to all.

Is it possible to get the HWID on linux and windows in C# without WMI?

Hi :) I'm writing a C# application and need to get the HWID code for the computer the code is running on. Since this is a console, i need to figure out a way to find the HWID for the CPU, motherboard and HDD, without using the the WMI. Since the system.management is not available on linux, i need it without using that. is it possible to find the HWID without the WMI? Or could i find a way to use the WMI for linux to find the HWID?
Is it possible in C# to do this? I would appreciate if anyone told me how, or pointed me in the right direction to get started. thank you all!
Try this link, not sure if it will work on linux though.
Updated
private string GetUID()
{
StringBuilder strB = new StringBuilder();
Guid G = new Guid(); HidD_GetHidGuid(ref G);
strB.Append(Convert.ToString(G));
IntPtr lHWInfoPtr = Marshal.AllocHGlobal(123); HWProfile lProfile = new HWProfile();
Marshal.StructureToPtr(lProfile, lHWInfoPtr, false);
if (GetCurrentHwProfile(lHWInfoPtr))
{
Marshal.PtrToStructure(lHWInfoPtr, lProfile);
strB.Append(lProfile.szHwProfileGuid.Trim(new char[] { '{', '}' }));
}
Marshal.FreeHGlobal(lHWInfoPtr);
SHA256CryptoServiceProvider SHA256 = new SHA256CryptoServiceProvider();
byte[] B = Encoding.Default.GetBytes(strB.ToString());
string outStr = BitConverter.ToString(SHA256.ComputeHash(B)).Repla ce("-", null);
for(int i = 0;i < 64; i++)
{
if (i % 16 == 0 && i != 0)
outStr = outStr.Insert(i, "-");
}
return (outStr);
}
[DllImport("hid.dll")]
private static extern void HidD_GetHidGuid(ref Guid GUID);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetCurrentHwProfile(IntPtr fProfile);
[StructLayout(LayoutKind.Sequential)]
class HWProfile
{
public Int32 dwDockInfo;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 39)]
public string szHwProfileGuid;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szHwProfileName;
}

Netbeans6.9.1 Image as icons

I'm currently using Netbean 6.9.1 and I just want to add some PNG files to my program when it builds. I'm using the files as icons for some of the GUI buttons and labels. But when I select clean and build main project or build main project and execute the JAR file outside the IDE, the icons are missing.
I put the image files into my project folder and basically just add this kinda code in.
the code is working it sisplays the icons but it did nor pick the images for those icons.
void setMainForm(Resources r) {
UIManager.getInstance().setResourceBundle(r.getL10N("localize", "en"));
MainScreenForm main = new MainScreenForm(this, "Business Organiser");
if(mainMenu != null){
main.setTransitionInAnimator(mainMenu.getTransitionInAnimator());
main.setTransitionOutAnimator(mainMenu.getTransitionOutAnimator());
}else{
main.setTransitionOutAnimator(CommonTransitions.createFade(400));
}
mainMenu = main;
int width = Display.getInstance().getDisplayWidth(); //get the display width
elementWidth = 0;
Image[] selectedImages = new Image[DEMOS.length];
Image[] unselectedImages = new Image[DEMOS.length];
final ButtonActionListener bAListner = new ButtonActionListener();
for (int i = 0; i < DEMOS.length; i++) {
Image temp = r.getImage(DEMOS[i].getName() + "_sel.png");
selectedImages[i] = temp;
unselectedImages[i] = r.getImage(DEMOS[i].getName() + "_unsel.png");
final Button b = new Button(DEMOS[i].getName(), unselectedImages[i]);
b.setUIID("DemoButton");
b.setRolloverIcon(selectedImages[i]);
b.setAlignment(Label.CENTER);
b.setTextPosition(Label.BOTTOM);
mainMenu.addComponent(b);
b.addActionListener(bAListner);
b.addFocusListener(new FocusListener() {
public void focusGained(Component cmp) {
if (componentTransitions != null) {
mainMenu.replace(b, b, componentTransitions);
}
}
public void focusLost(Component cmp) {
}
});
demosHash.put(b, DEMOS[i]);
elementWidth = Math.max(b.getPreferredW(), elementWidth);
}
if(cols == 0){
cols = width / elementWidth;
}
int rows = DEMOS.length / cols;
mainMenu.setLayout(new GridLayout(rows, cols));
mainMenu.setDragMode(true);
mainMenu.addCommand(exitCommand);
mainMenu.addCommand(aboutCommand);
mainMenu.addCommand(rtlCommand);
mainMenu.addCommand(dragModeCommand);
mainMenu.addCommand(runCommand);
mainMenu.addCommandListener(this);
mainMenu.show();
}
You need to put the images in the src folder so they get packaged in the jar (use 7zip on the jar to see what went in). You didn't provide the image URL e.g icon in src root should work like this:
"/icon.png"

Print to a label printer from a web site / web application? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
Are there any known label printers that will accept print commands from a web site or web application?
Specifically, the one-off label printers such as Dymo, Brother, Zebra, etc.
Has anyone had success in printing to these printers (without using an Internet Explorer-Only hack or ActiveX control)
I would think that, eventually, there would have to be a solution as we move into a more browser-centric world.
Wow. I know this was asked over 4 years ago, but having burnt the better part of a week in search of a robust method of printing labels from a web app, I had to voice in here.
Here's what I've found:
DYMO seems the most likely candidate for excellence. But no, turns out it only prints from (a) its own app, or (b) something using its SDK. The DYMO SDK uses an XML drawing model that is both overly complex and limited in layout and styling. The documentation is scattered and incomprehensible (e.g. what are the <Bounds> values for the common label sizes? There's no description of the tag parameters anywhere!) So frustrating, so disappointing.
There's qz (was jzebra), which enables browser printing for devices that speak EPL, ZPL, FGL, ESC/POS, EPCL and CPCL ... which includes the Zebra series. It requires a load of integration (running a web server on device the label printer is attached to), but it works.
There's a well designed 3rd party app by Peninsula, which works for DYMO (among others), but requires a middle-step of printing from browser to PDF. They also assume you'll never scale what you want printed down less than 70%, which is incorrect.
The OP says "I would think that, eventually, there would have to be a solution as we move into a more browser-centric world." Four years later, I'd go a step further and suggest any label printer that can't print off a browser (or just behave like a regular printer with small paper) is falling WAY short of its potential. Layout in HTML+CSS is a snap. Browsers parse it perfectly, and render it at any resolution to any output device. It seems so obvious.
If anyone knows of a thermal label printer that prints from the browser instead of imprisoning you in archaic integration methodologies, I'd very much like to know!
The Dymo printers have a browser plugin that let you print from javascript. Very easy to use.
Revisiting this question a few years later.
The networked Zebra printers are easy to print to. In one project I had the webapplication open a socket to the printer and feed it instructions in ZPL.
You could also trying looking PrintNode which provide a cloud printing solution and means you can print straight to any printer over the internet.
A cross-browser/platform-compatible web page/web page script doesn't have the low-level access necessary to transmit printer language command (such as Zebra Printer Language [ZPL]) to the printer. In order to do this, an ActiveX control/browser plugin/applet/similar bit of executable code is required. This limitation is non-printer specific, coming from the browser not the printer manufacturer.
However, many label printers allow you to print to them as though they were normal printers--just ones that print to very small pieces of paper. You could layout your label using HTML/CSS. When displaying the results, instruct the user to go to "File > Print" and select their label printer before clicking print.
Hope this helps,
Ben
Zebra now has a tool called 'BrowserPrint' that works like PrintNode specifically for Zebra printers. (unlike Printnode, it's free to use with Zebra printers)
Some printers also have ppd files available and/or can be configured in cups on a linux platform system or otherwise connected and spoken too via linux. (which then means it's not impossible to use something from shell scripting, php, perl or other methods to print to it by building a simple server daemon or setting up something like apache or lighttpd on a linux box or even a raspberry pi connected to the printer)
You can print from a signed Java applet, or from a Java Web Start application:
http://java.sun.com/javase/technologies/desktop/printing/
That should work, if you format your print output so it fits on the labels.
Note that most modern browsers are restricting support for Java applets, so you may run into trouble with an applet, depending on the browsers in use. In particular, Google Chrome will stop supporting Java applets in September 2015. These restrictions do not apply to Java Web Start, which should continue to work.
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Management;
using System.Reflection;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GetAllPrinterList();
this.textBox1.Attributes.Add(
"onkeypress", "button_click(this,'" + this.Button1.ClientID + "')");
this.lstPrinterList.Attributes.Add(
"onkeypress", "button_click(this,'" + this.Button1.ClientID + "')");
}
private void GetAllPrinterList()
{
//ManagementScope objScope = new ManagementScope(ManagementPath.DefaultPath); //For the local Access
//objScope.Connect();
//SelectQuery selectQuery = new SelectQuery();
//selectQuery.QueryString = "Select * from win32_Printer";
//ManagementObjectSearcher MOS = new ManagementObjectSearcher(objScope, selectQuery);
//ManagementObjectCollection MOC = MOS.Get();
//foreach (ManagementObject mo in MOC)
//{
// lstPrinterList.Items.Add(mo["Name"].ToString());
// //lstPrinterList.Items.Add(new ListItem(mo["Name"].ToString()));
//}
lstPrinterList.Items.Add("\\\\10.32.65.6\\Parcel-Zebra-FDX ZM400");
lstPrinterList.Items.Add("\\\\10.32.65.4\\Singles_Station_Z_Printer");
lstPrinterList.Items.Add("\\\\10.32.65.12\\ZebraZ4M-Packaging");
if (lstPrinterList.Items.Count > 3)
{
lstPrinterList.Items.RemoveAt(5);
lstPrinterList.Items.RemoveAt(4);
lstPrinterList.Items.RemoveAt(3);
}
//LocalPrintServer printServer = new LocalPrintServer();
//string printer;
//printer = LocalPrintServer.DefaultPrintQueue;
//System.Management.ObjectQuery oquery =
// new System.Management.ObjectQuery("SELECT * FROM Win32_Printer");
// System.Management.ManagementObjectSearcher mosearcher =
// new System.Management.ManagementObjectSearcher(oquery);
// System.Management.ManagementObjectCollection moc = mosearcher.Get();
// foreach (ManagementObject mo in moc)
// {
// System.Management.PropertyDataCollection pdc = mo.Properties;
// foreach (System.Management.PropertyData pd in pdc)
// {
// // if ((bool)mo["Network"])
// // {
// lstPrinterList.Items.Add(mo["Name"].ToString());
// // }
// }
// }
//}
// using (var printServer = new PrintServer(string.Format(#"\\{0}", PrinterServerName)))
//{
// foreach (var queue in printServer.GetPrintQueues())
// {
// if (!queue.IsShared)
// {
// continue;
// }
// Debug.WriteLine(queue.Name);
// }
// }
//foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
//{
//MessageBox.Show(printer);
//System.Web.UI.WebControls.ListBox lstPrinterList = new System.Web.UI.WebControls.ListBox();
//System.Web.UI.WebControls.ListBox lstPrinterList = (System.Web.UI.WebControls.ListBox)Page.FindControl("lstPrinterList");
//lstPrinterList.Text = "Zebra 110PAX4 (203 ;dpi)";
//lstPrinterList.Items.Add(printer.ToString());
//lstPrinterList.Items.Add(new ListItem(printer));
//lstPrinterList.Items.Add(printer);
//System.Web.UI.WebControls.ListBox lstPrinterList = (System.Web.UI.WebControls.ListBox)Page.FindControl("ListBox1");
//Zebra 110PAX4 (203 dpi)
//lstPrinterList.Items.Insert(printer);
//}
}
//private void lstPrinterList_OnClick(object sender, System.EventArgs e)
//{
// // Get the currently selected item in the ListBox.
// string curItem = lstPrinterList.SelectedItem.ToString();
// // Find the string in ListBox2.
// int index = lstPrinterList.DataTextField(curItem);
// //int index = lstPrinterList.FindString(curItem);
// //lstPrinterList.DataTextField(curItem);
// // If the item was not found in ListBox 2 display a message box, otherwise select it in ListBox2.
// if (index == -1)
// MessageBox.Show("Item is not available in ListBox2");
// else
// lstPrinterList.SetSelected(index, true);
//}
//private void button1_Click(object sender, System.EventArgs e)
//{
// string str = File.ReadAllText("lpn.prn");
// str = str.Replace("BOX_TYPE", "boom");
// str = str.Replace("11111111", textBox1.Text);
// File.WriteAllText("lpn.prn", str);
// // Print the file to the printer.
// RawPrinterHelper.SendFileToPrinter("\\\\Zebra-FDX ZM400 200 dpi (ZPL)", "C:\\Users\\Administrator\\Documents\\Visual Studio 2015\\Projects\\WindowsFormsApplication4\\Prn Print\\bin\\Debug\\lpn.prn");
//}
public void button1_Click(object sender, System.EventArgs e)
{
String prnFile = "lpn2.prn";
string s = File.ReadAllText(prnFile);
string printer;
String Printer = lstPrinterList.SelectedItem.ToString();
s = s.Replace("*description*", "snuffles");
s = s.Replace("*barcode*", textBox1.Text);
//File.WriteAllText("PPlpn.prn", s);
//s = "^XA^LH30,30\n^FO20,10^ADN,90,50^AD^FDHello World^FS\n^XZ";
printer = lstPrinterList.SelectedItem.Value;
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
RawPrinterHelper.SendStringToPrinter(printer, s);
//RawPrinterHelper.SendStringToPrinter(Printer, s);
//Response.Redirect(Request.RawUrl.Replace(Request.Url.Query, "?__VIEWSTATE=%2%3D&ctl00%24MainContent%24textBox1=bp300&ctl00%24MainContent%24lstPrinterList=Shipping+Printer"));
}
protected void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
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, IntPtr 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, IntPtr 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 = "My C#.NET RAW Document";
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();
}
return bSuccess;
}
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
// How many characters are in the string?
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
This is what I created in C# and it worked out great. This is a web app.

How to generate GIR files from the Vala compiler?

I am trying to create python bindings to a vala library using pygi with gobject introspection. However, I am having trouble generating the GIR files (that I am planning to compile to typelib files subsequently). According to the documentation valac should support generating GIR files.
Compiling the following
helloworld.vala
public struct Point {
public double x;
public double y;
}
public class Person {
public int age = 32;
public Person(int age) {
this.age = age;
}
}
public int main() {
var p = Point() { x=0.0, y=0.1 };
stdout.printf("%f %f\n", p.x, p.y);
var per = new Person(22);
stdout.printf("%d\n", per.age);
return 0;
}
with the command
valac helloworld.vala --gir=Hello-1.0.gir
doesn't create the Hello-1.0.gir file as one would expect. How can I generate the gir file?
To generate the GIR one has to put the functions to be exported under the same namespace
hello.vala
namespace Hello {
public struct Point {
public double x;
public double y;
}
public class Person {
public int age = 32;
public Person(int age) {
this.age = age;
}
}
}
public int main() {
var p = Hello.Point() { x=0.0, y=0.1 };
stdout.printf("%f %f\n", p.x, p.y);
var per = new Hello.Person(22);
stdout.printf("%d\n", per.age);
return 0;
}
and then run the following command.
valac hello.vala --gir=Hello-1.0.gir --library Hello-1.0
This will generate a gir and a vapi file in the current directory.
Then to generate the typelib file, one needs to run
g-ir-compiler --shared-library=hello Hello-1.0.gir -o Hello-1.0.typelib
assuming the shared library has been compiled to libhello.so

Resources