VB. NET 2010 - Извлечь / сохранить файл ICO из My.Resources - PullRequest
0 голосов
/ 03 августа 2020

Название говорит само за себя, как мне сохранить файл из ресурсов приложения, например, на рабочий стол?

В будущем он создаст каталог и сохранит его там, по сути, я делаю установщик игры, но сейчас все это не имеет значения.

Я пробовал около 6 различных методов кода, и все они терпели неудачу, продолжали выдавать ошибки о невозможности конвертировать значок / изображение в 1-dimensional array. Или что «Значок» или «Изображение» не является членом System.Drawing.Icon

Любая помощь будет принята с благодарностью!

РЕДАКТИРОВАТЬ: размещение кода, который я пробовал.

# 1 ('Length' не является членом System.Drawing.Icon)

Dim File01 As System.IO.FileStream = New System.IO.FileStream("C:\Users\" + Environment.UserName + "\Desktop\" + "EXAMPLE_Icon.ico", IO.FileMode.Create) File01.Write(My.Resources.EXAMPLE_Icon, 0, My.Resources.EXAMPLE_Icon.length) File01.Close()

# 2 ('System.Drawing.Icon' не может быть преобразован в ' 1-мерный массив байтов)

Dim filePath = Path.Combine("C:\Users\" + Environment.UserName + "\Desktop\", "EXAMPLE_Icon.ico") File.WriteAllBytes(filePath, My.Resources.EXAMPLE_Icon)

# 3 (RawFormat не является членом System.Drawing.Icon)

Dim filePath = Path.Combine("C:\Users\" + Environment.UserName + "\Desktop\", "EXAMPLE_Icon.ico") Using icon = My.Resources.EXAMPLE_Icon icon.Save("C:\Users\" + Environment.UserName + "\Desktop\", icon.RawFormat) End Using

1 Ответ

1 голос
/ 04 августа 2020
  • Создайте путь назначения, используя Path.Combine () , когда путь составлен.

  • Многие известные системные местоположения имеют предопределенные значение в Environment.SpecialFolder : в вашем случае Environment.SpecialFolder.Desktop. Environment.GetFolderPath () принимает одно из этих значений и возвращает правильный путь к файловой системе. Это возвращает путь к папке рабочего стола для текущего пользователя:

    Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
    
  • Объект Icon имеет метод Save () , который принимает Stream в качестве аргумента. Вы можете передать FileStream , чтобы сохранить значок в файл с сохранением его формата, или MemoryStream , а затем использовать File.WriteAllBytes () для сохранения MemoryStream's буфер, вызывающий свой метод ToArray().

Использование имени ресурса в виде строки с использованием ResourceManager.GetObject () :

Dim iconPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "myIcon.ico")

Using stream As New FileStream(iconPath, FileMode.Create, FileAccess.Write, FileShare.None),
    ico = TryCast(My.Resources.ResourceManager.GetObject("myIcon"), Icon)
    ico?.Save(stream)
End Using

Или, в зависимости от того, что лучше подходит в контексте ваших операций:

Using stream As New FileStream(iconPath, FileMode.Create, FileAccess.Write, FileShare.None)
    My.Resources.myIcon.Save(stream)
End Using
GC.Collect()

Примечание: здесь я звоню GC.Collect() после звонка Save() непосредственно на объекте Icon, созданном My.Resources. Документы точно не объясняют это: My.Resources - это фабрика, она не возвращает объект, хранящийся в ресурсах проекта , она генерирует новый объект (каждый раз другой) из данных хранится как ресурс. С помощью My.Resources.myIcon.Save(stream) мы создаем новый объект, сохраняем его данные на c, но никогда не удаляем его. При вызове GC.Collect() сразу после этого используемая память немедленно восстанавливается. Если мы этого не сделаем, эта память никогда не будет восстановлена ​​(мы утекаем ).

Вероятно, лучше назначить сгенерированный объект временной переменной, объявленной с помощью оператора Using. Следующие два метода могут использовать GC.Collect(), вызывая его сразу после, для немедленного освобождения выделенной памяти, но это не строго требуется, мы на самом деле не теряем ресурсы. Откройте Visual Studio Diagnostic Tools, чтобы протестировать поведение с GC.Collect() и без него, вызывая эти методы несколько раз.

Using stream As New FileStream(iconPath, FileMode.Create, FileAccess.Write, FileShare.None),
    ico = My.Resources.myIcon
    ico.Save(stream)
End Using
' GC.Collect()  <= Not strictly required, but test the difference

Или используя MemoryStream:

Using ms As New MemoryStream(),
    ico As Icon = My.Resources.myIcon
    ico.Save(ms)
    ms.Position = 0
    File.WriteAllBytes(iconPath, ms.ToArray())
End Using
' GC.Collect()  <= Not strictly required, but test the difference
...