Skip to content

Instantly share code, notes, and snippets.

@lilxyzw
Last active July 15, 2025 14:26
Show Gist options
  • Select an option

  • Save lilxyzw/66c3c7e6d176e770116ac54dd72aeaeb to your computer and use it in GitHub Desktop.

Select an option

Save lilxyzw/66c3c7e6d176e770116ac54dd72aeaeb to your computer and use it in GitHub Desktop.
有料パッケージをvpmでインストールしたい場合になんとかできるかもしれないやつです。"ブラウザで"zipをダウンロード後、パッケージのフォルダ内を空っぽにしzipの中身を展開し不要になったダウンロードファイルを削除します。
// This code is licensed under CC0 1.0 Universal.
// https://creativecommons.org/publicdomain/zero/1.0/
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using UnityEditor;
namespace _PACKAGENAME_.downloader
{
internal static class Downloader
{
const string PACKAGE_DIRECTORY = "Packages/_PACKAGENAME_";
const string URL = "_URL_";
const string FILE_NAME = "_FILE_NAME_";
const int TIMEOUT_SECONDS = 120;
const int INTERVAL_SECONDS = 1;
[InitializeOnLoadMethod]
private static void Main()
{
if (File.Exists("Temp/downloaded__PACKAGENAME_"))
{
File.Delete("Temp/downloaded__PACKAGENAME_");
AssetDatabase.AllowAutoRefresh();
AssetDatabase.Refresh();
return;
}
if (File.Exists("Temp/downloading__PACKAGENAME_"))
{
return;
}
DoTask();
}
static async void DoTask()
{
File.Create("Temp/downloading__PACKAGENAME_");
string downloadFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");
Process.Start(new ProcessStartInfo(URL) { UseShellExecute = true });
string downloadedFile = await WaitForDownload(downloadFolder, DateTime.Now);
if (!string.IsNullOrEmpty(downloadedFile))
{
AssetDatabase.DisallowAutoRefresh();
foreach (var path in Directory.GetFiles(PACKAGE_DIRECTORY, "*", SearchOption.AllDirectories)) File.Delete(path);
ZipFile.ExtractToDirectory(downloadedFile, PACKAGE_DIRECTORY);
File.Delete(downloadedFile);
File.Delete("Temp/downloading__PACKAGENAME_");
File.Create("Temp/downloaded__PACKAGENAME_");
AssetDatabase.AllowAutoRefresh();
AssetDatabase.Refresh();
}
else
{
throw new Exception("Download timed out or file not found.");
}
}
private static async Task<string> WaitForDownload(string folder, DateTime afterTime)
{
int elapsed = 0;
while (elapsed < TIMEOUT_SECONDS)
{
var files = Directory.GetFiles(folder, FILE_NAME)
.Select(f => new FileInfo(f))
.Where(f => f.CreationTime >= afterTime && !IsLocked(f))
.OrderByDescending(f => f.CreationTime);
if (files.Any())
return files.First().FullName;
await Task.Delay(INTERVAL_SECONDS * 1000);
elapsed += INTERVAL_SECONDS;
}
return null;
}
private static bool IsLocked(FileInfo file)
{
try
{
using FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
return false;
}
catch (IOException)
{
return true;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment