diff --git a/TfsExcelImporter/MainFormUi.cs b/TfsExcelImporter/MainFormUi.cs
index a7bb14b..ad77a36 100644
--- a/TfsExcelImporter/MainFormUi.cs
+++ b/TfsExcelImporter/MainFormUi.cs
@@ -276,7 +276,7 @@ namespace TfsExcelImporter
_fExcel = NewField(_txtExcel, 500, true);
_fParent = NewField(_txtParentPbi, 150, true);
- _btnLoadIterations = NewButton("加载迭代列表", BtnKind.Secondary, IconKind.Sync, 130);
+ _btnLoadIterations = NewButton("加载迭代列表", BtnKind.Secondary, IconKind.Fetch, 130);
_btnBrowse = NewButton("浏览…", BtnKind.Secondary, IconKind.Folder, 92);
_btnTemplate = NewButton("导出 Excel 模板", BtnKind.Secondary, IconKind.Doc, 142);
_chkSkip = NewCheck("跳过已存在标题", "");
@@ -454,7 +454,7 @@ namespace TfsExcelImporter
_cardAdv.ShowBadge = false;
_fArea = NewField(_txtAreaPath, 420, true);
_btnFixArea = NewButton("按迭代修 Area", BtnKind.Secondary, IconKind.Wrench, 158);
- _btnLinkParent = NewButton("补挂父项", BtnKind.Secondary, IconKind.ArrowUp, 120);
+ _btnLinkParent = NewButton("补挂父项", BtnKind.Secondary, IconKind.Tree, 120);
int y = _cardAdv.HeaderH + Theme.S12;
y = Row(_cardAdv, y, 52, "Area 路径", _fArea, "改 Area 与补挂父项都按上面的「目标迭代」筛选已有工作项");
diff --git a/TfsExcelImporter/Theme.cs b/TfsExcelImporter/Theme.cs
index e23dec2..6c73645 100644
--- a/TfsExcelImporter/Theme.cs
+++ b/TfsExcelImporter/Theme.cs
@@ -199,10 +199,14 @@ namespace TfsExcelImporter
internal enum IconKind
{
- None, ChevronDown, ChevronRight, Check, Bolt, Folder, Doc, ArrowUp, Wrench, Trash, Table, Gear, Sync
+ None, ChevronDown, ChevronRight, Check, Bolt, Folder, Doc, ArrowUp, Wrench, Trash, Table, Gear, Fetch, Tree
}
- /// GDI+ 矢量图标:统一 24 网格、约 1.6 描边、圆头。界面内不用 emoji、不用位图。
+ ///
+ /// GDI+ 矢量图标:统一 24 网格、约 2 描边、圆头圆角。界面内不用 emoji、不用位图。
+ /// 这条流水线的图标实际只有 14~16px,所以几何一律「少笔画、留大间隙」:
+ /// 细节(桶身竖纹、齿轮齿)在小尺寸会糊成一坨,宁可省略也不用 2 个网格以内的短笔画。
+ ///
internal static class Icons
{
public static void Draw(Graphics g, IconKind kind, Rectangle box, Color color)
@@ -215,7 +219,10 @@ namespace TfsExcelImporter
float ox = box.X + (box.Width - side) / 2f;
float oy = box.Y + (box.Height - side) / 2f;
- using (var pen = new Pen(color, Math.Max(1.2f, 1.7f * k)))
+ // 描边随尺寸线性走(24 网格 2px),最小 1.35 保证 14px 下不断线
+ float stroke = Math.Max(1.35f, 2f * k);
+ using (var pen = new Pen(color, stroke))
+ using (var brush = new SolidBrush(color))
{
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
@@ -223,69 +230,127 @@ namespace TfsExcelImporter
switch (kind)
{
case IconKind.ChevronDown:
- Poly(g, pen, ox, oy, k, 6, 9, 12, 15, 18, 9);
+ Poly(g, pen, ox, oy, k, 6.2f, 9.2f, 12f, 15f, 17.8f, 9.2f);
break;
case IconKind.ChevronRight:
- Poly(g, pen, ox, oy, k, 9, 6, 15, 12, 9, 18);
+ Poly(g, pen, ox, oy, k, 9.2f, 6.2f, 15f, 12f, 9.2f, 17.8f);
break;
case IconKind.Check:
- Poly(g, pen, ox, oy, k, 5, 13, 10, 18, 19, 6);
+ Poly(g, pen, ox, oy, k, 4.8f, 12.6f, 9.6f, 17.4f, 19.2f, 6.6f);
break;
- case IconKind.Bolt:
- Poly(g, pen, ox, oy, k, 13, 3, 6, 13, 12, 13, 11, 21, 18, 11, 12, 11, 13, 3);
+ case IconKind.Bolt: // 实心:14px 下描边闪电会糊成一根棍
+ Fill(g, brush, ox, oy, k, 13.2f, 2.4f, 4.8f, 13.4f, 10.4f, 13.4f,
+ 10.8f, 21.6f, 19.2f, 10.6f, 13.6f, 10.6f);
break;
case IconKind.Folder:
- Poly(g, pen, ox, oy, k, 3, 7, 9, 7, 11, 9, 21, 9, 21, 19, 3, 19, 3, 7);
+ Poly(g, pen, ox, oy, k, 2.8f, 6.4f, 9.4f, 6.4f, 11.4f, 8.6f,
+ 21.2f, 8.6f, 21.2f, 18.8f, 2.8f, 18.8f, 2.8f, 6.4f);
break;
case IconKind.Doc:
- Poly(g, pen, ox, oy, k, 6, 3, 15, 3, 19, 7, 19, 21, 6, 21, 6, 3);
- Poly(g, pen, ox, oy, k, 15, 3, 15, 7, 19, 7);
- Line(g, pen, ox, oy, k, 9, 12, 16, 12);
- Line(g, pen, ox, oy, k, 9, 16, 16, 16);
+ Poly(g, pen, ox, oy, k, 5.8f, 3f, 14.6f, 3f, 19f, 7.4f, 19f, 21f, 5.8f, 21f, 5.8f, 3f);
+ Poly(g, pen, ox, oy, k, 14.6f, 3f, 14.6f, 7.4f, 19f, 7.4f);
+ Line(g, pen, ox, oy, k, 8.8f, 12.2f, 16f, 12.2f);
+ Line(g, pen, ox, oy, k, 8.8f, 16.2f, 16f, 16.2f);
break;
case IconKind.ArrowUp:
- Line(g, pen, ox, oy, k, 12, 20, 12, 5);
- Poly(g, pen, ox, oy, k, 5, 12, 12, 5, 19, 12);
+ Line(g, pen, ox, oy, k, 12f, 20.4f, 12f, 5.2f);
+ Poly(g, pen, ox, oy, k, 5.8f, 11.4f, 12f, 5.2f, 18.2f, 11.4f);
break;
- case IconKind.Wrench:
- g.DrawArc(pen, ox + 3 * k, oy + 3 * k, 8 * k, 8 * k, 300f, 250f);
- Line(g, pen, ox, oy, k, 10, 14, 19, 21);
+ case IconKind.Wrench: // 实心开口扳手:环+手柄在 16px 下会读成放大镜,实心剪影才立得住
+ var wst = g.Save();
+ g.TranslateTransform(ox + 12f * k, oy + 12f * k);
+ g.RotateTransform(45f);
+ using (var path = new GraphicsPath())
+ {
+ path.AddPolygon(new[]
+ {
+ new PointF(-4.8f * k, -9.4f * k), new PointF(-1.7f * k, -9.4f * k),
+ new PointF(-1.7f * k, -6.2f * k), new PointF(1.7f * k, -6.2f * k),
+ new PointF(1.7f * k, -9.4f * k), new PointF(4.8f * k, -9.4f * k),
+ new PointF(4.8f * k, -4.4f * k), new PointF(2.2f * k, -1.6f * k),
+ new PointF(2.2f * k, 9.6f * k), new PointF(-2.2f * k, 9.6f * k),
+ new PointF(-2.2f * k, -1.6f * k), new PointF(-4.8f * k, -4.4f * k)
+ });
+ g.FillPath(brush, path);
+ }
+ g.Restore(wst);
break;
case IconKind.Trash:
- Poly(g, pen, ox, oy, k, 4, 7, 20, 7);
- Poly(g, pen, ox, oy, k, 8, 7, 8, 20, 16, 20, 16, 7);
- Line(g, pen, ox, oy, k, 11, 4, 13, 4);
+ Line(g, pen, ox, oy, k, 4.2f, 8.2f, 19.8f, 8.2f); // 盖
+ Line(g, pen, ox, oy, k, 9.4f, 4.2f, 14.6f, 4.2f); // 提手(与盖留 4 单位空隙)
+ Poly(g, pen, ox, oy, k, 6.8f, 8.2f, 6.8f, 20f, 17.2f, 20f, 17.2f, 8.2f); // 桶身
break;
case IconKind.Table:
- g.DrawRectangle(pen, ox + 3 * k, oy + 5 * k, 18 * k, 14 * k);
- Line(g, pen, ox, oy, k, 3, 10, 21, 10);
- Line(g, pen, ox, oy, k, 10, 10, 10, 19);
+ var tr = new RectangleF(ox + 2.8f * k, oy + 4.6f * k, 18.4f * k, 14.8f * k);
+ using (var path = Theme.RoundRect(tr, 2.2f * k)) g.DrawPath(pen, path);
+ Line(g, pen, ox, oy, k, 2.8f, 9.6f, 21.2f, 9.6f);
+ Line(g, pen, ox, oy, k, 10.4f, 9.6f, 10.4f, 19.4f);
break;
- case IconKind.Gear:
- g.DrawEllipse(pen, ox + 8 * k, oy + 8 * k, 8 * k, 8 * k);
- g.DrawEllipse(pen, ox + 10.5f * k, oy + 10.5f * k, 3 * k, 3 * k);
+ case IconKind.Gear: // 环 + 8 根短齿 + 实心轴:齿短一点才不会糊成太阳
+ for (int i = 0; i < 8; i++)
+ {
+ double a = i * Math.PI / 4;
+ Line(g, pen, ox, oy, k, 12f + (float)Math.Cos(a) * 5.2f, 12f + (float)Math.Sin(a) * 5.2f,
+ 12f + (float)Math.Cos(a) * 7.4f, 12f + (float)Math.Sin(a) * 7.4f);
+ }
+ g.DrawEllipse(pen, ox + 6.8f * k, oy + 6.8f * k, 10.4f * k, 10.4f * k);
+ g.FillEllipse(brush, ox + 10.2f * k, oy + 10.2f * k, 3.6f * k, 3.6f * k);
break;
- case IconKind.Sync: // 拉取服务器数据:带缺口的圆 + 箭头
- g.DrawArc(pen, ox + 4 * k, oy + 4 * k, 16 * k, 16 * k, 300f, 250f);
- Poly(g, pen, ox, oy, k, 19, 4, 20, 9, 15, 8);
+ case IconKind.Fetch: // 从服务器拉取(加载迭代列表):下箭头落进托盘,与「开始导入」的上箭头成对
+ // 圆形箭头在 16px 下始终读成「缺口的圈 + 一坨」,这里换直线几何;
+ // 托盘底边取 19.8 而不是 20.2,100%/125% 下都落在像素中心,不会渲成一条虚灰线
+ Line(g, pen, ox, oy, k, 12f, 3.4f, 12f, 12.2f);
+ Poly(g, pen, ox, oy, k, 6.4f, 7.4f, 12f, 13.2f, 17.6f, 7.4f);
+ Poly(g, pen, ox, oy, k, 5f, 14.6f, 5f, 19.8f, 19f, 19.8f, 19f, 14.6f);
+ break;
+ case IconKind.Tree: // 父项 + 两个子项:比链环更像「挂到父项下」,16px 也分得清
+ using (var node = Theme.RoundRect(new RectangleF(ox + 8.8f * k, oy + 2.6f * k, 6.4f * k, 5.2f * k), 1.4f * k))
+ using (var c1 = Theme.RoundRect(new RectangleF(ox + 2.6f * k, oy + 15.4f * k, 6.4f * k, 5.2f * k), 1.4f * k))
+ using (var c2 = Theme.RoundRect(new RectangleF(ox + 15f * k, oy + 15.4f * k, 6.4f * k, 5.2f * k), 1.4f * k))
+ {
+ g.FillPath(brush, node);
+ g.FillPath(brush, c1);
+ g.FillPath(brush, c2);
+ }
+ Line(g, pen, ox, oy, k, 12f, 7.8f, 12f, 12.4f);
+ Line(g, pen, ox, oy, k, 5.8f, 12.4f, 18.2f, 12.4f);
+ Line(g, pen, ox, oy, k, 5.8f, 12.4f, 5.8f, 15.4f);
+ Line(g, pen, ox, oy, k, 18.2f, 12.4f, 18.2f, 15.4f);
break;
}
}
g.SmoothingMode = old;
}
+ /// 圆徽标里画勾用的内缩盒子:铺满整个圆会贴边,视觉上像被裁掉一块。
+ public static Rectangle BadgeGlyph(Rectangle circle)
+ {
+ int inset = Math.Max(2, circle.Width * 2 / 11); // 22px 圆 → 4px 内缩(14px 盒子)
+ return Rectangle.Inflate(circle, -inset, -inset);
+ }
+
private static void Poly(Graphics g, Pen pen, float ox, float oy, float k, params float[] xy)
{
- var pts = new PointF[xy.Length / 2];
- for (int i = 0; i < pts.Length; i++)
- pts[i] = new PointF(ox + xy[i * 2] * k, oy + xy[i * 2 + 1] * k);
- g.DrawLines(pen, pts);
+ g.DrawLines(pen, Points(ox, oy, k, xy));
+ }
+
+ private static void Fill(Graphics g, Brush brush, float ox, float oy, float k, params float[] xy)
+ {
+ g.FillPolygon(brush, Points(ox, oy, k, xy));
}
private static void Line(Graphics g, Pen pen, float ox, float oy, float k, float x1, float y1, float x2, float y2)
{
g.DrawLine(pen, ox + x1 * k, oy + y1 * k, ox + x2 * k, oy + y2 * k);
}
+
+ private static PointF[] Points(float ox, float oy, float k, float[] xy)
+ {
+ var pts = new PointF[xy.Length / 2];
+ for (int i = 0; i < pts.Length; i++)
+ pts[i] = new PointF(ox + xy[i * 2] * k, oy + xy[i * 2 + 1] * k);
+ return pts;
+ }
}
internal enum BadgeKind { Pending, Active, Done, Warn }
@@ -329,7 +394,8 @@ namespace TfsExcelImporter
var r = new RectangleF(0.5f, 0.5f, Width - 1f, Height - 1f);
using (var b = new SolidBrush(fill)) g.FillEllipse(b, r);
g.SmoothingMode = old;
- if (Kind == BadgeKind.Done) Icons.Draw(g, IconKind.Check, ClientRectangle, ink);
+ // 勾画在圆内缩 4px(14px 盒子 / 22px 圆),铺满整圆会贴边看着像被裁掉
+ if (Kind == BadgeKind.Done) Icons.Draw(g, IconKind.Check, Icons.BadgeGlyph(ClientRectangle), ink);
else
TextRenderer.DrawText(g, Number.ToString(), Theme.CaptionBold, ClientRectangle, ink,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding);
@@ -505,7 +571,7 @@ namespace TfsExcelImporter
g.SmoothingMode = SmoothingMode.AntiAlias;
using (var b = new SolidBrush(badgeFill)) g.FillEllipse(b, badge);
g.SmoothingMode = old;
- if (Badge == BadgeKind.Done) Icons.Draw(g, IconKind.Check, badge, badgeInk);
+ if (Badge == BadgeKind.Done) Icons.Draw(g, IconKind.Check, Icons.BadgeGlyph(badge), badgeInk);
else
TextRenderer.DrawText(g, StepNumber.ToString(), Theme.CaptionBold, badge, badgeInk,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding);
@@ -575,7 +641,7 @@ namespace TfsExcelImporter
Width = Math.Max(Theme.Px(designMin), pad * 2 + gw + gap + Theme.TextWidth(Text, Font));
}
- private int GlyphWidth { get { return Glyph == IconKind.None ? 0 : Theme.Px(14); } }
+ private int GlyphWidth { get { return Glyph == IconKind.None ? 0 : Theme.Px(16); } }
private Color FaceColor
{
@@ -773,6 +839,10 @@ namespace TfsExcelImporter
/// 宿主右侧留给自绘箭头的区域,同时也是点击展开下拉的热区。
private int ArrowZone { get { return Theme.Px(26); } }
+ /// 内容左缘相对 _box 的缩进。TextBox 就摆在 Px(7),组合框闭合态文字必须共用同一基准,
+ /// 否则同一排的输入框文字会错开一条竖线。
+ private static int TextInsetX { get { return Theme.Px(7); } }
+
public InputField()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint
@@ -851,19 +921,30 @@ namespace TfsExcelImporter
// 闭合态就是普通输入框:白底黑字。焦点/校验态由宿主描边表达,
// 不响应 Selected 标记——否则一聚焦整块变浅蓝,还会把旁边的箭头衬成白色方块。
using (var b = new SolidBrush(Theme.Card)) e.Graphics.FillRectangle(b, full);
+ // 文字矩形不能直接用 e.Bounds:原生闭合区自带内缩(左侧约 2px、上沿同理),
+ // 且该内缩随 DPI 放大(150% 下实测 4px),照它画出来的文字会比同排 TextBox
+ // 右移、下沉 3~4px,看上去就是「没居中」。改成在 _box 坐标里定目标矩形
+ // (与 TextBox 共用 TextInsetX 基准),再换算到组合框客户区,DPI 无关。
+ // 额外再让 1px:原生那条「闭合区」裁剪边界正好压在文字起点上,贴着画会把首字
+ // 最左边的反锯齿列切掉("ntlm" 的 n 少半竖就是这个);顺带补上 TextBox 自身
+ // 1px 的 EM 内边距,两者文字才是同一条竖线。
+ var target = new Rectangle(TextInsetX + Theme.Px(1), 0,
+ Math.Max(0, _box.Width - TextInsetX - Theme.Px(1) - ArrowZone), _box.Height);
+ var textRect = cb.IsHandleCreated && _box.IsHandleCreated
+ ? cb.RectangleToClient(_box.RectangleToScreen(target))
+ : target;
TextRenderer.DrawText(e.Graphics, cb.GetItemText(cb.Items[e.Index]), cb.Font,
- new Rectangle(full.X, full.Y, Math.Max(0, full.Width - ArrowZone), full.Height),
- Theme.Ink,
+ textRect, Theme.Ink,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding
| TextFormatFlags.SingleLine | TextFormatFlags.EndEllipsis);
return;
}
using (var b = new SolidBrush(selected ? Theme.PrimarySoft : Theme.Card))
e.Graphics.FillRectangle(b, full);
- // 列表项贴着自己窗口的左沿,要补一段缩进才和输入框里的文字对齐;
- // 闭合态的组合框本身就摆在宿主内缩处,原生 bounds 已经带了这个缩进。
- int pad = inBox ? 0 : Theme.Px(10);
- int right = inBox ? ArrowZone : Theme.Px(6);
+ // 列表项贴着自己窗口的左沿(列表窗口对齐宿主外沿),要补上 _box 的 2px 内缩
+ // 和文字基准缩进,才和闭合态里的文字严格同一条竖线。
+ int pad = TextInsetX + 2;
+ int right = Theme.Px(6);
var text = new Rectangle(full.X + pad, full.Y,
Math.Max(0, full.Width - pad - right), full.Height);
TextRenderer.DrawText(e.Graphics, cb.GetItemText(cb.Items[e.Index]), cb.Font, text,
@@ -955,6 +1036,9 @@ namespace TfsExcelImporter
private void ToggleComboDropDown()
{
if (!_combo.IsHandleCreated) return;
+ // 先让组合框拿到焦点:没焦点就 CB_SHOWDROPDOWN,列表展开后随即被焦点变化收掉,
+ // 表现出来就是「点一下闪一下」。
+ if (!_combo.Focused) _combo.Focus();
bool dropped = SendMessage(_combo.Handle, CB_GETDROPPEDSTATE, IntPtr.Zero, IntPtr.Zero) != IntPtr.Zero;
SendMessage(_combo.Handle, CB_SHOWDROPDOWN, new IntPtr(dropped ? 0 : 1), IntPtr.Zero);
}
@@ -1040,14 +1124,19 @@ namespace TfsExcelImporter
}
private ComboListHook _listHook;
+ private IntPtr _listHwnd = IntPtr.Zero;
+ private bool _listSkinned;
/// ComboLBox 随组合框句柄一起创建,尽早挂上钩子,第一次下拉就不跳。
private void HookComboList()
{
- if (_listHook != null || _combo == null || !_combo.IsHandleCreated) return;
+ if (_combo == null || !_combo.IsHandleCreated) return;
var info = new ComboInfo();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(ComboInfo));
if (!GetComboBoxInfo(_combo.Handle, ref info) || info.hwndList == IntPtr.Zero) return;
+ if (_listHook != null && _listHook.Handle == info.hwndList) return; // 已挂在当前列表窗口上
+ // 列表窗口被重建过:旧钩子会留在已销毁的句柄上,必须换新的
+ if (_listHook != null) { _listHook.ReleaseHandle(); _listHook = null; }
_listHook = new ComboListHook(this);
_listHook.AssignHandle(info.hwndList);
}
@@ -1076,17 +1165,37 @@ namespace TfsExcelImporter
var info = new ComboInfo();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(ComboInfo));
if (!GetComboBoxInfo(_combo.Handle, ref info) || info.hwndList == IntPtr.Zero) return;
- int style = GetWindowLong(info.hwndList, GWL_STYLE);
- if ((style & WS_BORDER) != 0)
- SetWindowLong(info.hwndList, GWL_STYLE, style & ~WS_BORDER);
- int ex = GetWindowLong(info.hwndList, GWL_EXSTYLE);
- if ((ex & WS_EX_CLIENTEDGE) != 0)
- SetWindowLong(info.hwndList, GWL_EXSTYLE, ex & ~WS_EX_CLIENTEDGE);
+ // 列表窗口重建后边框会长回来,按句柄判断是否需要重新剥一次
+ if (_listHwnd != info.hwndList) { _listHwnd = info.hwndList; _listSkinned = false; }
+
+ bool skin = false;
+ if (!_listSkinned)
+ {
+ int style = GetWindowLong(info.hwndList, GWL_STYLE);
+ if ((style & WS_BORDER) != 0)
+ {
+ SetWindowLong(info.hwndList, GWL_STYLE, style & ~WS_BORDER);
+ skin = true;
+ }
+ int ex = GetWindowLong(info.hwndList, GWL_EXSTYLE);
+ if ((ex & WS_EX_CLIENTEDGE) != 0)
+ {
+ SetWindowLong(info.hwndList, GWL_EXSTYLE, ex & ~WS_EX_CLIENTEDGE);
+ skin = true;
+ }
+ _listSkinned = true;
+ }
RECT r;
if (!GetWindowRect(info.hwndList, out r)) return;
var host = RectangleToScreen(ClientRectangle);
+ // 位置已经被 ComboListHook 改写到宿主外沿时不要再 SetWindowPos:
+ // 每重摆一次列表窗口都要整窗重算重画,肉眼就是「打开瞬间闪一下」。
+ bool moved = r.Left != host.Left || r.Top != host.Bottom || (r.Right - r.Left) != host.Width;
+ if (!moved && !skin) return;
+ // 只有真的改了窗口样式才需要 SWP_FRAMECHANGED(它强制整窗重算非客户区)
SetWindowPos(info.hwndList, IntPtr.Zero, host.Left, host.Bottom,
- host.Width, r.Bottom - r.Top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ host.Width, Math.Max(0, r.Bottom - r.Top),
+ SWP_NOZORDER | SWP_NOACTIVATE | (skin ? SWP_FRAMECHANGED : 0));
}
protected override void OnPaint(PaintEventArgs e)
diff --git a/debug.log b/debug.log
index ebc7015..23c47b9 100644
--- a/debug.log
+++ b/debug.log
@@ -1,2 +1,4 @@
[1101/171941.143:ERROR:third_party\crashpad\crashpad\util\win\registration_protocol_win.cc:108] CreateFile: 系统找不到指定的文件。 (0x2)
[1101/173900.093:ERROR:third_party\crashpad\crashpad\util\win\registration_protocol_win.cc:108] CreateFile: 系统找不到指定的文件。 (0x2)
+[1101/184906.941:ERROR:third_party\crashpad\crashpad\util\win\registration_protocol_win.cc:108] CreateFile: 系统找不到指定的文件。 (0x2)
+[1101/191310.883:ERROR:third_party\crashpad\crashpad\util\win\registration_protocol_win.cc:108] CreateFile: 系统找不到指定的文件。 (0x2)