Create KMZ file from KML file Programatically in C# - c#

I have a number of kml file I am generating in a directory.
I am wondering if there is a way to group them all into a kmz file programmatically in C#. With a name and description displayed in google earth.
Thanks and best regards,
private static void combineAllKMLFilesULHR(String dirPath)
{
string kmzPath = "outputULHR.kmz";
string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string rootKml = appPath + #"\" + dirPath + #"\doc.kml";
Console.WriteLine(appPath + #"\"+ dirPath);
String[] filepaths = Directory.GetFiles(appPath + #"\" + dirPath);
using (ZipArchive archive = ZipFile.Open(kmzPath, ZipArchiveMode.Create))
{
archive.CreateEntryFromFile( rootKml, "doc.kml");
foreach (String file in filepaths)
{
Console.WriteLine(file);
if(!file.Equals(rootKml))
archive.CreateEntryFromFile( file, Path.GetFileName(file) );
}
}
}

Being a KMZ file a zip archive, you can use the ZipArchive class to generate it.
string kmzPath = "output.kmz";
string rootKml = "doc.kml";
string referencedKml = "someother.kml";
using (ZipArchive archive = ZipFile.Open(kmzPath, ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(rootKml, "doc.kml");
archive.CreateEntryFromFile(referencedKml, "someother.kml");
}
just remember to name the default kml as doc.kml, from the documentation:
Put the default KML file (doc.kml, or whatever name you want to give
it) at the top level within this folder. Include only one .kml file.
(When Google Earth opens a KMZ file, it scans the file, looking for
the first .kml file in this list. It ignores all subsequent .kml
files, if any, in the archive. If the archive contains multiple .kml
files, you cannot be sure which one will be found first, so you need
to include only one.)

Related

How do I add a resource folder to app data?

I have a folder that contains many png images in my resources of my WPF application. I would like to add this folder to appdata/roaming. Since there are many images that are sorted in folders, I would prefer to add the whole folder. Is there any way to do this?
By the way, the folder is in a directory called Resources and all the pngs are build as resources in Visual Studio.
Here is my code example for your question:
public void MyCopy()
{
//1.You can use the following code to get the path appdata/roaming, and suppose you want to copy the files to NewImageFolder
string strTarget = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString() + "\\NewImageFolder\\";
if (!Directory.Exists(strTarget))
{
Directory.CreateDirectory(strTarget);
}
//2. Then you need to get the path of your the File to be copied
string strSource = AppDomain.CurrentDomain.BaseDirectory;
strSource = strSource.Substring(0, strSource.LastIndexOf("bin")) + "Resources\\Image";
//3.Copy the file
DirectoryInfo dir = new DirectoryInfo(strSource);
FileInfo[] files = dir.GetFiles();
string strFileName = null;
foreach (FileInfo file in files)
{
strFileName = strSource + "\\" + file.Name;
File.Copy(strFileName, System.IO.Path.Combine(strTarget, System.IO.Path.GetFileName(strFileName)));
}
}

Get the filename of a file that was created through ZipFile.ExtractToDirectory()

string zipPath = #"D:\books\"+fileinfo.DccFileName;
string extractPath = #"D:\books";
System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);
This is a simple piece of code that does exactly what i want it to do: Gets a zip file from d:\books and unzips it into the same directory. Is there any way i can read the filename of the newly created file (considering that there is only one file in the .zip archive). I would prefer a solution that does not involve reading changes in the directory since other files might be created in it at the same time of the unzip.
You can construct the path by inspecting the archive
var intentedPath = string.Empty;
//open archive
using (var archive = ZipFile.OpenRead(zipPath)) {
//since there is only one entry grab the first
var entry = archive.Entries.First();
//the relative path of the entry in the zip archive
var fileName = entry.FullName;
//intended path once extracted would be
intentedPath = Path.Combine(extractPath, fileName);
}

C# -Make a zip file from List of file paths

I have a number of folders and I have number of file in each folders.
I am taking some of the file paths from different folders and I need to zip those files into a single zip file.
if I have the file in a single folder, I can do zip using
string startPath = #"c:\example\start";//folder to add
string zipPath = #"c:\example\result.zip";//URL for your ZIP file
ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Fastest, true);
string extractPath = #"c:\example\extract";//path to extract
ZipFile.ExtractToDirectory(zipPath, extractPath);
using (ZipArchive newFile = ZipFile.Open(zipName, ZipArchiveMode.Create))
{
foreach (string file in Directory.GetFiles(myPath))
{
newFile.CreateEntryFromFile(file);
}
}
Suppose I don't know about the folders, I only have a list of file paths, I need to foreach through each file path and add into the zip. What should I do for this?
You can enumerate all files in the directory include subdirectories with Directory.GetFiles overloading and SearchOption.AllDirectories option and then use it
String[] allfiles = System.IO.Directory.GetFiles("myPath", "*.*", System.IO.SearchOption.AllDirectories);
foreach (string file in allfiles)
{
newFile.CreateEntryFromFile(file);
}
You can use ZipFile.CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName) or its overload to create an archive in one step too.
Also there is a way to manipulate zip archive structure more flexibly via Path.GetDirectoryName() method. Here is the example:
foreach(var filePath in files)
{
var directory = Path.GetDirectoryName(filePath);
var fileName = Path.GetFileName(filePath);
var entry = archive.GetEntryFromFile(filePath, $"{directory}/{fileName}");
}
Finally, you can use 3rd party library DotNetZip and solve yor scenario in just 3 lines of code:
using (ZipFile zip = new ZipFile())
{
zip.AddFiles(files);
zip.Save("Archive.zip");
}
Using the DotNetZip library from newget manager, just check whether it will work or not
using (ZipFile zip = new ZipFile())
{
foreach(var filestring in AllFileArray)
{
zip.AddFile(filestring);
}
zip.save("MyZipFile.zip")
}

Enumerate zipped contents of unzipped folder

I am trying to enumerate the zipped folders that are inside an unzipped folder using Directory.GetDirectories(folderPath).
The problem I have is that it does not seem to be finding the zipped folders, when I come to iterate over the string[], it is empty.
Is Directory.GetDirectories() the wrong way to go about this and if so what method serves this purpose?
Filepath example: C:\...\...\daily\daily\{series of zipped folder}
public void CheckZippedDailyFolder(string folderPath)
{
if(folderPath.IsNullOrEmpty())
throw new Exception("Folder path required");
foreach (var folder in Directory.GetDirectories(folderPath))
{
var unzippedFolder = Compression.Unzip(folder + ".zip", folderPath);
using (TextReader reader = File.OpenText(unzippedFolder + #"\" + new DirectoryInfo(folderPath).Name))
{
var csv = new CsvReader(reader);
var field = csv.GetField(0);
Console.WriteLine(field);
}
}
}
GetDirectories is the wrong thing to use. Explorer lies to you; zip files are actually files with an extension .zip, not real directories on the file system level.
Look at:
https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive.entries%28v=vs.110%29.aspx (ZipArchive.Entries) and/or
https://msdn.microsoft.com/en-us/library/system.io.compression.zipfile%28v=vs.110%29.aspx (ZipFile) to see how to deal with them.

Add prefix to all file names in a folder with a certain extension using C#

I have 4 directories that host different files in them.
I currently have a form that if a certain checkbox is checked, it is suppose to go to that directory, and find all the pdf's in that directory and add a prefix to them.
for example, say folder 1 has 5 pdf's in them. i want it to go through and add "some prefix" to the file name.
Before: Filename
After: Some Prefix Filename
Get all the files in the directory using Directory.GetFiles
For each file create a new file path using parent directory path, prefix string and file name
Use File.Move to rename the file.
It should be like:
var files = Directory.GetFiles(#"C:\yourFolder", "*.pdf");
string prefix = "SomePrefix";
foreach (var file in files)
{
string newFileName = Path.Combine(Path.GetDirectoryName(file), (prefix + Path.GetFileName(file)));
File.Move(file, newFileName);
}
string path = "Some Directory";
string prefix = "Some Prefix";
foreach (var file in Directory.GetFiles(path, "*.pdf"))
{
var newName = Path.Combine(Path.GetDirectoryName(file), prefix + Path.GetFileName(file));
File.Move(file, newName);
}

Categories