How to load Dependent Assembly in memory to use Assembly.Load() method - assemblies

I have three dlls ProjBL.dll , ProjDL.dll and ProjMC.dll.
ProjBL.dll is Business object dll
ProjDL.dll is Data Access layer method dll
ProjMC.dll is Master Class dll contains Properties
ProjDL.dll depends on ProjMC.dll and ProjBL.dll depends on ProjDL.dll
I have load ProjBL.dll in Memory using Assembly.Load() method from folder on D: drive with specified folder.
Currently it gives error that "One of dependent Assembly not found"
The Method Used is as below
DirectoryInfo dllDirectory = new DirectoryInfo(folderPath);
FileInfo[] dllFiles = dllDirectory.GetFiles("*.dll");
int dllCount = dllFiles.Length;
FileStream fs = null;
if (dllCount > 0)
{
long streamLength = 0;
for (int fileCount = 0; fileCount < dllCount; fileCount++)
{
fs = new FileStream(dllFiles[fileCount].FullName, FileMode.Open);
streamLength += fs.Length;
fs.Close();
}
byte[] memory = new byte[streamLength];
byte[] memory1 = null;
byte[] memory2 = null;
byte[] memory3 = null;
fs = new FileStream(dllFiles[0].FullName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
memory1 = br.ReadBytes(Convert.ToInt32(fs.Length)); // Loads ProjMC.dll
fs = new FileStream(dllFiles[1].FullName, FileMode.Open);
br = new BinaryReader(fs);
memory2 = br.ReadBytes(Convert.ToInt32(fs.Length)); // Loads ProjDA.dll
fs = new FileStream(dllFiles[2].FullName, FileMode.Open);
br = new BinaryReader(fs);
memory3 = br.ReadBytes(Convert.ToInt32(fs.Length)); // Loads ProjBL.dll
fs.Close();
br.Close();
memory1.CopyTo(memory, 0);
memory2.CopyTo(memory, memory1.Length);
memory3.CopyTo(memory, (memory1.Length + memory2.Length));
assemblyUsed = Assembly.Load(memory);
}
return assemblyUsed;

Why so complex? Assembly.LoadFrom(string) will do the job nicely. Or you're trying to achieve some really weird behavior?

Since ProjBL.dll needs ProjDL.dll which needs ProjMC.dll the CLR will need to be able to find ProjDL.dll and ProjMC.dll (and any other dependencies) when you load ProjBL.dll.
It should be able to find them if they're either in the same directory as the executable or in the probepath. You can use fuslogvw to see where the CLR is looking for the dependent assemblies.

When the current application looks for assemblies, it looks in several locations (bin folder, gac, etc..) if it can not find one, then the developer needs to manually tell the application where to look. You can do this by intercepting the AssemblyResolve event, and using the event args to tell the CLR where your assembly is.
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
....................
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var assemblyPath=
Path.GetFullPath("..\\..\\..\\example\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
return Assembly.LoadFrom(assemblyPath);
}

Related

Error message "entries cannot be opened multiple times in update mode." in Spreadsheet Lite SaveAs function

Upon execution of the dBWorksheet.SaveAs(xlsFileSpec), in the code below, I am seeing an exception:
"entries cannot be opened multiple times in update mode."
SLDocument dBWorksheet = new SLDocument();
TimeSpan interval = new TimeSpan(0, 0, 2);
dBWorksheet.SetCellValue(2, 1, "Hour");
dBWorksheet.SetCellValue(3, 1, "Time");
int Row = 3;
// Create the hour and time of day columns.
for(TimeSpan dBTime = new TimeSpan(0, 0, 0); dBTime.TotalHours < 24; dBTime = dBTime.Add(interval))
{
dBWorksheet.SetCellValue(Row, 1, dBTime.Hours);
dBWorksheet.SetCellValue(Row, 2, dBTime.ToString());
Row++;
}
// Save the new worksheet.
dBWorksheet.SaveAs(xlsFileSpec);
I had this error when I opened (by SpreadsheetLight) .xlsx file that was saved (by LibreOffice Calc) in "Excel 2007-365" format and then I tried use a SaveAs function.
When I save (by LibreOffice Calc) the .xlsx file as "Office Open XML" then I can Open and SaveAs (by SpreadsheetLight) a .xlsx file without problems.
Here's how I solved it.
Downloaded the source code for SpreadsheetLight (version 3.5).
http://spreadsheetlight.com/downloads/SpreadsheetLight3.5.zip
Created a .NET Core library project with the name "SpreadsheetLight" and added necessary NuGet packages (DocumentFormat.OpenXML and System.Drawing.Common) to it. Copied and pasted all the downloaded source code files in this project.
Added the project "SpreadsheetLight" to my solution and referenced it in one of the existing projects.
In "SLDocument.cs" file, make the following changes in the method "LoadDocumentProperties()" so that the code looks like the following:
// XDocument xdoc = XDocument.Load(XmlReader.Create(xl.CoreFilePropertiesPart.GetStream()));
Stream stream = xl.CoreFilePropertiesPart.GetStream();
XDocument xdoc = XDocument.Load(XmlReader.Create(stream));
foreach (XElement xelem in xdoc.Descendants())
{
// Code omitted.
}
stream.Close();
Build your solution and test it.
Roll-back from .NET Core 3.0 to .NET Framework 4.7.x
This is obviously not the most desirable solution.
However, the only solution that I have found is to roll-back the application from .NET Core 3.0 and SpreadsheetLight.Core to .NET Framework 4.7.x and SpreadsheetLight.
The code posted in the question above runs without modification.
I believe this has to do with a memory leak that was fixed in System.IO.Packaging in .NET Core 3.0. This will require further investigation and probably a fix to SpreadsheetLight.Core.
A bit late to the party but just bumped in to this problem.
I solved this by create a new SLDocument and copied cell by cell from the old SLDocument. Might not work 100%, but it has covered my reports so far.
Code
using (var file = new SLDocument())
{
file.CopyFromTemplate(Path.Combine("ReportTemplates\\Tackningsbidrag_budget.xlsx"), maxCols: 20, maxRows: 10);
// code
using (var ms = new MemoryStream())
{
file.SaveAs(ms);
}
}
Extension method:
public static void CopyFromTemplate(this SLDocument file, string pathToOrgFile, int? maxCols = null, int? maxRows = null)
{
using (var orgFile = new SLDocument(pathToOrgFile))
{
var page = orgFile.GetPageSettings();
file.SetPageSettings(page);
foreach (var cell in orgFile.GetWorksheetMergeCells())
{
file.MergeWorksheetCells(cell.StartRowIndex, cell.StartColumnIndex, cell.EndRowIndex, cell.EndColumnIndex);
}
var stats = orgFile.GetWorksheetStatistics();
var endCol = stats.EndColumnIndex;
if (maxCols.HasValue && maxCols < endCol)
{
endCol = maxCols.Value;
}
var endRow = stats.EndRowIndex;
if (maxRows.HasValue && maxRows < endRow)
{
endRow = maxRows.Value;
}
for (int col = stats.StartColumnIndex; col <= endCol; col++)
{
file.SetColumnStyle(col, orgFile.GetColumnStyle(col));
file.SetColumnWidth(col, orgFile.GetColumnWidth(col));
}
for (int row = stats.StartRowIndex; row <= endRow; row++)
{
file.SetRowStyle(row, orgFile.GetRowStyle(row));
file.SetRowHeight(row, orgFile.GetRowHeight(row));
}
for (int row = stats.StartRowIndex; row <= endRow; row++)
{
for (int col = stats.StartColumnIndex; col <= endCol; col++)
{
var formula = orgFile.GetCellFormula(row, col);
var stringValue = orgFile.GetCellValueAsString(row, col);
file.SetCellValue(row, col, !string.IsNullOrWhiteSpace(formula) ? ("=" + formula) : stringValue);
file.SetCellStyle(row, col, orgFile.GetCellStyle(row, col));
}
}
}
}

Routine to Play encrypted mp3 plays the file and then locks the app

I have a procedure that opens an encrypted mp3, decrypts it to a memory stream, and then uses NAudio to play it. The encrypted mp3 file plays okay, but then the app locks.
I'm new to NAudio, and this is the first app I'm working on. Here's the code I've got.
public void PlayEncMP3(String sourceFile)
{
FileInfo info = new FileInfo(sourceFile);
FileStream input = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider();
cryptic.Key = ASCIIEncoding.ASCII.GetBytes("64BITKEY");
cryptic.IV = ASCIIEncoding.ASCII.GetBytes("64BIT_IV");
CryptoStream crStream = new CryptoStream(input, cryptic.CreateDecryptor(), CryptoStreamMode.Read);
BinaryReader rdr = new BinaryReader(crStream);
byte[] dta = new byte[info.Length];
rdr.Read(dta, 0, (int)info.Length);
Stream stream = new MemoryStream(dta);
using (WaveStream waveStream = new Mp3FileReader(stream))
{
using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(waveStream);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(100);
}
waveOut.Stop();
}
}
}
What seems to be happening is that the waveOut.PlaybackState is never being set to stopped. Debug statements show that loop lasting for as long as I care to wait, but the length of the mp3 file is only 5 seconds. Any idea why this is happening?
Removing that while loop on the PlaybackState has the result that the mp3 file does not play at all.
I tried simplifying the play code as follows, but with THIS version the mp3 file never plays. (Got this "solution" from this link: How to play a MP3 file using NAudio)
public void PlayEncMP3(String sourceFile)
{
// Get the encrypted file and setup the decryption engine
FileInfo info = new FileInfo(sourceFile);
FileStream input = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider();
cryptic.Key = ASCIIEncoding.ASCII.GetBytes("64BITKEY");
cryptic.IV = ASCIIEncoding.ASCII.GetBytes("64BIT_IV");
// Implement the decryptor
CryptoStream crStream = new CryptoStream(input, cryptic.CreateDecryptor(), CryptoStreamMode.Read);
// Read the decrypted file into memory and convert to a memory stream
BinaryReader rdr = new BinaryReader(crStream);
byte[] dta = new byte[info.Length];
rdr.Read(dta, 0, (int)info.Length);
Stream stream = new MemoryStream(dta);
// Open the waveStream for NAudio
using (WaveStream waveStream = new Mp3FileReader(stream))
{
// Open the waveOut
using (WaveOut waveOut = new WaveOut())
{
// Play the file
waveOut.Init(waveStream);
waveOut.Play();
}
}
}
BTW, I have two sound files I'm testing with (the second is 6 seconds long), and both behave the same way. Both sound files played perfectly okay when I was using the .NET SoundPlayer.
I am using the latest version of NAudio... downloaded it from the site this morning.
Any ideas how to fix this?

Out Of Memory exception if files to big

I'm currently working on a data-check for images. I need to request the Size (width & height) and the resolution of the image. Files over 70MB throw an "out of memory" exception on GDI Problem. Is there an alternative way to get the file-information? The same error on parse it through FromStream...
Using myfile = Image.FromFile(filePath)
...
End Using
You can use the following code to get image properties (it loads metadata only):
using (var fs = new FileStream(#"C:\Users\Dmitry\Pictures\blue-earth-wallpaper.jpg", FileMode.Open, FileAccess.Read)) {
var decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
var size = decoder.Frames[0].PixelWidth;
var height = decoder.Frames[0].PixelHeight;
var dpiX = decoder.Frames[0].DpiX;
var dpiY = decoder.Frames[0].DpiY;
}
I found this link http://www.fastgraph.com/help/image_file_header_formats.html that tells where in the file you can find the type and its dimensions. I guess, if you use something like this below to seek and get the first few bytes and close once you are done, shouldnt be using much resources
Untested code below...
// This really needs to be a member-level variable;
private static readonly object fsLock = new object();
// Instantiate this in a static constructor or initialize() method
private static FileStream fs = new FileStream("myFile.txt", FileMode.Open);
public string ReadFile(int fileOffset) {
byte[] buffer = new byte[bufferSize];
int arrayOffset = 0;
lock (fsLock) {
fs.Seek(fileOffset, SeekOrigin.Begin);
int numBytesRead = fs.Read(bytes, arrayOffset , bufferSize);
// Typically used if you're in a loop, reading blocks at a time
arrayOffset += numBytesRead;
}
// Do what you want to the byte array and close
}

how to get the image dimesion without using bitmap or graphics object in .net

i want to create SQL CLR integrated function from Visual C#, now my requirement is user will pass a folder path as a paramter, and the function should get all the image file from the the folder, and get its basic property like FileSize, dimension etc.. but it seems SQL project does not supports System.Drawing Namespace... as i created the same function in normal project it worked fine, as i was able to use System.Drawing Namespace, but here i cannot use, System.Drawing Namespace.. so is there any other way to get the image dimension...
below is the code i have used in my normal project.
public DataTable InsertFile(string FolderPath)
{
DataTable dt = new DataTable();
DataColumn[] col = new DataColumn[] { new DataColumn("FileName", typeof(System.String)), new DataColumn("FileSize", typeof(System.Int32)), new DataColumn("FilePath", typeof(System.String)), new DataColumn("Width", typeof(System.Int32)), new DataColumn("Height", typeof(System.Int32)) };
dt.Columns.AddRange(col);
FileInfo info= null;
Bitmap bmp = null;
foreach (String s in Directory.GetFiles(FolderPath, "*.jpg"))
{
info = new FileInfo(s);
bmp = new Bitmap(s);
DataRow dr = dt.NewRow();
dr["FileName"] = Path.GetFileName(s);
dr["FileSize"] = info.Length / 1024;
dr["FilePath"] = s;
dr["Width"] = bmp.Width;
dr["Height"] = bmp.Height;
dt.Rows.Add(dr);
}
return dt;
}
does anyone have any idea how to get image dimension without using System.Drawing Namespace.
wow never seen anyone try this before, but if using Drawing in a SQL project isn't allowed try reading the header info like this http://www.codeproject.com/KB/cs/ReadingImageHeaders.aspx
Edit included the code, with the change to remove the dependency on Size.
while (binaryReader.ReadByte() == 0xff)
{
byte marker = binaryReader.ReadByte();
ushort chunkLength = binaryReader.ReadLittleEndianInt16();
if (marker == 0xc0)
{
binaryReader.ReadByte();
int height = binaryReader.ReadLittleEndianInt16();
int width = binaryReader.ReadLittleEndianInt16();
return new int[] { width, height };
}
binaryReader.ReadBytes(chunkLength - 2);
}
Is the Image object any better for you?
System.Drawing.Image forSize = System.Drawing.Image.FromFile(s);
dr["Width"] = forSize.Width;
and so forth.
That any better or same problem?

Need to find the length of audio file in minutes in asp.net

I have asp.net application in which i am uploading audio files by converting them into the stream and upload to the database.But not able to find the length of the audio file into minutes.Here problem is that my asp.net application is present in the cloud.For uploading i am using upload file control of asp.net.Please suggest solution for this.
You may look at taglib#
I would have expected that you can calculate this from the bit rate and the file length: (file.lenghtInBits / kbsp ) / 60 = minutes.
rather assumes that you can get the bit rate from the file header though.
You will need to reference Windows Media Player. Go to Com Add-ins to add the wmp.dll to your project.
string Duration = null;
WMPLib.WindowsMediaPlayer w = new WMPLib.WindowsMediaPlayer();
WMPLib.IWMPMedia mediaFile = w.newMedia(Filename);
if (mediaFile != null) {
Duration = mediaFile.durationString;
}
w.close();
You could use the NAudio library as suggested in this answer to a similar SO question.
We can do it easily by given below code
private string GetDuration(string FileFullPath)
{
string duration = "";
string fName = FileFullPath.Substring(FileFullPath.LastIndexOf("\\") + 1);
string filePath = FileFullPath.Substring(0, FileFullPath.LastIndexOf("\\"));
Shell32.Shell shell = new Shell32.ShellClass();
Shell32.Folder folder = shell.NameSpace(filePath);
Shell32.FolderItem folderItem = folder.ParseName(fName);
if (folderItem != null)
{
duration = folder.GetDetailsOf(folderItem, 21);
}
folderItem = null;
folder = null;
shell = null;
return duration;
}
TimeSpan span= GetWavFileDuration(filePath + "\" + fileName);
string spanSeconds = span.TotalSeconds.ToString();
string[] spanSecondsArray=spanSeconds.Split('.');
spanSeconds = spanSecondsArray[0].ToString();
public static TimeSpan GetWavFileDuration(string fileName) {
WaveFileReader wf = new WaveFileReader(fileName);
return wf.TotalTime;
}
You can use this library for getting the Audio file duration

Resources