Get absolute address of range - c#

In old school Excel Interop, I can use the following code to generate an absolute address and use it inside a formula:
range.Formula = $"=sum({myRange.Address[false, true]})";
What is the EPPlus equivalent of this line, to get an absolute address (with an absolute row and/or column on demand)?

For an approach, that uses only EPPlus methods, there are static methods like ExcelCellBase.GetAddress (with a couple of overloads) that return absolute addresses:
public abstract class ExcelCellBase
{
public static string GetAddress(
int Row,
int Column,
bool Absolute
);
public static string GetAddress(
int Row,
bool AbsoluteRow,
int Column,
bool AbsoluteCol
);
public static string GetAddress(
int FromRow,
int FromColumn,
int ToRow,
int ToColumn,
bool FixedFromRow,
bool FixedFromColumn,
bool FixedToRow,
bool FixedToColumn
);
/* ... and others, see comments */
}
An extension method could be as easy as this one:
public static class EpPlusExtensions
{
public static string GetAddress(
this ExcelRangeBase range,
bool absoluteRow = false,
bool absoluteColumn = false)
{
return ExcelCellBase.GetAddress(
range.Start.Row,
range.Start.Column,
range.End.Row,
range.End.Column,
absoluteRow,
absoluteColumn,
absoluteRow,
absoluteColumn);
}
}

Well, there isn't a built in method, but you can do the following:
string GetAddress(ExcelRange rgn, bool absoluteRow, bool absoluteColumn,bool includeSheetName=false)
{
string address = rgn.Address;
if (absoluteColumn)
{
address = Regex.Replace(address, #"\b([A-Z])", #"$$$1");
}
if (absoluteRow)
{
address = Regex.Replace(address, #"([0-9]+)", #"$$$1");
}
if (includeSheetName)
{
address = $"'{rgn.Worksheet.Name}'!{address}";
}
return address;
}
Or as an extension method, so you can use like interop:
public static class EpplusExtensions
{
public static string Address(this ExcelRange rgn, bool absoluteRow, bool absoluteColumn, bool includeSheetName=false)
{
string address = rgn.Address;
if (absoluteColumn)
{
address = Regex.Replace(address, #"\b([A-Z])", #"$$$1");
}
if (absoluteRow)
{
address = Regex.Replace(address, #"([0-9]+)", #"$$$1");
}
if (includeSheetName)
{
address = $"'{rgn.Worksheet.Name}'!{address}";
}
return address;
}
}
Usage:
using (var ep = new ExcelPackage(new FileInfo(file)))
{
var sh = ep.Workbook.Worksheets.First();
ExcelRange myRange = sh.Cells[1, 1, 26, 36];
var absoluteColumn = myRange.Address(false, true);
var absoluteRow = myRange.Address(true, false);
var absolute = myRange.Address(true, true);
var relative = myRange.Address(false, false);
var withSheetName = myRange.Address(true, true, true);
}

Related

Check if a C# string is a well formed url with a port number

I got a string which I check if it represents a URL like this:
if(Uri.IsWellFormedUriString(urlString, UriKind.Absolute)) ...
Is there also a way to add there a check if the url contains a port number?
You could offload all the heavy work to the Uri constructor:
var uri = new Uri(urlString);
Then you only need to interpret uri.Authority. If it contains a colon, the port is specified.
public static bool IncludesPort(this string urlAddress)
{
return new Uri(urlAddress).Authority.Contains(':');
}
public class StackoverflowQuestion
{
public string Run() {
string urlString = "http://mywebsite:8001/application/api";
if (Uri.IsWellFormedUriString(urlString, UriKind.Absolute) && urlString.IncludesPort())
return "The uri contains explicitly defined port";
return "";
}
}
public static class Extensions {
public static bool IncludesPort(this string urlAddress)
{
urlAddress = urlAddress.Replace("http://", "").Replace("https://", "");
var splitted = urlAddress.Split(':');
var port = splitted?[1].Split("/")?[0];
return port != null && int.TryParse(port, out _);
}
}

C# CurlSharp EasyGet - How to get string result

I'm using this code to make an EasyGet request.Does anyone know how to get a string result?
using CurlSharp;
public static void CurlSharpGet(string url, bool useHttp2 = true)
{
Curl.GlobalInit(CurlInitFlag.All);
try
{
if (useHttp2)
{
using (var easy = new CurlEasy())
{
easy.Url = url;
easy.WriteFunction = OnWriteData;
easy.HttpVersion = CurlHttpVersion.Http2_0;
easy.SslVerifyPeer = false;
easy.SslVerifyhost = false;
easy.Perform();
Console.WriteLine(easy.Perform());
}
}
else
{
using (var easy = new CurlEasy())
{
easy.Url = url;
easy.WriteFunction = OnWriteData;
easy.Perform();
Console.WriteLine(easy.Perform());
}
}
}
finally
{
Curl.GlobalCleanup();
}
}
public static Int32 OnWriteData(byte[] buf, Int32 size, Int32 nmemb, object data)
{
Console.Write(Encoding.UTF8.GetString(buf));
return size * nmemb;
}
Ideally i would like to have something that looks like this:
public static string CurlSharpGet(string url, bool useHttp2 = true)
{
//my fixed code here
}
The nature of what I'm doing cannot be accomplished using httpclient or webresponse. Would appreciate any advice on what I should do to get the above code to return a string result. Thanks

BioMetric FingerPrint

I am using ZKFinger SDK2.3.3.1 version and Device
Communication Protocol SDK(32Bit Ver6.2.4.1 -- DLL Version : zkemkeeper.dll - 6.2.4.1. I have a small USB fingerprint scanner. When I scan the fingerprint,
I get an array of bytes . I saved it to disc in a bitmap file and jpg both and the fingerprint looks quite good scanned. To set the fingerprint template to a user on the device, i decomporessed fingerprint image, and then call SetUserTmp Function of zkemkeeper.dll.
I am getting size error , (-3) in code.
How can i go further? What is my mistake?
Below is my code for transfering finger from USB device to BioMetric device
bool fullImage = false;
zkfpEng.SaveJPG("Myfirstfinger.jpg");
string strtmp, sRegTemplate;
object pTemplate;
sRegTemplate = zkfpEng.GetTemplateAsStringEx("9");
pTemplate = zkfpEng.DecodeTemplate1(sRegTemplate);
// Note: 10.0Template can not be compressed
zkfpEng.SetTemplateLen(ref pTemplate, 602);
zkfpEng.SaveTemplate("Myfirstfingerprint.tpl", pTemplate);
byte[] TmpData = new byte[700];
TmpData =ObjectToByteArray(pTemplate);
if (bIsConnected == false)
{
MessageBox.Show("Please connect the device first!", "Error");
return;
}
int idwFingerIndex = Convert.ToInt32(cbFingerIndex.Text.Trim());
int idwEnrollNumber = Convert.ToInt32(txtUserID.Text.Trim());
int iTmpLength = 0;
string sdwEnrollNumber = txtUserID.Text.Trim();
axCZKEM1.EnableDevice(iMachineNumber, false);
Cursor = Cursors.WaitCursor;
bool IsSetTmp = false;
IsSetTmp = axCZKEM1.SetUserTmp(iMachineNumber, idwEnrollNumber, idwFingerIndex, ref TmpData[0]);
int errCode = 0;
axCZKEM1.GetLastError(ref errCode);
MessageBox.Show(IsSetTmp.ToString() + " " + errCode.ToString());
if (IsSetTmp == true)
{
MessageBox.Show("User template set successfully!", "Success");
}
else
{
MessageBox.Show("User template not set successfully!", "Error");
}
i think you don't have to convert it to image file, just like Remin said.
here some example. i'm using xaf and mysql db
private void DownloadUserInformationAction_Execute(object sender, SimpleActionExecuteEventArgs e)
{
IObjectSpace os = Application.CreateObjectSpace();
Terminal terminal = (Terminal)View.SelectedObjects[0];
//create new czkemclass obj
CZKEMClass myCZKEMClass = new CZKEMClass();
//connecting the device
myCZKEMClass.Connect_Net(terminal.IPAddress, terminal.Port);
//Initialize variable for store temporary user information
int tMachineNo = 0;
string tEnrollNo = "";
string tName = "";
string tPassword = "";
int tPrivilage = 0;
bool tEnabled = false;
int tFingerIndex;
int tFlag = 0;
string tTemplateData = "";
int tTemplateLength = 0;
myCZKEMClass.EnableDevice(terminal.DeviceId, false);
myCZKEMClass.ReadAllUserID(terminal.DeviceId);
myCZKEMClass.ReadAllTemplate(terminal.DeviceId);
while (myCZKEMClass.SSR_GetAllUserInfo(tMachineNo, out tEnrollNo, out tName, out tPassword, out tPrivilage, out tEnabled))
{
for (tFingerIndex = 0; tFingerIndex < 10; tFingerIndex++)
{
if (myCZKEMClass.GetUserTmpExStr(tMachineNo, tEnrollNo, tFingerIndex, out tFlag, out tTemplateData, out tTemplateLength))
{
EmployeeBiometric employeeBiometric = new EmployeeBiometric(terminal.Session);
//employeeBiometric.EnrollNumber = tEnrollNo;
XPCollection<Employee> employees = new XPCollection<Employee>(terminal.Session);
employeeBiometric.Employee = employees.Where(emp => emp.EnrollNo == tEnrollNo).FirstOrDefault();//(emp => emp.Sequence.ToString() == tEnrollNo).FirstOrDefault();
employeeBiometric.UserName = tName;
employeeBiometric.Password = tPassword;
employeeBiometric.Privilege = (Privilege)Enum.ToObject(typeof(Privilege), tPrivilage);
employeeBiometric.Enabled = tEnabled;
employeeBiometric.FingerprintIndex = tFingerIndex;
employeeBiometric.FingerprintTemplate = tTemplateData;
employeeBiometric.TemplateLength = tTemplateLength;
terminal.Session.CommitTransaction();
}
}
}
myCZKEMClass.EnableDevice(terminal.DeviceId, true);
}
that's method for downloading the your fingerprint image from device to your apps.
and here you can upload it back to another device
private void UploadUserInformationAction_Execute(object sender, PopupWindowShowActionExecuteEventArgs e)
{
IObjectSpace os = Application.CreateObjectSpace();
EmployeeBiometric employeeBiometric = (EmployeeBiometric)View.SelectedObjects[0];
EmployeeBiometricParameter param = (EmployeeBiometricParameter)e.PopupWindowViewCurrentObject;
//create new czkemclass obj
CZKEMClass myCZKEMClass = new CZKEMClass();
//connecting the device
myCZKEMClass.Connect_Net(param.Terminal.IPAddress, param.Terminal.Port);
myCZKEMClass.EnableDevice(param.Terminal.DeviceId, false);
int myCount = View.SelectedObjects.Count;
//Set specific user to fingerprint device
for (int i = 1; i <= myCount; i++)
{
int tMachineNo = param.Terminal.DeviceId;
string tEnrollNo = employeeBiometric.Employee.EnrollNo;//Sequence.ToString();
string tName = employeeBiometric.UserName;
string tPassword = employeeBiometric.Password;
int tPrivilege = (int)employeeBiometric.Privilege;
bool tEnabled = employeeBiometric.Enabled;
int tFingerIndex = employeeBiometric.FingerprintIndex;
string tTmpData = employeeBiometric.FingerprintTemplate;
int tFlag = 1;
if (myCZKEMClass.SSR_SetUserInfo(tMachineNo, tEnrollNo, tName, tPassword, tPrivilege, tEnabled))
{
myCZKEMClass.SetUserTmpExStr(tMachineNo, tEnrollNo, tFingerIndex, tFlag, tTmpData);
}
}
myCZKEMClass.RefreshData(param.Terminal.DeviceId);
myCZKEMClass.EnableDevice(param.Terminal.DeviceId, true);
}
and this is my "Terminal" Class
public partial class Terminal : XPCustomObject
{
Guid fOid;
[Key(AutoGenerate = true), Browsable(false)]
public Guid Oid
{
get { return fOid; }
set { SetPropertyValue<Guid>("Oid", ref fOid, value); }
}
private Branch _Branch;
[RuleRequiredField("", DefaultContexts.Save, "Branch required")]
public Branch Branch
{
get
{
return _Branch;
}
set
{
SetPropertyValue("Branch", ref _Branch, value);
}
}
string fDescription;
[RuleUniqueValue("", DefaultContexts.Save, "The value was already registered within the system.", ResultType = ValidationResultType.Warning)]
[RuleRequiredField("", DefaultContexts.Save, "Description required")]
public string Description
{
get { return fDescription; }
set { SetPropertyValue<string>("Description", ref fDescription, value); }
}
string fIPAddress;
[Size(15)]
public string IPAddress
{
get { return fIPAddress; }
set { SetPropertyValue<string>("IPAddress", ref fIPAddress, value); }
}
private int _Port;
public int Port
{
get
{
return _Port;
}
set
{
SetPropertyValue("Port", ref _Port, value);
}
}
string fDeviceDescription;
public string DeviceDescription
{
get { return fDeviceDescription; }
set { SetPropertyValue<string>("DeviceDescription", ref fDeviceDescription, value); }
}
private int _DeviceId;
public int DeviceId
{
get
{
return _DeviceId;
}
set
{
SetPropertyValue("DeviceId", ref _DeviceId, value);
}
}
private bool _Disabled;
public bool Disabled
{
get
{
return _Disabled;
}
set
{
SetPropertyValue("Disabled", ref _Disabled, value);
}
}}
Read the FP as string and push the same string to the Biometric device without any compression or conversion.

IQueryable<OFSOMEOBJECT> Export to excel

Well, this certainly might have not been asked before.
I have a method that returns me an IQueryable, the client requirement is one specific example we should export that to excel without showing the results in a gridview.
Any idea?
string strSql = BuildQuery();
try
{
var list = RequestBaseBL.GetRequestByCustomQuery(strSql, DdlRequestType.SelectedValue).ToList();
to export in excel have a look here:
http://epplus.codeplex.com/releases/view/42439
then you can create your own class to generate excel export for IEnumerable
here some hint (these are part of more large object so only hints, nothing compiling surely) at the possible from one of my projects:
public interface IExcelReporting : IServiceObject
{
ColumnsExcel Columns { get; }
void SetDatasource(IEnumerable datasource);
void SetHeaderLabelMerge(int columnMerge);
void AddHeader(string label, string value);
Byte[] ExportToExcel(string title, string author, DateTime date);
}
an example of implementation :
public Byte[] ExportToExcel(string title, string author, DateTime date)
{
ExcelPackage package = new ExcelPackage();
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(title);
if (_Columns != null)
{
Dictionary<int, Func<object, string>> internalMappingGetter = new Dictionary<int, Func<object, string>>();
//create the Header of the body
foreach (ColumnExcel entity in _Columns)
{
worksheet.Cells[RowIndex, ColumnIndex].Value = entity.HeaderName;
worksheet.Cells[RowIndex, ColumnIndex].Style.WrapText = true;
BorderCell(worksheet.Cells[RowIndex, ColumnIndex]);
worksheet.Column(ColumnIndex).Width = entity.Width;
ColumnIndex++;
}
RowIndex++;
if (_DataSource != null)
{
foreach (Object o in _DataSource)
{
ColumnIndex = 1;
foreach (ColumnExcel column in _Columns)
{
column.Apply(worksheet.Cells[RowIndex, ColumnIndex], o);
worksheet.Column(ColumnIndex).BestFit = true;
worksheet.Cells[RowIndex, ColumnIndex].Style.WrapText = true;
//BorderCell(worksheet.Cells[RowIndex, ColumnIndex]);
ColumnIndex++;
}
RowIndex++;
}
}
and the column class:
public class ColumnsExcel : IEnumerable
{
List<ColumnExcel> _Columns;
public ColumnsExcel()
{
_Columns = new List<ColumnExcel>();
}
public void AddInt(Func<object,int> getValue, string headerName, int width, string format)
{
ColumnExcel entity = new ColumnExcelInt(headerName, width, format, getValue);
_Columns.Add(entity);
}
public void AddString(Func<object, string> getValue, string headerName, int width )
{
ColumnExcel entity = new ColumnExcelstring(headerName, width, getValue);
_Columns.Add(entity);
}
public void AddDateTime(Func<object, DateTime?> getValue, string headerName, int width, string format)
{
ColumnExcel entity = new ColumnExcelDateTime(headerName, width, format, getValue);
_Columns.Add(entity);
}
public void AddDecimal(Func<object, decimal> getValue, string headerName, int width, string format)
{
ColumnExcel entity = new ColumnExcelDecimal(headerName, width, format, getValue);
_Columns.Add(entity);
}
public IEnumerator GetEnumerator()
{
return _Columns.GetEnumerator();
}
}
and its use :
//prepare the Ienumerable<MyObject>
var interventi = GetInterventoSchedeConsuntivi()
//prepare the report
IExcelReporting report = ReportingFactory.GetInstance();
report.SetDatasource(interventi);
report.AddHeader("Lotto:", lotto);
report.Columns.AddString((object v) => ((InterventoSchedeConsuntiviView)v).Lotto, "Lotto", 20);
using (System.IO.Stream s = File.Create(filepath))
{
byte[] csv = report.ExportToExcel(("titleFile", string.Empty, Servizi.DataOra.Now);
s.Write(csv, 0, csv.Length);
}

Way to determine framework version without Registry

I've searching a long time, but i couldn't find answer.
Is there any way to determine framework and service pack .NET installed on PC, without access to registry in C#?
I can use registry keys, but i have to do this without access to registry.
I read something about directories in C:\Windows\Microsoft .NET, but there, I only found framework version, nothing about SP. But I need framework and Service Pack.
Can somebody help me?
Regards, Greg
string clrVersion = System.Environment.Version.ToString();
string dotNetVersion = Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Where(x => x.Name == "mscorlib").First().Version.ToString();
you could use WMI to get a list of all the installed software filtering the result to achieve your goal
public static class MyClass
{
public static void Main()
{
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
}
}
I think it's possible to ask the WMI.
Query for all Win32_Product elements and look for the Name Property contains "Microsoft .NET Framework"
ServicePack information is also provided by WMI.. But I don't know exactly where.
You can do this:
System.Environment.Version.ToString()
(CLR Version only)
or this
from MSDN blog on Updated sample .NET Framework detection code that does more in-depth checking
or this
No registry access. Borrowed from this blog.
using System;
using System.IO;
using System.Security;
using System.Text.RegularExpressions;
namespace YourNameSpace
{
public class SystemInfo
{
private const string FRAMEWORK_PATH = "\\Microsoft.NET\\Framework";
private const string WINDIR1 = "windir";
private const string WINDIR2 = "SystemRoot";
public static string FrameworkVersion
{
get
{
try
{
return getHighestVersion(NetFrameworkInstallationPath);
}
catch (SecurityException)
{
return "Unknown";
}
}
}
private static string getHighestVersion(string installationPath)
{
string[] versions = Directory.GetDirectories(installationPath, "v*");
string version = "Unknown";
for (int i = versions.Length - 1; i >= 0; i--)
{
version = extractVersion(versions[i]);
if (isNumber(version))
return version;
}
return version;
}
private static string extractVersion(string directory)
{
int startIndex = directory.LastIndexOf("\\") + 2;
return directory.Substring(startIndex, directory.Length - startIndex);
}
private static bool isNumber(string str)
{
return new Regex(#"^[0-9]+\.?[0-9]*$").IsMatch(str);
}
public static string NetFrameworkInstallationPath
{
get { return WindowsPath + FRAMEWORK_PATH; }
}
public static string WindowsPath
{
get
{
string winDir = Environment.GetEnvironmentVariable(WINDIR1);
if (String.IsNullOrEmpty(winDir))
winDir = Environment.GetEnvironmentVariable(WINDIR2);
return winDir;
}
}
}
}
Here is an improved example that includes service packs,
string path = System.Environment.SystemDirectory;
path = path.Substring( 0, path.LastIndexOf('\\') );
path = Path.Combine( path, "Microsoft.NET" );
// C:\WINDOWS\Microsoft.NET\
string[] versions = new string[]{
"Framework\\v1.0.3705",
"Framework64\\v1.0.3705",
"Framework\\v1.1.4322",
"Framework64\\v1.1.4322",
"Framework\\v2.0.50727",
"Framework64\\v2.0.50727",
"Framework\\v3.0",
"Framework64\\v3.0",
"Framework\\v3.5",
"Framework64\\v3.5",
"Framework\\v3.5\\Microsoft .NET Framework 3.5 SP1",
"Framework64\\v3.5\\Microsoft .NET Framework 3.5 SP1",
"Framework\\v4.0",
"Framework64\\v4.0"
};
foreach( string version in versions )
{
string versionPath = Path.Combine( path, version );
DirectoryInfo dir = new DirectoryInfo( versionPath );
if( dir.Exists )
{
Response.Output.Write( "{0}<br/>", version );
}
}
The problem is that you will have to keep up with the versions as they come out.
You can use the MSI API functions to get a list of all installed products and then check whether the required .NET Framework version is installed.
Just don't tell you boss that these functions will read from the Registry.
Here's the code:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
[DllImport("msi.dll", SetLastError = true)]
static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len);
public const int ERROR_SUCCESS = 0;
public const int ERROR_MORE_DATA = 234;
public const int ERROR_NO_MORE_ITEMS = 259;
static void Main(string[] args)
{
int index = 0;
StringBuilder sb = new StringBuilder(39);
while (MsiEnumProducts(index++, sb) == 0)
{
var productCode = sb.ToString();
var product = new Product(productCode);
Console.WriteLine(product);
}
}
class Product
{
public string ProductCode { get; set; }
public string ProductName { get; set; }
public string ProductVersion { get; set; }
public Product(string productCode)
{
this.ProductCode = productCode;
this.ProductName = GetProperty(productCode, "InstalledProductName");
this.ProductVersion = GetProperty(productCode, "VersionString");
}
public override string ToString()
{
return this.ProductCode + " - Name: " + this.ProductName + ", Version: " + this.ProductVersion;
}
static string GetProperty(string productCode, string name)
{
int size = 0;
int ret = MsiGetProductInfo(productCode, name, null, ref size); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
{
StringBuilder buffer = new StringBuilder(++size);
ret = MsiGetProductInfo(productCode, name, buffer, ref size);
if (ret == ERROR_SUCCESS)
return buffer.ToString();
}
throw new System.ComponentModel.Win32Exception(ret);
}
}
}
This page may be of use:
http://blogs.msdn.com/b/astebner/archive/2009/06/16/9763379.aspx
Although the registry bit is irrelevant to you, the checking using mscoree.dll may be of help - its just that I cant access skydrive from work hence cant look through the code.
Ill see if i find something else.

Categories