本帖最后由 shujh1989 于 2025-8-2 14:51 编辑
最近有点无聊。第一次写.net版本的插件,可以显示当前城市的天气。apikey在高德可以免费申请。
网友答: 你们把CAD玩坏了。有点不务正业了。网友答: 看来是个高手,都已经会异步了,
不过少了一个缓存层,当天应该不要重复去取.网友答: 效果什么样子的啊网友答:
,惭愧,用ai写的程序拼的。ai一步一步教出来的,刚刚知道怎么编译程序。网友答:
本帖最后由 你有种再说一遍 于 2025-8-8 23:06 编辑
那你用AI的话,就需要继续追问了,
异步用不好的话会有奇特的效果.
例如Task就必须要await,
不然在独立进程下,启动后执行一半任务就死亡的线程.
任务即使完成了,但是由于没有设置信号机制,
导致它结束连接数据库失败而空转,出现隐藏bug,泄漏资源.
网友答: 玩的6啊


网友答:
厉害厉害,支持分享网友答:
可以,虽然槽点太多了,这篇文章最有用的地方是,知道了高德可以申请免费api网友答:
直接显示在状态栏更好一些
最近有点无聊。第一次写.net版本的插件,可以显示当前城市的天气。apikey在高德可以免费申请。

- using Autodesk.AutoCAD.Runtime;
- using Autodesk.AutoCAD.ApplicationServices;
- using System.Windows;
- using System.Net.Http;
- using Newtonsoft.Json;
- using System.Threading.Tasks;
- using System.Windows.Controls;
- using System.Windows.Media;
- using System;
- public class WeatherPlugin : IExtensionApplication
- {
- private static Window weatherWindow;
- public void Initialize()
- {
- Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nWeather Plugin Initialized\n");
- }
- public void Terminate()
- {
- if (weatherWindow != null)
- {
- weatherWindow.Close();
- }
- }
- [CommandMethod("WTR")]
- public async void ShowWeatherCommand()
- {
- if (weatherWindow != null)
- {
- weatherWindow.Close();
- }
- weatherWindow = new Window
- {
- Title = "当前天气",
- Width = 400,
- Height = 300,
- WindowStartupLocation = WindowStartupLocation.CenterScreen,
- Topmost = true,
- ResizeMode = ResizeMode.CanResizeWithGrip
- };
- var stackPanel = new StackPanel
- {
- Margin = new Thickness(10),
- Background = Brushes.White
- };
- var cityLabel = new Label { Content = "请输入城市:" };
- var cityTextBox = new TextBox { Width = 200, Margin = new Thickness(0, 5, 0, 5) };
- var getWeatherButton = new Button
- {
- Content = "获取天气",
- Width = 100,
- Margin = new Thickness(0, 5, 0, 5)
- };
- var weatherInfo = new Label { Content = "正在加载您的位置天气...", Margin = new Thickness(0, 5, 0, 5) };
- stackPanel.Children.Add(cityLabel);
- stackPanel.Children.Add(cityTextBox);
- stackPanel.Children.Add(getWeatherButton);
- stackPanel.Children.Add(weatherInfo);
- weatherWindow.Content = stackPanel;
- getWeatherButton.Click += async (s, e) =>
- {
- string city = cityTextBox.Text.Trim();
- if (!string.IsNullOrEmpty(city))
- {
- weatherInfo.Content = "正在加载...";
- try
- {
- string weatherData = await GetWeatherData(city);
- weatherInfo.Content = weatherData;
- }
- catch (System.Exception ex)
- {
- weatherInfo.Content = $"错误: {ex.Message}";
- }
- }
- else
- {
- weatherInfo.Content = "请输入城市名称。";
- }
- };
- try
- {
- string city = await GetCityFromIP();
- string weatherData = await GetWeatherData(city);
- weatherInfo.Content = weatherData;
- cityTextBox.Text = city;
- }
- catch (System.Exception ex)
- {
- weatherInfo.Content = $"加载本地天气失败: {ex.Message}";
- }
- Autodesk.AutoCAD.ApplicationServices.Core.Application.ShowModelessWindow(weatherWindow);
- }
- private async Task<string> GetCityFromIP()
- {
- try
- {
- using (var client = new HttpClient())
- {
- client.Timeout = TimeSpan.FromSeconds(10);
- string apiKey = "你申请的APIKey"; // 替换为实际的高德地图Web服务API Key
- string url = $"https://restapi.amap.com/v3/ip?key={apiKey}";
- var response = await client.GetAsync(url);
- response.EnsureSuccessStatusCode();
- string json = await response.Content.ReadAsStringAsync();
- System.Diagnostics.Debug.WriteLine(json); // 调试输出JSON
- var locationData = JsonConvert.DeserializeObject<IPLocationResponse>(json);
- // 检查API状态
- if (locationData.Status != "1")
- {
- throw new System.Exception($"IP定位失败: {locationData.Info}");
- }
- // 返回adcode
- if (!string.IsNullOrEmpty(locationData.Adcode))
- {
- return locationData.Adcode; // 返回adcode,如 "110101"
- }
- throw new System.Exception("未获取到城市adcode");
- }
- }
- catch (System.Exception ex)
- {
- System.Diagnostics.Debug.WriteLine($"GetCityFromIP 错误: {ex.Message}");
- return "110101"; // 默认返回北京东城区的adcode
- }
- }
- // 定义强类型类以解析高德IP定位API的JSON响应
- public class IPLocationResponse
- {
- public string Status { get; set; }
- public string Info { get; set; }
- public string Infocode { get; set; }
- public string Province { get; set; }
- public string City { get; set; }
- public string Adcode { get; set; }
- public string Rectangle { get; set; }
- }
- private async Task<string> GetWeatherData(string city)
- {
- string apiKey = "你申请的API Key"; // 替换为实际Key
- string url = $"https://restapi.amap.com/v3/weather/weatherInfo?city={city}&key={apiKey}&extensions=base&output=JSON";
- try
- {
- using (var client = new HttpClient())
- {
- client.Timeout = TimeSpan.FromSeconds(10);
- var response = await client.GetAsync(url);
- response.EnsureSuccessStatusCode();
- string json = await response.Content.ReadAsStringAsync();
- System.Diagnostics.Debug.WriteLine(json); // 调试输出JSON
- // 使用强类型解析JSON,增加可靠性
- var weatherData = JsonConvert.DeserializeObject<WeatherResponse>(json);
- // 检查API状态
- if (weatherData.Status != "1")
- {
- throw new System.Exception($"API错误: {weatherData.Info} (infocode: {weatherData.Infocode})");
- }
- // 检查lives数组是否存在且不为空
- if (weatherData.Lives == null || weatherData.Lives.Length == 0)
- {
- throw new System.Exception("未找到天气数据,请检查城市编码或名称");
- }
- // 获取实况天气数据
- var liveWeather = weatherData.Lives[0];
- return $"城市 {liveWeather.City} 的天气:\n" +
- $"状况: {liveWeather.Weather}\n" +
- $"温度: {liveWeather.Temperature}°C\n" +
- $"湿度: {liveWeather.Humidity}%\n" +
- $"风向: {liveWeather.Winddirection}\n" +
- $"风力: {liveWeather.Windpower}级\n" +
- $"数据更新时间: {liveWeather.Reporttime}";
- }
- }
- catch (HttpRequestException ex)
- {
- throw new System.Exception($"网络错误: {ex.Message}");
- }
- catch (TaskCanceledException)
- {
- throw new System.Exception("请求超时");
- }
- catch (JsonException ex)
- {
- throw new System.Exception($"JSON解析失败: {ex.Message}");
- }
- catch (System.Exception ex)
- {
- throw new System.Exception($"获取天气数据失败: {ex.Message}");
- }
- }
- // 定义强类型类以解析JSON
- public class WeatherResponse
- {
- public string Status { get; set; }
- public string Count { get; set; }
- public string Info { get; set; }
- public string Infocode { get; set; }
- public LiveWeather[] Lives { get; set; }
- }
- public class LiveWeather
- {
- public string Province { get; set; }
- public string City { get; set; }
- public string Adcode { get; set; }
- public string Weather { get; set; }
- public string Temperature { get; set; }
- public string Winddirection { get; set; }
- public string Windpower { get; set; }
- public string Humidity { get; set; }
- public string Reporttime { get; set; }
- public string Temperature_float { get; set; }
- public string Humidity_float { get; set; }
- }
- }
网友答: 你们把CAD玩坏了。有点不务正业了。网友答: 看来是个高手,都已经会异步了,
不过少了一个缓存层,当天应该不要重复去取.网友答: 效果什么样子的啊网友答:
你有种再说一遍 发表于 2025-8-2 16:14
看来是个高手,都已经会异步了,
不过少了一个缓存层,当天应该不要重复去取.
,惭愧,用ai写的程序拼的。ai一步一步教出来的,刚刚知道怎么编译程序。网友答:
本帖最后由 你有种再说一遍 于 2025-8-8 23:06 编辑 shujh1989 发表于 2025-8-2 17:28
,惭愧,用ai写的程序拼的。ai一步一步教出来的,刚刚知道怎么编译程序。
那你用AI的话,就需要继续追问了,
异步用不好的话会有奇特的效果.
例如Task就必须要await,
不然在独立进程下,启动后执行一半任务就死亡的线程.
任务即使完成了,但是由于没有设置信号机制,
导致它结束连接数据库失败而空转,出现隐藏bug,泄漏资源.
网友答: 玩的6啊



网友答:
厉害厉害,支持分享网友答:
可以,虽然槽点太多了,这篇文章最有用的地方是,知道了高德可以申请免费api网友答:
直接显示在状态栏更好一些