Phase 17 완료 표시 (AGENT_ROADMAP.md 갱신): - 17-A1/A2: Reflexion 자기성찰 메모리 + 검증 강제 확대 - 17-B1/B2: TaskState Working Memory + AgentEventLog .jsonl 영속화 - 17-C1/C2/C3: 훅 11개 이벤트·4타입(Command/Http/Prompt/Agent) 완비 - 17-D1/D2/D3: 스킬 fork 격리·paths 자동활성화·user-invocable 필터 Phase 18 완료 표시: - 18-C2 (AiSnippetHandler), 18-C3 (QuickLinkHandler) 버전 v1.8.0 → v2.0.0: - AxCopilot.csproj, Installer.csproj, SetupForm.cs, McpClientService.cs DEVELOPMENT.md 버전 이력 v2.0.0 추가 Phase 17 섹션 헤더: 차기 개발 → ✅ 완료 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
325 lines
19 KiB
C#
325 lines
19 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using Microsoft.Win32;
|
|
|
|
namespace AxCopilot.Installer.Offline
|
|
{
|
|
public class SetupForm : Form
|
|
{
|
|
private const string AppName = "AX Copilot";
|
|
private const string AppVer = "2.0.0";
|
|
private const string Org = "AX\uC5F0\uAD6C\uC18C AI\uD300";
|
|
private const string RegUn = @"Software\Microsoft\Windows\CurrentVersion\Uninstall\AxCopilot";
|
|
private const string RegRun = @"Software\Microsoft\Windows\CurrentVersion\Run";
|
|
|
|
private TextBox _pathBox;
|
|
private Label _status, _existLbl;
|
|
private Panel _existPnl, _progPnl;
|
|
private ProgressBar _prog;
|
|
private CheckBox _chkDesk, _chkAuto, _chkReg;
|
|
private Button _btnInst, _btnCanc, _btnBrowse, _btnDel;
|
|
private string _exPath, _exVer;
|
|
|
|
private static readonly string DefPath = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "AX Copilot");
|
|
|
|
[DllImport("gdi32.dll")] static extern IntPtr CreateRoundRectRgn(int a,int b,int c,int d,int e,int f);
|
|
[DllImport("user32.dll")] static extern int SetWindowRgn(IntPtr h,IntPtr r,bool re);
|
|
|
|
public SetupForm()
|
|
{
|
|
Text = AppName + " Setup"; Size = new Size(520, 470);
|
|
StartPosition = FormStartPosition.CenterScreen;
|
|
try { var ico = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location); if (ico != null) Icon = ico; } catch { }
|
|
FormBorderStyle = FormBorderStyle.None; DoubleBuffered = true;
|
|
BackColor = Color.FromArgb(248, 249, 255);
|
|
Build(); Detect();
|
|
}
|
|
|
|
protected override void OnShown(EventArgs e)
|
|
{ base.OnShown(e); SetWindowRgn(Handle, CreateRoundRectRgn(0,0,Width,Height,20,20), true); }
|
|
|
|
// drag
|
|
private Point _ds; private bool _dg;
|
|
protected override void OnMouseDown(MouseEventArgs e) { if(e.Button==MouseButtons.Left&&e.Y<82){_dg=true;_ds=e.Location;} }
|
|
protected override void OnMouseMove(MouseEventArgs e) { if(_dg){var p=PointToScreen(e.Location);Location=new Point(p.X-_ds.X,p.Y-_ds.Y);} }
|
|
protected override void OnMouseUp(MouseEventArgs e) { _dg=false; }
|
|
protected override void OnMouseClick(MouseEventArgs e) { if(e.X>Width-40&&e.Y<30)Close(); }
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
var g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
var hr = new Rectangle(0,0,Width,82);
|
|
using(var hb = new LinearGradientBrush(hr, Color.FromArgb(46,58,140), Color.FromArgb(75,94,252), 0f))
|
|
g.FillRectangle(hb, hr);
|
|
|
|
// Diamond icon in header (둥근 모서리)
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
|
g.TranslateTransform(40, 30);
|
|
g.RotateTransform(45);
|
|
FillRoundRect(g, new SolidBrush(Color.FromArgb(68,136,255)), 0, 0, 9, 9, 2.5f); // 상: Blue
|
|
FillRoundRect(g, new SolidBrush(Color.FromArgb(68,221,102)), 11, 0, 9, 9, 2.5f); // 우: Green
|
|
FillRoundRect(g, new SolidBrush(Color.FromArgb(68,221,102)), 0, 11, 9, 9, 2.5f); // 좌: Green
|
|
FillRoundRect(g, new SolidBrush(Color.FromArgb(255,68,102)), 11, 11, 9, 9, 2.5f); // 하: Red
|
|
g.ResetTransform();
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
|
|
|
|
using(var f1 = new Font("Segoe UI",18f,FontStyle.Bold)) g.DrawString(AppName,f1,Brushes.White,60,16);
|
|
using(var f2 = new Font("Segoe UI",9f))
|
|
g.DrawString(Org + " \u00b7 v" + AppVer,
|
|
f2, new SolidBrush(Color.FromArgb(170,187,255)), 60, 50);
|
|
using(var fc = new Font("Segoe UI",14f)) g.DrawString("\u00d7",fc,new SolidBrush(Color.FromArgb(140,170,204,255)),Width-30,4);
|
|
using(var pen = new Pen(Color.FromArgb(220,220,240))) g.DrawLine(pen,0,Height-56,Width,Height-56);
|
|
}
|
|
|
|
private void Build()
|
|
{
|
|
int y = 94;
|
|
_existPnl = new Panel{Left=20,Top=y,Width=Width-40,Height=30,BackColor=Color.FromArgb(255,248,225),Visible=false};
|
|
_existLbl = new Label{Dock=DockStyle.Fill,ForeColor=Color.FromArgb(146,64,14),Font=new Font("Segoe UI",9f),
|
|
TextAlign=ContentAlignment.MiddleLeft,Padding=new Padding(8,0,0,0)};
|
|
_existPnl.Controls.Add(_existLbl); Controls.Add(_existPnl); y+=38;
|
|
|
|
Controls.Add(new Label{Text="\uC124\uCE58 \uACBD\uB85C",Left=24,Top=y,AutoSize=true,
|
|
Font=new Font("Segoe UI",9.5f,FontStyle.Bold),ForeColor=Color.FromArgb(51,51,102)}); y+=22;
|
|
_pathBox = new TextBox{Left=24,Top=y,Width=Width-110,Height=26,Font=new Font("Consolas",10f),
|
|
Text=DefPath,BorderStyle=BorderStyle.FixedSingle};
|
|
Controls.Add(_pathBox);
|
|
_btnBrowse = Btn("\uBCC0\uACBD",Color.FromArgb(238,240,255),Color.FromArgb(75,94,252),Width-80,y-1,56,28);
|
|
_btnBrowse.Click += (s,ev)=>{using(var d=new FolderBrowserDialog{SelectedPath=_pathBox.Text})
|
|
if(d.ShowDialog()==DialogResult.OK)_pathBox.Text=d.SelectedPath;};
|
|
Controls.Add(_btnBrowse); y+=34;
|
|
|
|
Controls.Add(new Label{Text="\uBCF8\uCCB4 + .NET Runtime \uBAA8\uB450 \uB0B4\uC7A5 (\uC778\uD130\uB137 \uBD88\uD544\uC694)",
|
|
Left=24,Top=y,AutoSize=true,
|
|
Font=new Font("Segoe UI",8f),ForeColor=Color.FromArgb(153,153,187)}); y+=24;
|
|
|
|
_chkDesk = Chk("\uBC14\uD0D5\uD654\uBA74 \uBC14\uB85C\uAC00\uAE30 \uC0DD\uC131",true,24,y); y+=24;
|
|
_chkAuto = Chk("Windows \uC2DC\uC791 \uC2DC \uC790\uB3D9 \uC2E4\uD589",true,24,y); y+=24;
|
|
_chkReg = Chk("\uD504\uB85C\uADF8\uB7A8 \uCD94\uAC00/\uC81C\uAC70\uC5D0 \uB4F1\uB85D",true,24,y); y+=36;
|
|
|
|
_progPnl = new Panel{Left=20,Top=y,Width=Width-40,Height=42,Visible=false};
|
|
_status = new Label{Dock=DockStyle.Top,Height=20,Font=new Font("Segoe UI",9f),ForeColor=Color.FromArgb(75,94,252)};
|
|
_prog = new ProgressBar{Dock=DockStyle.Bottom,Height=10,Style=ProgressBarStyle.Continuous};
|
|
_progPnl.Controls.Add(_prog); _progPnl.Controls.Add(_status); Controls.Add(_progPnl);
|
|
|
|
int fy = Height-44;
|
|
Controls.Add(new Label{Text="v"+AppVer,Left=24,Top=fy+4,AutoSize=true,
|
|
Font=new Font("Segoe UI",8f),ForeColor=Color.FromArgb(187,187,204)});
|
|
_btnDel = Btn("\uC81C\uAC70",Color.FromArgb(254,226,226),Color.FromArgb(220,38,38),Width-270,fy,60,32);
|
|
_btnDel.Visible=false; _btnDel.Click+=async(s,ev)=>await Uninstall(); Controls.Add(_btnDel);
|
|
_btnCanc = Btn("\uCDE8\uC18C",Color.FromArgb(240,240,248),Color.FromArgb(102,102,136),Width-200,fy,68,32);
|
|
_btnCanc.Click+=(s,ev)=>Close(); Controls.Add(_btnCanc);
|
|
_btnInst = Btn("\uC124\uCE58",Color.FromArgb(75,94,252),Color.White,Width-122,fy,100,32);
|
|
_btnInst.Click+=async(s,ev)=>await Install(); Controls.Add(_btnInst);
|
|
}
|
|
|
|
private CheckBox Chk(string t,bool c,int x,int y){var cb=new CheckBox{Text=t,Checked=c,Left=x,Top=y,AutoSize=true,
|
|
Font=new Font("Segoe UI",9.5f),ForeColor=Color.FromArgb(85,85,119)};Controls.Add(cb);return cb;}
|
|
private Button Btn(string t,Color bg,Color fg,int x,int y,int w,int h){var b=new Button{Text=t,Left=x,Top=y,Width=w,Height=h,
|
|
FlatStyle=FlatStyle.Flat,BackColor=bg,ForeColor=fg,Font=new Font("Segoe UI",9.5f,FontStyle.Bold),Cursor=Cursors.Hand};
|
|
b.FlatAppearance.BorderSize=0;return b;}
|
|
|
|
private void Detect()
|
|
{
|
|
try{using(var k=Registry.CurrentUser.OpenSubKey(RegUn)){
|
|
_exPath=k!=null?k.GetValue("InstallLocation") as string:null;
|
|
_exVer=k!=null?k.GetValue("DisplayVersion") as string:null;}}catch{}
|
|
if(!string.IsNullOrEmpty(_exPath)&&Directory.Exists(_exPath)){
|
|
_pathBox.Text=_exPath;_existPnl.Visible=true;
|
|
_existLbl.Text=" \u26A0 \uAE30\uC874: v"+(_exVer??"")+" \u2014 "+_exPath;
|
|
_btnInst.Text="\uC5C5\uADF8\uB808\uC774\uB4DC";_btnDel.Visible=true;}
|
|
}
|
|
|
|
private async Task Install()
|
|
{
|
|
var path = _pathBox.Text.Trim();
|
|
if(string.IsNullOrEmpty(path)){CustomMessageBox.Show("\uC124\uCE58 \uACBD\uB85C\uB97C \uC785\uB825\uD558\uC138\uC694.");return;}
|
|
Busy(true);
|
|
try
|
|
{
|
|
St("앱 종료...",5); Kill(); await Task.Delay(500);
|
|
|
|
// ── 기존 AX Commander 마이그레이션 ──
|
|
MigrateFromAxCommander();
|
|
|
|
St("파일 설치...",20);
|
|
Directory.CreateDirectory(path);
|
|
ExtractZip(path);
|
|
await Task.Delay(300);
|
|
|
|
if(_chkDesk.Checked){St("바로가기...",60);
|
|
Lnk(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"AX Copilot.lnk"),
|
|
Path.Combine(path,"AxCopilot.exe"));}
|
|
St("시작 메뉴...",70);
|
|
var sm=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu),"Programs","AX Copilot");
|
|
Directory.CreateDirectory(sm);
|
|
Lnk(Path.Combine(sm,"AX Copilot.lnk"),Path.Combine(path,"AxCopilot.exe"));
|
|
if(_chkAuto.Checked){St("\uC790\uB3D9 \uC2E4\uD589...",80);
|
|
using(var k=Registry.CurrentUser.OpenSubKey(RegRun,true)){if(k!=null)k.SetValue("AxCopilot","\""+Path.Combine(path,"AxCopilot.exe")+"\"");}}
|
|
// 인스톨러를 설치 폴더에 복사 (제거 기능용)
|
|
St("제거 프로그램 등록...",85);
|
|
try{var me=Assembly.GetExecutingAssembly().Location;
|
|
var dest=Path.Combine(path,"AxCopilot_Setup.exe");
|
|
if(!string.Equals(me,dest,StringComparison.OrdinalIgnoreCase))
|
|
File.Copy(me,dest,true);}catch{}
|
|
|
|
if(_chkReg.Checked){St("\uD504\uB85C\uADF8\uB7A8 \uB4F1\uB85D...",90);RegAdd(path);}
|
|
|
|
St("\uC124\uCE58 \uC644\uB8CC!",100); await Task.Delay(400);
|
|
if(CustomMessageBox.Show(AppName+" \uC124\uCE58 \uC644\uB8CC!\n\n"+Path.Combine(path,"AxCopilot.exe")+"\n\n\uC2E4\uD589\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
AppName,MessageBoxButtons.YesNo,MessageBoxIcon.Information)==DialogResult.Yes)
|
|
Process.Start(new ProcessStartInfo(Path.Combine(path,"AxCopilot.exe")){UseShellExecute=true});
|
|
Close();
|
|
}
|
|
catch(UnauthorizedAccessException){CustomMessageBox.Show("관리자 권한이 필요합니다.\n다른 경로를 선택하거나 관리자로 실행하세요.");Busy(false);}
|
|
catch(Exception ex){CustomMessageBox.Show("\uC124\uCE58 \uC2E4\uD328:\n"+ex.Message);Busy(false);}
|
|
}
|
|
|
|
private async Task Uninstall()
|
|
{
|
|
if(string.IsNullOrEmpty(_exPath))return;
|
|
if(CustomMessageBox.Show("\uC81C\uAC70\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?\n\n"+_exPath+"\n\n\uC124\uC815(%APPDATA%)\uC740 \uC720\uC9C0\uB429\uB2C8\uB2E4.",
|
|
AppName+" \uC81C\uAC70",MessageBoxButtons.YesNo,MessageBoxIcon.Question)!=DialogResult.Yes)return;
|
|
Busy(true);
|
|
try{
|
|
St("\uC571 \uC885\uB8CC...",10);Kill();await Task.Delay(500);
|
|
St("\uD30C\uC77C \uC0AD\uC81C...",30);
|
|
if(Directory.Exists(_exPath)){try{Directory.Delete(_exPath,true);}catch{
|
|
foreach(var f in Directory.GetFiles(_exPath))try{File.Delete(f);}catch{}}}
|
|
St("\uBC14\uB85C\uAC00\uAE30 \uC0AD\uC81C...",55);
|
|
Del(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"AX Copilot.lnk"));
|
|
Del(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"AX Commander.lnk")); // 레거시
|
|
var sm=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu),"Programs","AX Copilot");
|
|
try{var smOld=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu),"Programs","AX Commander");if(Directory.Exists(smOld))Directory.Delete(smOld,true);}catch{}
|
|
try{if(Directory.Exists(sm))Directory.Delete(sm,true);}catch{}
|
|
St("\uB808\uC9C0\uC2A4\uD2B8\uB9AC...",75);
|
|
try{using(var k=Registry.CurrentUser.OpenSubKey(RegRun,true)){if(k!=null)k.DeleteValue("AxCopilot",false);}}catch{}
|
|
try{Registry.CurrentUser.DeleteSubKey(RegUn,false);}catch{}
|
|
St("\uC81C\uAC70 \uC644\uB8CC!",100);await Task.Delay(400);
|
|
CustomMessageBox.Show("\uC81C\uAC70 \uC644\uB8CC.\n\uC124\uC815: %APPDATA%\\AxCopilot",AppName);Close();
|
|
}catch(Exception ex){CustomMessageBox.Show("\uC81C\uAC70 \uC2E4\uD328:"+ex.Message);Busy(false);}
|
|
}
|
|
|
|
private void Busy(bool b){_btnInst.Enabled=!b;_btnCanc.Enabled=!b;_btnDel.Enabled=!b;_progPnl.Visible=b;}
|
|
private void St(string t,int p){_status.Text=t;_prog.Value=Math.Min(p,100);Application.DoEvents();}
|
|
private static void Kill()
|
|
{
|
|
foreach(var p in Process.GetProcessesByName("AxCopilot"))try{p.Kill();p.WaitForExit(3000);}catch{}
|
|
foreach(var p in Process.GetProcessesByName("AxCommander"))try{p.Kill();p.WaitForExit(3000);}catch{} // 레거시
|
|
}
|
|
private static void Del(string f){try{if(File.Exists(f))File.Delete(f);}catch{}}
|
|
|
|
/// <summary>기존 AX Commander 설치를 감지하여 정리 + AppData 마이그레이션</summary>
|
|
private void MigrateFromAxCommander()
|
|
{
|
|
const string OldRegUn = @"Software\Microsoft\Windows\CurrentVersion\Uninstall\AxCommander";
|
|
try
|
|
{
|
|
using var oldKey = Registry.CurrentUser.OpenSubKey(OldRegUn, false);
|
|
if (oldKey == null) return; // 기존 설치 없음
|
|
|
|
St("AX Commander → AX Copilot 업그레이드...", 8);
|
|
|
|
// 기존 설치 폴더 삭제
|
|
var oldPath = oldKey.GetValue("InstallLocation") as string;
|
|
if (!string.IsNullOrEmpty(oldPath) && Directory.Exists(oldPath))
|
|
try { Directory.Delete(oldPath, true); } catch { }
|
|
|
|
// 기존 바로가기 삭제
|
|
Del(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "AX Commander.lnk"));
|
|
var oldSm = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Programs", "AX Commander");
|
|
try { if (Directory.Exists(oldSm)) Directory.Delete(oldSm, true); } catch { }
|
|
|
|
// 기존 레지스트리 정리
|
|
try { using (var k = Registry.CurrentUser.OpenSubKey(RegRun, true)) { k?.DeleteValue("AxCommander", false); } } catch { }
|
|
try { Registry.CurrentUser.DeleteSubKey(OldRegUn, false); } catch { }
|
|
|
|
// %APPDATA%\AxCommander → %APPDATA%\AxCopilot 이동
|
|
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
|
var oldDir = Path.Combine(appData, "AxCommander");
|
|
var newDir = Path.Combine(appData, "AxCopilot");
|
|
if (Directory.Exists(oldDir) && !Directory.Exists(newDir))
|
|
{
|
|
St("설정 데이터 마이그레이션...", 12);
|
|
try { Directory.Move(oldDir, newDir); } catch { }
|
|
}
|
|
|
|
St("마이그레이션 완료", 15);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private void ExtractZip(string dest)
|
|
{
|
|
var asm = Assembly.GetExecutingAssembly();
|
|
var names = asm.GetManifestResourceNames();
|
|
string name = null;
|
|
foreach(var n in names) if(n.IndexOf("payload.zip",StringComparison.OrdinalIgnoreCase)>=0){name=n;break;}
|
|
if(name==null)throw new FileNotFoundException("payload.zip not found in embedded resources.");
|
|
using(var s = asm.GetManifestResourceStream(name))
|
|
using(var zip = new ZipArchive(s, ZipArchiveMode.Read))
|
|
{
|
|
int total = 0; foreach(var _ in zip.Entries) total++;
|
|
int done = 0;
|
|
foreach(var entry in zip.Entries)
|
|
{
|
|
var target = Path.Combine(dest, entry.FullName);
|
|
if(string.IsNullOrEmpty(entry.Name)){Directory.CreateDirectory(target);continue;}
|
|
var dir = Path.GetDirectoryName(target);
|
|
if(dir!=null) Directory.CreateDirectory(dir);
|
|
entry.ExtractToFile(target, true);
|
|
done++;
|
|
int pct = 20 + (done * 35 / Math.Max(total, 1));
|
|
St("\uD30C\uC77C \uC124\uCE58... ("+done+"/"+total+")", pct);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void FillRoundRect(Graphics g, Brush brush, float x, float y, float w, float h, float r)
|
|
{
|
|
using var path = new System.Drawing.Drawing2D.GraphicsPath();
|
|
path.AddArc(x, y, r * 2, r * 2, 180, 90);
|
|
path.AddArc(x + w - r * 2, y, r * 2, r * 2, 270, 90);
|
|
path.AddArc(x + w - r * 2, y + h - r * 2, r * 2, r * 2, 0, 90);
|
|
path.AddArc(x, y + h - r * 2, r * 2, r * 2, 90, 90);
|
|
path.CloseFigure();
|
|
g.FillPath(brush, path);
|
|
}
|
|
|
|
private static void Lnk(string lnk,string target)
|
|
{
|
|
var iconPath = Path.Combine(Path.GetDirectoryName(target)??"", "Assets", "icon.ico");
|
|
var iconArg = File.Exists(iconPath) ? "$s.IconLocation='"+iconPath.Replace("'","''")+"';" : "";
|
|
var ps="$ws=New-Object -ComObject WScript.Shell;$s=$ws.CreateShortcut('"+lnk.Replace("'","''")+"');"+
|
|
"$s.TargetPath='"+target.Replace("'","''")+"';$s.WorkingDirectory='"+Path.GetDirectoryName(target).Replace("'","''")+"';"+
|
|
iconArg+"$s.Save()";
|
|
Process.Start(new ProcessStartInfo("powershell","-NoProfile -Command \""+ps+"\"")
|
|
{CreateNoWindow=true,UseShellExecute=false}).WaitForExit(5000);
|
|
}
|
|
|
|
private static void RegAdd(string dir)
|
|
{
|
|
try{using(var k=Registry.CurrentUser.CreateSubKey(RegUn)){
|
|
k.SetValue("DisplayName",AppName);
|
|
k.SetValue("DisplayVersion",AppVer);
|
|
k.SetValue("Publisher",Org);
|
|
k.SetValue("InstallLocation",dir);
|
|
k.SetValue("DisplayIcon",Path.Combine(dir,"AxCopilot.exe")+",0");
|
|
k.SetValue("UninstallString","\""+Path.Combine(dir,"AxCopilot_Setup.exe")+"\"");
|
|
k.SetValue("InstallDate",DateTime.Now.ToString("yyyyMMdd"));
|
|
k.SetValue("NoModify",1,RegistryValueKind.DWord);
|
|
k.SetValue("NoRepair",1,RegistryValueKind.DWord);
|
|
k.SetValue("EstimatedSize",72000,RegistryValueKind.DWord);}}catch{}
|
|
}
|
|
}
|
|
}
|