I'm going to tell you a tale of a man and his zipper that wouldn't zip.
(the last [written] blog post was about how I automated building with a unity editor script. then i ran into a problem with zipping the folders. and now.....)
A few days ago, I was like Oooh. I bet I could write a batch script for zipping my files in like 20 minutes. That'll be cool. SPOILER ALERT I DIDNT END UP USING A BATCH SCRIPT AND YOU KNOW THAT IF U READ THE PREVIOUS BLOG POST BC I CLEARLY CALLED A ZIP FUNCTION FROM WITHIN A CSHARP SCRIPT BUT I WANT TO TELL THIS STORY: Bascially, I wanted to do two commands. (a) Remove old things from folder. (b) Zip up new things into folder. The first command was a lot like this line:
move Dropbox\Flock of Dogs\* Documents\FoDBuildStorage\RemovedFromDropbox
This command says move all files found at Dropbox\Flock of Dogs\ to the folder Documents\FoDBuildStorage\RemovedFromDropbox. Which works and is fine. Then I wanted there to exist some command like (this is my imaginary command below).
zip Documents\FoD Build Storage\CompletedBuilds\* Dropbox\Flock of DogsThen later I'd just figure out how to start this batch script from a c# script and then I could do all this zipping from an editor command inside Unity! I figured there'd be some easily accesible cmdlet or whatever, because it's so easy and accessible to just right click a file/folder in Explorer and click SendTo->Compressed Folder. But apparently, there's no way to do that through a normal batch script.
Turns out tho, that with the power of powershell (!), one can summon the powers of the native Windows compression (Although evne this wasn't possible until like 2013 or something when you had to use visual basic scrip or something or the GStream and idk what else, but 2013 has dfeinitely come and gone and so I had to decide if I wanted to learn powershell scripting.)
I briefly considered using 7-zip, which actually compresses things way better normally (this all made me feel very Pied Pipery). Trouble with 7-zip is that the end user would have to have it installed to unzip any FlockOfDogs_1.0_win.7z file.
Turns out extra tho, that executing powershell scripts requires certain authorization.
Internet forums msotly suggested disabling the requirement for authorization, which sounds like a sweeping, system wide change that could be very scary adn open my system up to vulnerabilities maybe that I know nothing about how to fix. So somebody said well, you don't have to turn it off universally, just when you call the powershll script, use this little ByPass flag, which lets you ByPass the ExecutionPolicy:
powershell -ExecutionPolicy ByPass -File MaxsPowershellScript.ps1
Which when I typed this into the command line, it worked. Which is what I did. But then I don't understand why somebody else's command line argument couldn't start a powershell script the same way? (Idk. more on that later.) Well, if they can, they can. And I am power(shell)less to stop them.
So now I could can run my powershell script, which is where I can properly zip things up. I'd never written a powershell script before, so that was kinda fun and went pretty well. A small issue was that to zip up the 3 newly made builds, my script had to identify them, or it would just act on every file within a folder that I, thru some other means, guarantee only has the newest builds in it, so I don't have to zip up the dozens of completed builds I have saved locally. So either I iterate thru all files in my completed builds folder and then zipping them up, using a destination name which matched their current file name (+ .zip on the end), or I needed a way to just identify the newly build builds. But what if my completed builds folder had more than the most recent builds in it? Do I want to always make sure that folder is clear too? How about, I just pass the dateStamp as an argument to identify the builds I want to zip up? So that meant learning how to pass a variable to a batch script and referencing it. Which for powershll meant using $ signs. (Batch scripts use %s).
Ok, so how do I run this from a c# script? Some googling taught me about c# being able to run processes thru Process.Start ()! You pass it the thing you want to run, in my case, cmd.exe (the command line!!!!). So if I can run the command line, I think I'm golden. And maybe I was. But it didn't work. And it kept not working. And then
i think the reason the process failed
So I read on a forum that years ago, c# didn't have a compression library. But with .NET 4.x framework, it does! It has System.IO.Compression.ZipFile (). And that function requires using the assembly System.IO.Compression.FileSystem.dll.
So I checked in Unity what .NET framekwork I was using (pretty sure it wasn't .net 4.x) and sure enough I had to update. So I cliked File->Build. Clicked Player Settings (bot left, see photo). Then in the "Other Settings", selected the .net 4.x options for script runtime version and api compatibility. It may have told me to restart. I don't remember.
So. Then, super excitedly, I typed
using System.IO.Compression;But disappointment. Red squiggly lines abounded. Online forums said you had to "add a reference" from insude Visual Studio.
So I clicked Project->Add Reference and selected System.IO.Compression and clicked ok.
NOTICE HOW THAT LITTLE WHITE BOX ON THE LEFT IS A BOX WITHOUT A CHECKMARK? Well, I opened this dialog box and clicked Ok and nothing happened like 4 times before I realized I had to check that little white box. This is a full confessional of my development process here. So after I checked that box. And the box for System.IO.Compression.FileSystem. Then Visual Studio was so happy!
Then I opened Unity. And Unity was not happy.
Unity was unhappy. Unity said these assemblies didn't exist. Watched some YouTube videos on how to make your own dll and add it to Unity. They just dragged and dropped it into their assets folder! I was like No Way. So then I was like...where's System.IO.Compression.dll on my system I have no idea!
Turns out that it was in the GAC (general assembly cache)! The internet eventually told me that is located at:
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.IO.CompressionAnd I copy/pasted them into my assets folder and voila.
It worked. Unity, VisualStudio, and me...all happy. But I shouldn't have been one hundred percent happy. You should never be 100% happy.
So I went to the OC Indies Meetup last night.
And I told the guys there about my drag and drop solution to adding .net assemblies and they were horrified. Well, not really horrified, but I could read between the lines. They lost all respect for me as a programmer.
Anyway, Tony, a fearless leader of our Meetup, found this thread:
Wherein the sad truth is revealed that through some bug, these particular assemblies fail to link properly or whatever. And if you just copy/paste them in, while it may work in the short term, it's liable to failing later with new versios of Unity. So...I'm pretty sure I'm getting close to the last version of Unity that I will use for Flock of Dogs, before having to risk breaking things when switching versions, but I'll probably go thru the Unity 2019 versions. So anyway. The thread has a simple solution.
1) Create a file and add the following lines:
-r:System.IO.Compression.dll2) Save this file as mcs.rsp
3) Step 2 was a trick, if you're using Unity 2018.3, you actually have to name the file csc.rsp.
4) Move the file into your Asset/ directory for your project.
5) What if I upgrade to later versions of Unity, will I have to change the file name back to msc.rsp? Did the Unity guy in the thread mean "for Unity 2018.3 and later"? I don't know.
There you go.
You have been qiuckly equipped with a hot .zip tip.