Search code examples
c#system.io.filesystem.io.directory

TextWriter not working because its being used by another process. Network 5.0


I am trying to create a console app on network version 5.0 using visual studio. The purpose is to read all the PNG files in a directory, and make a JSON file with the code:

{
    "format_version": "1.16.100",
    "minecraft:texture_set": {
        "color": "*Filename*",
        "metalness_emissive_roughness": "*Filename_mer*"
    }
}

In it. And yes this is for Minecraft. The filename and the filename_mer are automatically filled in by code, but that isn't my issue.

    static void Main(string[] args)
    {
        Console.WriteLine("Goto " + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Packages\\Microsoft.MinecraftUWP_8wekyb3d8bbwe\\LocalState\\games\\com.mojang\\resource_packs" + " And find the resource pack you want to generate files into");
        string pathname = Console.ReadLine();
        #region Message
        Console.WriteLine();
        Console.WriteLine("Looking for folder...");
        #endregion
        string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Packages\\Microsoft.MinecraftUWP_8wekyb3d8bbwe\\LocalState\\games\\com.mojang\\resource_packs\\" + pathname + "\\textures";
        #region Message
        Console.WriteLine();
        Console.WriteLine("Folder found in");
        Console.WriteLine(path);
        #endregion
        string[] directories = Directory.GetDirectories(path);
        foreach (string paths in directories)
        {
            string[] files = Directory.GetFiles(paths);
            foreach (string file in files)
            {
                string filenameWithType = file.Substring(file.LastIndexOf("\\") + 1);
                string filename = filenameWithType.Substring(0, filenameWithType.LastIndexOf("."));
                string thisPath = file.Substring(0, file.LastIndexOf("\\"));
                if (filenameWithType.Substring(filenameWithType.LastIndexOf(".") + 1) == "png")
                {
                    string newPath = thisPath + "\\" + filename + ".texture_set.json";
                    File.Create(newPath);
                    List<string> codeInFile = new List<string>();
                    codeInFile.Clear();
                    codeInFile.Add("{");
                    codeInFile.Add("\"format_version\": \"1.16.100\",");
                    codeInFile.Add("\"minecraft:texture_set\": {");
                    codeInFile.Add("\"color\": \"" + filename + "\",");
                    codeInFile.Add("\"metalness_emissive_roughness\": \"" + filename + "_mer\"");
                    codeInFile.Add("}");
                    codeInFile.Add("}");
                    TextWriter tw = new StreamWriter(newPath, false);
                    foreach (string line in codeInFile)
                    {
                        tw.WriteLine(line);
                        Console.WriteLine(line);
                    }
                    tw.Close();
                    string newPathtxt = thisPath + "\\" + filename + "_mer.png";
                    Bitmap bitmap = new Bitmap(file);
                    using (Bitmap b = new Bitmap(bitmap.Width, bitmap.Height))
                    {
                        using (Graphics g = Graphics.FromImage(b))
                        {
                            g.Clear(Color.Green);
                        }
                        b.Save(newPathtxt, ImageFormat.Png);
                    }
                }
            }
        }
        #region Message
        Console.WriteLine("");
        Console.WriteLine("All done, Your good to go!");
        #endregion
        Console.Read();
    }

This is all my code, on the file. It reads a directory which you enter, looks through the textures file, and for each PNG file in there it creates a JSON file with the code specified earlier. Although when run the code gives me this error.

    System.IO.IOException: 'The process cannot access the file 'C:\Users\https\AppData\Local\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang\resource_packs\Vanilla_Resource_Pack_1.17.10\textures\blocks\acacia_trapdoor.texture_set.json' because it is being used by another process.'

I cannot find any answers which fit my issue, I would appreciate any help.

This is a Minecraft Bedrock edition resource pack btw, not sure if that helps.


Solution

  • Don't do this File.Create(newPath); or rethink your problem. It looks like a typo.

    In short File.Create(newPath) is creating a FileStream and discarding it, leaving the file open and with a share lock. If you are trying to pre-create the file, at least use the using statement:

    using (File.Create(newPath));
    

    or Close

    File.Create(newPath).Close();
    

    or

    File.WriteAllText(newPath, String.Empty);
    

    or

    File.WriteAllBytes(newPath, Array.Empty<byte>());
    

    If you are just trying to create or overwrite the file StreamWriter(newPath, false) is good enough.