How to zip files/directories in VB.NET? - c#

I would like to zip a folder containing files and subfolders in VB.NET. My solution targets .NET 4.0 Client Profile.
I see that there is a ZipFile class for .NET 4.5, and System.IO.Packing for .NET 4.0 (but not Client Profile). So, those won't help. I note that there is also a GZipStream class, but I never see .gz files floating around, so not sure if that's a good approach. I would prefer a basic .zip file that I know my users can work with.
There are a handful of third-party solutions, such as http://icsharpcode.github.io/SharpZipLib/, but I assume they are far more bloated than the 10-20 lines of code I am looking for. Maybe that's the right answer...I don't know.
Just hoping for a few lines of VB.NET code to zip some files in a solution targeting .NET 4.0 CP.

Create ZIP from "source" folder.
Imports System.IO.Compression
ZipFile.CreateFromDirectory("source","destination.zip",CompressionLevel.Optimal,False)
Extract ZIP to "destination" folder.
ZipFile.ExtractToDirectory("destination.zip","destination")

Unable to comment in the comments section due to lack of reputation (due to being new here).
On the two answers indicating that using System.IO.Compression can be used that were commented as not working in NET 4.0 CP, this should be noted, as the original answers did not include an often overlooked fact.
A reference needs to be added to the project in order to activate "System.IO.Compression". This is not obvious to many new VS users, and unless the refrence is added, it indeed seems like "System.IO.Compression" does not work in NET 4.0.
In this case, the reference that needs to be added is System.IO.Compression.Filesystem (v4.0.0.0). One may also wish to add the reference: System.IO.Compression.
The "Add Reference..." dialog is under the "Project" menu in VS.

The MSDN Website has a class that can help you out here called ZipFile
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication {
class Program {
static void Main(string[] args) {
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
'Creates Zip File to directory as specified (startPath). And puts it in a specifed folder (zipPath)
ZipFile.CreateFromDirectory(startPath, zipPath);
'
Extracts Zip File to directory as specified(extractpath)
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}
Hope this helps!

Simply you can do it using Ionic.Zip.Dll
Here is the function for this,accepting two variables source path and destination path
public static void ExecuteBackupAsZip(string SourcePath, string DestinationPath)
{
using (var zip = new Ionic.Zip.ZipFile())
{
try
{
zip.AddDirectory(SourcePath);
zip.Save(DestinationPath);
}
catch { Console.WriteLine("Failed to execute backup"); }
}
}

Same challenges as "an odder guest". That is can't commment due to low rep as new user and have to add a new answer. (Frequent reader though). Running on vb.Net 4.6 and got no errors on the suggestions above, but no output zip file was generated. Then after some googling added references System.IO.Compression.Filesystem and System.IO.Compression and ended up with the following one-liner:
System.IO.Compression.ZipFile.CreateFromDirectory(FilePath1, FilePath3_ZippedFile)
Where FilePath1 is the path to the source folder (c:\whateverfolder) and FilePath3_ZippedFile is the path to the resulting output zip-file(c:\anotherfolder\MyZipFile.zip).
Sorry if you think my input is redundant, but I know for newcommers like my self we need the answers feed with tee spoons.
Word of caution: If you try to create the zip-file in the source folder you might have issues. My code then only included one of the files from the source folder in the zip-file. (No error messages). Changing the target location to another folder solved this without other edits to the code.

Related

BundleTransformer.Less unable to parse variables in #import statements

EDIT:
So according to this it is not possible which is a real shame. I will need to look for a library that bundles and compresses with the support of variables in imports.
I am having trouble trying to get BundleTransformer.Less to parse the following LESS:
// There is a path to Startup framework
#startup-basePath: "../../../";
#import '#{startup-basePath}flat-ui/less/config.less';
#import '#{startup-basePath}flat-ui/less/mixins.less';
And it is producing the following error:
You are importing a file ending in .less that cannot be found.":"/lib/startup/samples/template/less/#{startup-basePath}flat-ui/less/config.less
The files does exist but as you can see it isn't parsing the variable in the location string. Web Essentials in VS2013 has no problem compiling the LESS files and output the CSS as expected. I suspect the issue lies with BundleTransformer or the way that have set it up. I am using the following version:
Id Version Description/Release Notes
-- ------- -------------------------
BundleTransformer.Core 1.8.0 Bundle Transformer - a modular extension for System.Web.Optimization (aka Microsoft ASP.NET Web Optimization Framework). Classes `CssTransformer` and `JsTra...
BundleTransformer.Less 1.7.16 BundleTransformer.Less contains translator-adapter LessTranslator. This adapter makes translation of LESS-code to CSS-code. Also contains HTTP-handler LessA...
BundleTransformer.Yui 1.8.0 BundleTransformer.Yui contains 2 minifier-adapters: `YuiCssMinifier` (for minification of CSS-code) and `YuiJsMinifier` (for minification of JS-code). These...
I have to use these versions as I am using Umbraco 7 and it will not allow me to update Newtonsoft.Json without breaking Umbraco.
My bundle config file looks like the following:
public static void RegisterBundles(BundleCollection bundles)
{
bundles.UseCdn = true;
var nullBuilder = new NullBuilder();
var nullOrderer = new NullOrderer();
// CSS + LESS
var libCSS = new CustomStyleBundle("~/libCSS");
libCSS.Include(
"~/Content/font-awesome.css",
// LESS
"~/lib/startup/samples/template/less/style.less");
libCSS.Orderer = nullOrderer;
bundles.Add(libCSS);
}
I assumed that the issue was with the Less transformer not being registered correctly but I have followed the installation instructions to the letter, please see the documentation for the LESS version. Can anybody see something that I am missing that would help solve this issue or could anyone recommend something that I could try?
All help appreciated.
I have also tried this library, but unsuccessfully :/
Best solution for compiling LESS are node.js packages LESS (https://www.npmjs.org/package/less) or Recess (http://twitter.github.io/recess/).
Because your LESS files won't be changed after you deploy web project, you don't have to generate css during each application initialization.
You can also generate CSS before application builds or after saving LESS file.
If you're interested i can help you with more informations.
I have had better luck with the 1.9.40 and 1.9.34 versions of these BundleTransformer packages. I had problems with the 1.8 versions failing at times. We've been using BundleTransformer.Core.1.9.40, BundleTransformer.Less.1.9.40, and BundleTransformer.Yui.1.9.34 for a couple of weeks now without any of the errors of the 1.8 versions.
BundleTransformer.Less does not support the string interpolation in file paths (see «Is string interpolation not supported?» discussion).
UPDATE: In BundleTransformer.Less version 1.9.92 now supports the interpolation in file paths.

Merge DLL into EXE?

I have two DLL files which I'd like to include in my EXE file to make it easier to distribute it. I've read a bit here and there how to do this, even found a good thread here, and here, but it's far too complicated for me and I need real basic instructions on how to do this.
I'm using Microsoft Visual C# Express 2010, and please excuse my "low standard" question, but I feel like I'm one or two level below everyone else's expercise :-/ If someone could point out how to merge these DDL files into my EXE in a step-by-step guide, this would be really awesome!
For .NET Framework 4.5
ILMerge.exe /target:winexe /targetplatform:"v4,C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /out:finish.exe insert1.exe insert2.dll
ILMerge
Open CMD and cd to your directory. Let's say: cd C:\test
Insert the above code.
/out:finish.exe replace finish.exe with any filename you want.
Behind the /out:finish.exe you have to give the files you want to be
combined.
Use Costura.Fody.
You just have to install the nuget and then do a build. The final executable will be standalone.
Download ilmerge and ilmergre gui . makes joining the files so easy
ive used these and works great
Reference the DLL´s to your Resources and and use the AssemblyResolve-Event to return the Resource-DLL.
public partial class App : Application
{
public App()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
Assembly thisAssembly = Assembly.GetExecutingAssembly();
//Get the Name of the AssemblyFile
var name = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
//Load form Embedded Resources - This Function is not called if the Assembly is in the Application Folder
var resources = thisAssembly.GetManifestResourceNames().Where(s => s.EndsWith(name));
if (resources.Count() > 0)
{
var resourceName = resources.First();
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName))
{
if (stream == null) return null;
var block = new byte[stream.Length];
stream.Read(block, 0, block.Length);
return Assembly.Load(block);
}
}
return null;
};
}
}
Download
ILMerge
Call
ilmerge /target:winexe /out:c:\output.exe c:\input.exe C:\input.dll
Install ILMerge
as the other threads tell you to
Then go to the installation folder, by default
C:\Program Files (x86)\Microsoft\ILMerge
Drag your Dll's and Exes to that folder
Shift-Rightclick in that folder and choose open command prompt
Write
ilmerge myExe.exe Dll1.dll /out:merged.exe
Note that you should write your exe first.
There you got your merged exe. This might not be the best way if your going to
do this multiple times, but the simplest one for a one time use, I would
recommend putting Ilmerge to your path.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
/* PUT THIS LINE IN YOUR CLASS PROGRAM MAIN() */
AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) => { if (arg.Name.StartsWith("YOURDLL")) return Assembly.Load(Properties.Resources.YOURDLL); return null; };
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
First add the DLL´s to your project-Resources. Add a folder "Resources"
2019 Update (just for reference):
Starting with .NET Core 3.0, this feature is supported out of the box. To take advantage of the single-file executable publishing, just add the following line to the project configuration file:
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
Now, dotnet publish should produce a single .exe file without using any external tool.
More documentation for this feature is available at https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md.
Also you can use ilmergertool at codeplex with GUI interface.
Here is the official documentation. This is also automatically downloaded at step 2.
Below is a really simple way to do it and I've successfully built my app using .NET framework 4.6.1
Install ILMerge nuget package either via gui or commandline:
Install-Package ilmerge
Verify you have downloaded it. Now Install (not sure the command for this, but just go to your nuget packages):
Note: You probably only need to install it for one of your solutions if you have multiple
Navigate to your solution folder and in the packages folder you should see 'ILMerge' with an executable:
\FindMyiPhone-master\FindMyiPhone-master\packages\ILMerge.2.14.1208\tools
Now here is the executable which you could copy over to your \bin\Debug (or whereever your app is built) and then in commandline/powershell do something like below:
ILMerge.exe myExecutable.exe myDll1.dll myDll2.dll myDlln.dll myNEWExecutable.exe
You will now have a new executable with all your libraries in one!
I answered a similar question for VB.NET. It shouldn't however be too hard to convert. You embedd the DLL's into your Ressource folder and on the first usage, the
AppDomain.CurrentDomain.AssemblyResolve event gets fired.
If you want to reference it during development, just add a normal DLL reference to your project.
Embedd a DLL into a project
NOTE: if you're trying to load a non-ILOnly assembly, then
Assembly.Load(block)
won't work, and an exception will be thrown:
more details
I overcame this by creating a temporary file, and using
Assembly.LoadFile(dllFile)
I Found The Solution Below are the Stpes:-
Download ILMerge.msi and Install it on your Machine.
Open Command Prompt
type cd C:\Program Files (x86)\Microsoft\ILMerge Preess Enter
C:\Program Files (x86)\Microsoft\ILMerge>ILMerge.exe /target:winexe /targetplatform:"v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319"
/out:NewExeName.exe SourceExeName.exe DllName.dll
For Multiple Dll :-
C:\Program Files (x86)\Microsoft\ILMerge>ILMerge.exe /target:winexe /targetplatform:"v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319"
/out:NewExeName.exe SourceExeName.exe DllName1.dll DllName2.dll DllName3.dll
The command should be the following script:
ilmerge myExe.exe Dll1.dll /target:winexe /targetplatform:"v4,c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" /out:merged.exe /out:merged.exe

Tesseract 3 (OCR) - .NET Wrapper

http://code.google.com/p/tesseractdotnet/
I am having a problem getting Tesseract to work in my Visual Studio 2010 projects. I have tried console and winforms and both have the same outcome. I have come across a dll by someone else who claims to have it working in VS2010:
http://code.google.com/p/tesseractdotnet/issues/detail?id=1
I am adding a reference to the dll which can be found in the attached to post 64 from the website above. Every time I build my project I get an AccessViolationException saying that an attempt was made to read or write protected memory.
public void StartOCR()
{
const string language = "eng";
const string TessractData = #"C:\Users\Joe\Desktop\tessdata\";
using (TesseractProcessor processor = new TesseractProcessor())
{
using (Bitmap bmp = Bitmap.FromFile(fileName) as Bitmap)
{
if (processor.Init(TessractData, language, (int)eOcrEngineMode.OEM_DEFAULT))
{
string text = processor.Recognize(bmp);
}
}
}
}
The access violation exception always points to if (processor.Init(TessractData, language, (int)eOcrEngineMode.OEM_DEFAULT)). I've seen a few suggestions to make sure the solution platform is set to x86 in the configuration manager and that the tessdata folder location is finished with trailing slash, to no avail. Any ideas?
It appeared to be the contents of the tessdata folder that was causing the problem. Obtained the tessdata folder from the first link and all is now working.
I have just completed a project with tesseract engine 3. i think, there is a bug in the engine, that need to be rectified. What i Did to remove "AccessViolationError" is, add "\tessdata" to the real tessdata directory string. I don't know why, but the engine seems to be truncating the innermost directory in the Tessdata path.
Just made Full OCR package (Dlls+Tessdata(english)) that works with .net framework 4.
If somebody has the same problem and advice with trailing slash doesn't work, try... TWO ending slashes! Seriosly. It works for me.
if (processor.Init(#".\tessdata\\", "eng", (int)eOcrEngineMode.OEM_DEFAULT))
Seems your problem relates to stability issue mentioned here. On the official site there is a recommendation to use previous stable release 2.4.1. You can install it from nuget.org via the package manager command: Install-Package Tesseract -Version 2.4.1

How can I load this file into an NUnit Test?

I have the following IntegrationTest project structure ...
If i wish to use that test data 126.txt in an NUnit Test, how do I load that plain txt file data?
NOTE: The file is -linked- and I'm using c# (as noted by the image).
cheers :)
You could specify in the properties of the file to be copied to the output folder and inside the unit test:
string text = File.ReadAllText(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "126.txt"));
As an alternative you could embed this file as a resource into the test assembly and then:
var assembly = Assembly.GetExecutingAssembly();
using (var stream = assembly.GetManifestResourceStream("ProjectName.Tests.IntegrationTests.TestData.126.txt"))
using (var reader = new StreamReader(stream))
{
string text = reader.ReadToEnd();
}
If you do not want the files as ManifestResources, but just as file on the system. See Trouble with NUnit when determining the assembly's directory for more info and this answer in particular
Also interesting is the info from NUnit https://bugs.launchpad.net/nunit-vs-adapter/+bug/1084284/comments/3
But here is the quick info:
Path.Combine(TestContext.CurrentContext.TestDirectory, #"Files\test.pdf")
Where Files\test.PDF is just a file in your test project, with build action content and copy to output directory copy if newer
All credits go out to the people in the other post, but took me a while to find that answer, and that is the reason why i am adding the answer to this post.
This question is currently answered, but for googlers searching for other possibilities:
If you get a DirectoryNotFoundException because the test is looking in C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common... rather than in bin\Debug\..., it means your test adapter is executing from a path that isn't your test project output directory.
To solve this, you can get that bin\Debug\... directory by looking for the directory of the test DLL like so:
using System.IO;
using System.Reflection;
// Get directory of test DLL
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// dir is now "C:\...\bin\Debug" or wherever the executable is running from
I threw that in a TestHelpers static class in the test project so that I can use it in every test that needs to load external files.
Code is courtesy of this answer.
Found a gotcha with using TestContext.CurrentContext.TestDirectory. This works perfectly in a Setup, but when I call it from within a method supplied to a TestCaseSource, the static method is called before all other code, and returns the following:
C:\Users\<username>\.nuget\packages\nunit\3.10.1\lib\netstandard2.0
However, using TestContext.CurrentContext.WorkDirectory gives the desired result in both places:
C:\SVN\MyApp\trunk\MyApp.Tests\bin\Debug\netcoreapp2.1

SharpSVN Path Problem

Having a problem with SharpSVN (1.5 and 1.6) checking out code. (Note, I also have Tortoise 1.5 installed on my machine)
This same code has worked previously, so I don't know why things might have broken.
using (SvnClient client = new SvnClient())
{
SvnUriTarget url = new SvnUriTarget(checkoutURL.ToString());
client.Authentication.DefaultCredentials = new NetworkCredential(userName, password);
return client.CheckOut(url, destinationPath, out result); //error happens here
}
This code pulls Down a copy from SVN. It creates a copy into a directory named Sandbox.
Nothing has changed (except my own System configuration, I'll get to that in a minute), however, now I get the error:
SharpSvn.SvnException:
Can't open file '..\..\..\TestHarness\Sandbox\testBuild\Trunk\TestProjects\XX\Source\XX.TestHarness\Tests\Service\_svn\tmp\text-base\IViewProject_Tester.cs.svn-base':
The system cannot find the path specified.
Now this is crazy. This has pulled down fine before. For it to tell me to run "Cleanup" insinuates that there was a working copy there previously!
Also, you can also see that SharpSVN thinks that the .cs file is inside the _svn directory!
About my setup..
my system has Tortoise 1.5 on it (after downgrading from Tortoise 1.6 to see if I could fix this problem.. no go..
since I am a .net developer, I did set up Tortoise to use _svn folders
Any clues? Even questions are welcome..
ok,
Apparently this is an unresolvable bug that is tied to the max length for relative file paths in Windows.
Bert Huijben answers the issue pretty well here.
http://sharpsvn.open.collab.net/ds/viewMessage.do?dsForumId=728&dsMessageId=331173
Solution: Ditch the relative path and Use a Fully Qualified path

Categories