精华内容
下载资源
问答
  • 2020-04-05 09:09:13

    通过COM接口调用远程桌面,将远程桌面显示在应用程序窗体内:

    一、主程序:

    unit uMain;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Winapi.ActiveX
      , System.Win.ComObj, uEventSink,uShow, Vcl.ComCtrls,
      uConfig,uLog;
    
    type
      TfMain = class(TForm)
        bar1: TStatusBar;
        MemoInfo: TMemo;
        Panel4: TPanel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label1: TLabel;
        edtHost: TEdit;
        edtPort: TEdit;
        edtUser: TEdit;
        edtPwd: TEdit;
        btnConnect: TButton;
        btnClose: TButton;
        Panel1: TPanel;
        btnFullScreen: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure btnCloseClick(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure btnConnectClick(Sender: TObject);
        procedure btnFullScreenClick(Sender: TObject);
      private
        { Private declarations }
        mHost,mUser,mPwd:string;
        mPort:integer;
        EventSink: TEventSink;
    
        mScreenX,mScreenY:integer;
        function InitAtl: Boolean;
        procedure EventSinkInvoke(Sender: TObject; DispID: Integer;
           const IID: TGUID; LocaleID: Integer; Flags: Word;
           Params: tagDISPPARAMS; VarResult, ExcepInfo, ArgErr: Pointer);
        function verifyInput():boolean;
        procedure AppException(Sender: TObject; E: Exception);
        procedure LogMain(msg:string);
      public
        { Public declarations }
        ActiveXCon: Variant;
      end;
    
    var
      fMain: TfMain;
    
    const
      CLASS_MsRdpClient: TGUID = '{7CACBD7B-0D99-468F-AC33-22E495C0AFE5}';//'{791FA017-2DE3-492E-ACC5-53C67A2B94D0}';
    
    type
      PIUnknown=^IUnknown;
      TAtlAxAttachControl = function(Control:IUnknown; hwind:hwnd;ppUnkContainer:PIUnknown): HRESULT; stdcall;
      //--此处参考mstscax.dll的接口文件,如果没有,在 Component->Import Component->Import a Type Library
      //--导入:Microsoft Terminal Services Active Client 1.0 Type Library 1.0
      IMsTscAxEvents = dispinterface
        ['{336D5562-EFA8-482E-8CB3-C5C0FC7A7DB6}']
        {
        procedure OnConnecting; dispid 1;
        procedure OnConnected; dispid 2;
        procedure OnLoginComplete; dispid 3;
        procedure OnDisconnected(discReason: Integer); dispid 4;
        procedure OnEnterFullScreenMode; dispid 5;
        procedure OnLeaveFullScreenMode; dispid 6;
        procedure OnChannelReceivedData(const chanName: WideString; const data: WideString); dispid 7;
        procedure OnRequestGoFullScreen; dispid 8;
        procedure OnRequestLeaveFullScreen; dispid 9;
        procedure OnFatalError(errorCode: Integer); dispid 10;
        procedure OnWarning(warningCode: Integer); dispid 11;
        procedure OnRemoteDesktopSizeChange(width: Integer; height: Integer); dispid 12;
        procedure OnIdleTimeoutNotification; dispid 13;
        procedure OnRequestContainerMinimize; dispid 14;
        function OnConfirmClose: WordBool; dispid 15;
        function OnReceivedTSPublicKey(const publicKey: WideString): WordBool; dispid 16;
        function OnAutoReconnecting(disconnectReason: Integer; attemptCount: Integer): AutoReconnectContinueState; dispid 17;
        procedure OnAuthenticationWarningDisplayed; dispid 18;
        procedure OnAuthenticationWarningDismissed; dispid 19;
        }
      end;
    implementation
       //regsvr32 mstscax.dll
    {$R *.dfm}
    procedure TfMain.LogMain(msg:string);
    var
      info:string;
    begin
      info:=uLog.Log(msg);
      memoinfo.Lines.Add(info);
      bar1.Panels[0].Text:=msg;
    end;
    procedure TfMain.AppException(Sender: TObject; E: Exception);
    begin
      LogMain(e.Message);
      //Log(e.Message);
    end;
    function TfMain.verifyInput():boolean;
    begin
      result:=false;
      mHost:=trim(edtHost.Text);
      if mHost='' then
      begin
        showmessage('服务器地址不能为空!');
        exit;
      end;
      mUser:=trim(edtUser.Text);
      if mUser='' then
      begin
        showmessage('用户名不能为空!');
        exit;
      end;
      mPwd:=trim(edtPwd.Text);
      if mHost='' then
      begin
        showmessage('密码不能为空!');
        exit;
      end;
      mPort:=strtointdef(trim(edtPort.Text),3389);
      if mPort=0 then
      begin
        showmessage('端口号不能为0!');
        exit;
      end;
      result:=true;
    end;
    function CreateComObjectFromDll(CLSID: TGUID; DllHandle: THandle): IUnknown;
    var
      Factory: IClassFactory;
      DllGetClassObject: function(const CLSID, IID: TGUID; var Obj): HResult; stdcall;
      hr: HRESULT;
    begin
      DllGetClassObject := GetProcAddress(DllHandle, 'DllGetClassObject');
      if Assigned(DllGetClassObject) then
      begin
        hr := DllGetClassObject(CLSID, IClassFactory, Factory);
        if hr = S_OK then
        try
          hr := Factory.CreateInstance(nil, IUnknown, Result);
          if hr <> S_OK then begin
            ShowMessage('Error');
          end;
        except
          ShowMessage(IntToStr(GetLastError));
        end;
      end;
    end;
    
    
    procedure TfMain.EventSinkInvoke(Sender: TObject; DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word;
      Params: tagDISPPARAMS; VarResult, ExcepInfo, ArgErr: Pointer);
    begin {
    &nbsp;&nbsp;&nbsp; 这里需要注明Params这个参数, 包含了事件的参数
    &nbsp;&nbsp;&nbsp; 如:
    &nbsp;&nbsp;&nbsp; Params.rgvarg[0] 代表第一个参数
    &nbsp;&nbsp;&nbsp; Params.rgvarg[1] 代表第二个参数
    &nbsp;&nbsp;&nbsp; ......
    &nbsp;&nbsp;&nbsp; Params.rgvarg[65535] 代表第65535个参数
    &nbsp;&nbsp;&nbsp; 最多65535个参数
    &nbsp;&nbsp;&nbsp; 具体可以参考 tagDISPPARAMS 的定义</p><p>&nbsp;&nbsp;&nbsp; 这里只列出了怎么扑获相关事件,具体功能具体实现
    &nbsp; }  case dispid of
        $00000001: LogMain('正在连接');
        $00000002: LogMain('连接成功');
        $00000003: LogMain('登陆成功');
        $00000004: LogMain('断开连接');
        $00000005: LogMain('进入全屏模式');
        $00000006: LogMain('离开全屏模式');
        $00000007: LogMain('通道接收数据');
        $00000008: LogMain('OnRequestGoFullScreen');
        $00000009: LogMain('OnRequestLeaveFullScreen');
        $00000010: LogMain( 'OnFatalError');
        $00000011: LogMain('OnWarning');
        $00000012: LogMain('OnRemoteDesktopSizeChange');
        $00000013: LogMain('OnIdleTimeoutNotification');
        $00000014: LogMain('OnRequestContainerMinimize');
        $00000015: LogMain('OnConfirmClose');
        $00000016: LogMain('OnReceivedTSPublicKey');
        $00000017: LogMain('OnAutoReconnecting');
        $00000018: LogMain('OnAuthenticationWarningDisplayed');
        $00000019: LogMain('OnAuthenticationWarningDismissed');
      end
    end;
    procedure TfMain.btnCloseClick(Sender: TObject);
    begin
      close;
    end;
    
    procedure TfMain.btnConnectClick(Sender: TObject);
    begin
      if not verifyInput() then exit;
      InitAtl();
      btnConnect.Enabled:=false;
    end;
    
    procedure TfMain.btnFullScreenClick(Sender: TObject);
    begin
      fMain.ActiveXCon.FullScreen := true;
    end;
    
    procedure TfMain.Button1Click(Sender: TObject);
    
    begin
      //ActiveXCon.Navigate(edit1.Text);
      InitAtl;
    end;
    
    
    procedure TfMain.FormCreate(Sender: TObject);
    begin
      Application.OnException := AppException;
    end;
    
    procedure TfMain.FormShow(Sender: TObject);
    begin
      fmain.Caption:=uConfig.APP_NAME+uConfig.APP_VERSION+uConfig.APP_CONTACT;
      edthost.Text:=uConfig.SERVER_HOST;
      edtuser.Text:=uConfig.SERVER_USER;
      edtport.Text:=inttostr(uConfig.SERVER_PORT);
      edtpwd.Text:=uConfig.SERVER_PWD;
      mScreenX:=GetSystemMetrics(SM_CXSCREEN);
      mScreenY:=GetSystemMetrics(SM_CYSCREEN);
    end;
    
    function TfMain.InitAtl: Boolean;
    var
      hModule, hDll: THandle;
      AtlAxAttachControl: TAtlAxAttachControl;
    begin
      hModule := LoadLibrary('atl.dll');
      if hModule < 32 then begin
        Exit(False);
      end;
      AtlAxAttachControl := TAtlAxAttachControl(GetProcAddress(hModule, 'AtlAxAttachControl'));
      EventSink := TEventSink.Create(Self);
      EventSink.OnInvoke := EventSinkInvoke;
      if not Assigned(AtlAxAttachControl) then
        Exit(False);
      try
        {--后期绑定}
    //    ActiveXCon := CreateComObject(CLASS_MsRdpClient); //CreateOleObject('Shell.Explorer');  //CreateComObject(CLASS_MsRdpClient);
        {--前期绑定}
        hDll := LoadLibrary('mstscax.dll');
        ActiveXCon := CreateComObjectFromDll(CLASS_MsRdpClient, hDll) as IDispatch;
    //    if Assigned(ActiveXCon) then begin
    //
    //    end;
        if VarIsNull(ActiveXCon) then begin
          Result := False;
          Exit;
        end;
        EventSink.Connect(ActiveXCon, IMsTscAxEvents);
        //AtlAxAttachControl(ActiveXCon,pnlCom.Handle, nil);
        AtlAxAttachControl(ActiveXCon,fshow.Handle, nil);
    //    ActiveXCon.GoHome;
        ActiveXCon.Server := mHost;
        ActiveXCon.UserName := mUser;
        ActiveXCon.AdvancedSettings2.ClearTextPassword := mPwd;
        ActiveXCon.AdvancedSettings2.RDPport:=3389;
        ActiveXCon.FullScreen := false;// 窗口/全屏模式
        ActiveXCon.ConnectingText := '欢迎使用远程桌面服务!';
        ActiveXCon.DisconnectedText := '正在停止远程桌面服务!';
        ActiveXCon.DesktopHeight := mScreenY;
        ActiveXCon.DesktopWidth := mScreenX;
        //ActiveXCon.AdvancedSettings.BitmapPeristence = 1;;
        //ActiveXCon.AdvancedSettings.Compress = 1;
        //ActiveXCon.SecuredSettings.set_StartProgram('C:\ccrun\123.exe');
        ActiveXCon.Connect;
        Result := True;
        //fshow.Width:=1024;
        //fshow.Height:=768;
        fshow.WindowState :=  wsMaximized; //wsnormal wsminimized
        fshow.Show;
      except
        Result := False;
      end;
    end;
    end.
    

    二、显示远程桌面的窗体

    unit uShow;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
    
    type
      TfShow = class(TForm)
        procedure FormResize(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      fShow: TfShow;
    
    implementation
    
    {$R *.dfm}
    uses
      uMain;
    procedure TfShow.FormResize(Sender: TObject);
    begin
      if self.WindowState=wsMaximized then
      begin
        //fMain.ActiveXCon.FullScreen := true;
      end;
    
    end;
    
    end.
    

    三、配置文件:

    unit uConfig;
    
    interface
    uses
      Vcl.Forms,System.SysUtils,windows;
    const
      DEBUG:boolean=false;
      APP_NAME='远程桌面';
      APP_VERSION='v1.01';
      APP_CONTACT='联系方式:QQ:1409232611微信:byc6352';
      WORK_DIR:string='remotedesk';
      LOG_NAME:string='remotedeskLog.txt';
    
      SERVER_HOST:string='127.0.0.1';
      SERVER_PORT:DWORD=3389;
      SERVER_USER:string='administrator';
      SERVER_PWD:string='123456';
    
    var
      workdir:string;//工作目录
      logfile:string;//
      apkfilename:string;
      isInit:boolean=false;
    
      procedure init();
    implementation
    procedure init();
    var
        me:String;
    begin
      isInit:=true;
      me:=application.ExeName;
      workdir:=extractfiledir(me)+'\'+WORK_DIR;
      if(not DirectoryExists(workdir))then ForceDirectories(workdir);
    
      logfile:=workdir+'\'+LOG_NAME;
    
    end;
    begin
      init();
    end.
    

    四、事件回调单元

    unit uEventSink;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
      Winapi.ActiveX;
    
    type
      TInvokeEvent = procedure(Sender: TObject; DispID: Integer; const IID: TGUID;
        LocaleID: Integer; Flags: Word; Params: TDispParams;
        VarResult, ExcepInfo, ArgErr: Pointer) of object;
    
      TAbstractEventSink = class(TObject, IUnknown, IDispatch)
      private
        FDispatch: IDispatch;
        FDispIntfIID: TGUID;
        FConnection: LongInt;
        FOwner: TComponent;
      protected
        { IUnknown }
        function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
        function _AddRef: Integer; stdcall;
        function _Release: Integer; stdcall;
        { IDispatch }
        function GetTypeInfoCount(out Count: Integer): HRESULT; stdcall;
        function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo)
          : HRESULT; stdcall;
        function GetIDsOfNames(const IID: TGUID; Names: Pointer;
          NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT; stdcall;
        function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
          Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer)
          : HRESULT; stdcall;
      public
        constructor Create(AOwner: TComponent);
        destructor Destroy; override;
        procedure Connect(AnAppDispatch: IDispatch; const AnAppDispIntfIID: TGUID);
        procedure Disconnect;
      end;
    
      TEventSink = class(TComponent)
      private
        { Private declarations }
        FSink: TAbstractEventSink;
        FOnInvoke: TInvokeEvent;
      protected
        { Protected declarations }
        procedure DoInvoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
          Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer); virtual;
      public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure Connect(AnAppDispatch: IDispatch; const AnAppDispIntfIID: TGUID);
      published
        { Published declarations }
        property OnInvoke: TInvokeEvent read FOnInvoke write FOnInvoke;
      end;
    
    implementation
    
    uses
      ComObj;
    
    procedure InterfaceConnect(const Source: IUnknown; const IID: TIID;
      const Sink: IUnknown; var Connection: LongInt);
    var
      CPC: IConnectionPointContainer;
      CP: IConnectionPoint;
      i: HRESULT;
    begin
      Connection := 0;
      if Succeeded(Source.QueryInterface(IConnectionPointContainer, CPC)) then
        if Succeeded(CPC.FindConnectionPoint(IID, CP)) then
          i := CP.Advise(Sink, Connection);
    end;
    
    procedure InterfaceDisconnect(const Source: IUnknown; const IID: TIID;
      var Connection: LongInt);
    var
      CPC: IConnectionPointContainer;
      CP: IConnectionPoint;
    begin
      if Connection <> 0 then
        if Succeeded(Source.QueryInterface(IConnectionPointContainer, CPC)) then
          if Succeeded(CPC.FindConnectionPoint(IID, CP)) then
            if Succeeded(CP.Unadvise(Connection)) then
              Connection := 0;
    end;
    
    { TAbstractEventSink }
    function TAbstractEventSink._AddRef: Integer; stdcall;
    begin
      Result := 2;
    end;
    
    function TAbstractEventSink._Release: Integer; stdcall;
    begin
      Result := 1;
    end;
    
    constructor TAbstractEventSink.Create(AOwner: TComponent);
    begin
      inherited Create;
      FOwner := AOwner;
    end;
    
    destructor TAbstractEventSink.Destroy;
    var
      p: Pointer;
    begin
      Disconnect;
    
      inherited Destroy;
    end;
    
    function TAbstractEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT; stdcall;
    begin
      Result := E_NOTIMPL;
    end;
    
    function TAbstractEventSink.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo)
      : HRESULT; stdcall;
    begin
      Result := E_NOTIMPL;
    end;
    
    function TAbstractEventSink.GetTypeInfoCount(out Count: Integer)
      : HRESULT; stdcall;
    begin
      Count := 0;
      Result := S_OK;
    end;
    
    function TAbstractEventSink.Invoke(DispID: Integer; const IID: TGUID;
      LocaleID: Integer; Flags: Word; var Params;
      VarResult, ExcepInfo, ArgErr: Pointer): HRESULT; stdcall;
    begin
      (FOwner as TEventSink).DoInvoke(DispID, IID, LocaleID, Flags, Params,
        VarResult, ExcepInfo, ArgErr);
      Result := S_OK;
    end;
    
    function TAbstractEventSink.QueryInterface(const IID: TGUID; out Obj)
      : HRESULT; stdcall;
    begin
      // We need to return the event interface when it's asked for
      Result := E_NOINTERFACE;
      if GetInterface(IID, Obj) then
        Result := S_OK;
      if IsEqualGUID(IID, FDispIntfIID) and GetInterface(IDispatch, Obj) then
        Result := S_OK;
    end;
    
    procedure TAbstractEventSink.Connect(AnAppDispatch: IDispatch;
      const AnAppDispIntfIID: TGUID);
    begin
      FDispIntfIID := AnAppDispIntfIID;
      FDispatch := AnAppDispatch;
      // Hook the sink up to the automation server
      InterfaceConnect(FDispatch, FDispIntfIID, Self, FConnection);
    end;
    
    procedure TAbstractEventSink.Disconnect;
    begin
      if Assigned(FDispatch) then
      begin
        // Unhook the sink from the automation server
        InterfaceDisconnect(FDispatch, FDispIntfIID, FConnection);
        FDispatch := nil;
        FConnection := 0;
      end;
    end;
    
    { TEventSink }
    
    procedure TEventSink.Connect(AnAppDispatch: IDispatch;
      const AnAppDispIntfIID: TGUID);
    begin
      FSink.Connect(AnAppDispatch, AnAppDispIntfIID);
    end;
    
    constructor TEventSink.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
    
      FSink := TAbstractEventSink.Create(Self);
    end;
    
    destructor TEventSink.Destroy;
    begin
      FSink.Free;
    
      inherited Destroy;
    end;
    
    procedure TEventSink.DoInvoke(DispID: Integer; const IID: TGUID;
      LocaleID: Integer; Flags: Word; var Params;
      VarResult, ExcepInfo, ArgErr: Pointer);
    begin
      if Assigned(FOnInvoke) then
        FOnInvoke(Self, DispID, IID, LocaleID, Flags, TDispParams(Params),
          VarResult, ExcepInfo, ArgErr);
    end;
    
    end.
    

    五、日志单元

    unit uLog;
    
    
    interface
    uses windows,sysutils,uConfig;
    procedure init();
    function Log(txt:string):string;
    var
      tf:TextFile;
    implementation
    procedure init();
    begin
      if not uConfig.isInit then uConfig.init();
      AssignFile(tf,uconfig.logfile);
      if(not fileexists(uconfig.logfile))then
        Rewrite(tF)  //会覆盖已存在的文件
      else
        Append(tF);  //打开准备追加
    end;
    function Log(txt:string):string;
    var
      t:string;
    begin
      t:=FormatDateTime('yyyy-mm-dd hh:nn:ss:zzz', Now);
      WriteLn(tf,t);
      WriteLn(tf,txt);
      flush(tf);
      result:=t+#13#10+txt+#13#10;
    end;
    initialization
      {初始化部分}
      {程序启动时先执行,并顺序执行}
      {一个单元的初始化代码运行之前,就运行了它使用的每一个单元的初始化部分}
       init();
    finalization
      {结束化部分,程序结束时执行}
      CloseFile(tF);
    end.
    
    

     

    更多相关内容
  • 用C#windowsform开发的基本桌面应用程序,代表快餐店的ERP系统。 该应用程序包含三种类型的用户,其中每个用户都有自己的界面。 在以下图像中,您可以看到某些屏幕的设计。 应用程序的登录页面 以管理人员身份登录...
  • 说明:本次作业采用EntityFramework框架完成,连接字符串的存放位置:Exam001\Exam001\App.congif 登录界面 ... 主界面 主界面可以直接进行数据的“删除”与“查询”操作。...查询数据:查询时,“货物代码”、“商品...

    说明:本次项目为.Net数据访问技术课程期末大作业,采用EntityFramework框架完成,连接字符串的存放位置:Exam001\Exam001\App.congif,源代码参见上方资源链接。

    • 登录界面

    输入用户名:daixiang,密码:123456,点击登录按钮登录进入主界面,账户名密码错误会提示“用户名或密码错误”,代码调用存储过程实现登录。
    在这里插入图片描述

    • 主界面

    主界面可以直接进行数据的“删除”与“查询”操作。
    删除数据:在数据行上右键“删除”或选中记录行点击“删除”按钮,可进行数据的删除操作。
    查询数据:查询时,“货物代码”、“商品名称”不是必填,“商品类型”必选,输入/选择后,点击“查询”按钮可进行多条件查询。
    在这里插入图片描述

    • 查询界面

    查询:查询时,“货物代码”、“商品名称”不是必填,“商品类型”必选,输入/选择后,点击“查询”按钮可进行多条件查询。
    在这里插入图片描述

    • 删除界面

    删除数据:在数据行上右键“删除”或选中记录行点击“删除”按钮,可进行对数据的删除操作。
    在这里插入图片描述

    • 添加商品界面

    添加商品:用户在主界面点击“增加”按钮,进入添加商品界面,库存量和售价只接收数字输入,输入信息后点击“提交”即可完成商品的添加,提交时会校验字段,为空不允许提交。
    在这里插入图片描述

    • 修改商品界面

    修改商品:选中数据行,点击修改,进入数据修改界面,填写信息后点击“提交”存储信息。
    在这里插入图片描述


    作者:戴翔
    电子邮箱:daixiangcn@outlook.com
    微信开发者主页:Null
    简介:中国公民,CSDN博客专家,秦淮区疾控中心托管社会公益组织指南针工作室志愿者,创业公司研发中心负责人,在校大学生。第二届大学生微信小程序应用开发大赛全国三等奖项目第一作者,微信小程序《约车吗》、《庆云慈善会》、《锋云速检》项目总工程师。


    展开全文
  • C#Windows桌面应用开发实践(持续更新)

    千次阅读 2022-03-26 14:49:42
    //TODO:对文件进行处理 如果在 DownloadFileTaskAsync 方法中发生了异常(通常是网络中断或网络超时),那么下载不完整的文件将会保留在本地系统中。在该任务重试执行时,因为文件已存在(虽然它不完整)所以会直接...

    必须功能一览

    注册表相关的操作(添加与删除)

           RegistryKey hkml = Registry.LocalMachine;
                RegistryKey software = hkml.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", true);
                RegistryKey softdemo = software.CreateSubKey("再见江湖");
                softdemo.SetValue("DisplayName", "再见江湖"); 
                softdemo.SetValue("UninstallString", InstallPath + "\\"+PathNameDef+"\\Uninstall.exe uninstall");
                softdemo.SetValue("DisplayIcon", InstallPath + "\\"+PathNameDef+"\\Uninstall.exe");
    
                //清楚注册表
                try
                {
                    RegistryKey hkml = Registry.LocalMachine;
                    RegistryKey software = hkml.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", true);
                    RegistryKey softdemo = software.OpenSubKey("再见江湖");
                    if (softdemo.GetValue("再见江湖") != null)
                    {
                        softdemo.DeleteSubKeyTree("再见江湖");
                    }
    
                    //Registry.ClassesRoot.OpenSubKey("再见江湖", true);
                    //Registry.ClassesRoot.DeleteSubKeyTree("再见江湖", true);
                    Registry.CurrentUser.OpenSubKey("longtu", true);
                    Registry.CurrentUser.OpenSubKey("再见江湖", true);
                    if (Registry.CurrentUser.GetValue("再见江湖") != null)
                    {
                        Registry.CurrentUser.DeleteSubKeyTree("再见江湖", true);
                    }
    
                }
                catch (System.Exception exc)
                {
                    //注册表异常暂时不捕获不抛出
                    throw exc;
                }
    

    文件占用问题的处理

    此问题发生一般是资源没被释放掉,但也存在如下可能性。我们对文件的操作非常频繁,所以写了特定的操作类/组件来维护文件之间的操作,知道特定的时刻才结束,常见的如日志,随着程序的启动便开始写日志,直到程序关闭。但其中也存在我们需要提供一个特殊的操作(读/写/删除)来操作文件,例如我们需要提供一个日志查看器来查看当前日志或所有日志,这时,便无可避免的发生了以上的问题。解决此问题,只需将文件读写锁改为FileShare.ReadWrite(FileShare就是控制文件流的“访问权限),具体代码如下:

    
    
     using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
     {
       byte[] bt = new byte[fs.Length];
       fs.Read(bt, 0, bt.Length);
       fs.Close();
      }
    

    防止重复启动只开一个实例,通用弹窗和提示 使用示例

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Threading;
    
    namespace Launcher
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                //Application.EnableVisualStyles();
                //Application.SetCompatibleTextRenderingDefault(false);
    
                bool isAppRunning = false;
                Mutex mutex = new Mutex(true, System.Diagnostics.Process.GetCurrentProcess().ProcessName, out isAppRunning);
                if (!isAppRunning)
                {
                    MessageBox.Show("程序已运行,不能再次打开!");
                    Environment.Exit(1);
                }
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
    
                var freeSpace = ComTool.GetDiskFreeSpace(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase);
                if (freeSpace < 42949672960)
                {
    
                    DialogResult dr = MessageBox.Show(string.Format("更新本游戏至少需要5G的安装空间,检测到您的磁盘不足5G({0}),是否继续更新?",ComTool.HumanReadableFilesize(freeSpace)), "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    if (dr == DialogResult.OK)
                    {
                        Application.Run(new Form1());
                    }                
                }
                else
                {
                    Application.Run(new Form1());
                }          
            }
        }
    }
    
    

    使用 C# 下载文件 (引用自使用 C# 下载文件的十八般武艺)

    简单下载

    在 .NET 程序中下载文件最简单的方式就是使用 WebClient 的 DownloadFile 方法:

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    using (var web = new WebClient())
    {
        web.DownloadFile(url,save);
    }
    

    异步下载

    该方法也提供异步的实现:

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    using (var web = new WebClient())
    {
        await web.DownloadFileTaskAsync(url, save);
    }
    

    下载文件的同时向服务器发送自定义请求头
    如果需要对文件下载请求进行定制,可以使用 HttpClient :

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    var http = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get,url);
    //增加 Auth 请求头
    request.Headers.Add("Auth","123456");
    var response = await http.SendAsync(request);
    response.EnsureSuccessStatusCode();
    using (var fs = File.Open(save, FileMode.Create))
    {
        using (var ms = response.Content.ReadAsStream())
        {
            await ms.CopyToAsync(fs);
        }
    }
    

    如何解决下载文件不完整的问题

    以上所有代码在应对小文件的下载时没有特别大的问题,在网络情况不佳或文件较大时容易引入错误。以下代码在开发中很常见:

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    if (!File.Exists(save))
    {
        Console.WriteLine("文件不存在,开始下载...");
        using (var web = new WebClient())
        {
            await web.DownloadFileTaskAsync(url, save);
        }
        Console.WriteLine("文件下载成功");
    }
    Console.WriteLine("开始处理文件");
    //TODO:对文件进行处理
    

    如果在 DownloadFileTaskAsync 方法中发生了异常(通常是网络中断或网络超时),那么下载不完整的文件将会保留在本地系统中。在该任务重试执行时,因为文件已存在(虽然它不完整)所以会直接进入处理程序,从而引入异常。

    一个简单的修复方式是引入异常处理,但这种方式对应用程序意外终止造成的文件不完整无效:

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    if (!File.Exists(save))
    {
        Console.WriteLine("文件不存在,开始下载...");
        using (var web = new WebClient())
        {
            try
            {
                await web.DownloadFileTaskAsync(url, save);
            }
            catch
            {
                if (File.Exists(save))
                {
                    File.Delete(save);
                }
                throw;
            }
        }
        Console.WriteLine("文件下载成功");
    }
    Console.WriteLine("开始处理文件");
    //TODO:对文件进行处理
    

    笔者更喜欢的方式是引入一个临时文件。下载操作将数据下载到临时文件中,当确定下载操作执行完毕时将临时文件改名:

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    if (!File.Exists(save))
    {
        Console.WriteLine("文件不存在,开始下载...");
        //先下载到临时文件
        var tmp = save + ".tmp";
        using (var web = new WebClient())
        {
            await web.DownloadFileTaskAsync(url, tmp);
        }
        File.Move(tmp, save, true);
        Console.WriteLine("文件下载成功");
    }
    Console.WriteLine("开始处理文件");
    //TODO:对文件进行处理
    

    使用 Downloader 进行 HTTP 多线程下载

    在网络带宽充足的情况下,单线程下载的效率并不理想。我们需要多线程和断点续传才可以拿到更好的下载速度。

    Downloader 是一个现代化的、流畅的、异步的、可测试的和可移植的 .NET 库。这是一个包含异步进度事件的多线程下载程序。Downloader 与 .NET Standard 2.0 及以上版本兼容,可以在 Windows、Linux 和 macOS 上运行。

    GitHub 开源地址: https://github.com/bezzad/Downloader

    NuGet 地址:https://www.nuget.org/packages/Downloader

    从 NuGet 安装 Downloader 之后,创建一个下载配置:

    var downloadOpt = new DownloadConfiguration()
    {
        BufferBlockSize = 10240, // 通常,主机最大支持8000字节,默认值为8000。
        ChunkCount = 8, // 要下载的文件分片数量,默认值为1
        MaximumBytesPerSecond = 1024 * 1024, // 下载速度限制为1MB/s,默认值为零或无限制
        MaxTryAgainOnFailover = int.MaxValue, // 失败的最大次数
        OnTheFlyDownload = false, // 是否在内存中进行缓存? 默认值是true
        ParallelDownload = true, // 下载文件是否为并行的。默认值为false
        TempDirectory = "C:\\temp", // 设置用于缓冲大块文件的临时路径,默认路径为Path.GetTempPath()。
        Timeout = 1000, // 每个 stream reader  的超时(毫秒),默认值是1000
        RequestConfiguration = // 定制请求头文件
        {
            Accept = "*/*",
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
            CookieContainer =  new CookieContainer(), // Add your cookies
            Headers = new WebHeaderCollection(), // Add your custom headers
            KeepAlive = false,
            ProtocolVersion = HttpVersion.Version11, // Default value is HTTP 1.1
            UseDefaultCredentials = false,
            UserAgent = $"DownloaderSample/{Assembly.GetExecutingAssembly().GetName().Version.ToString(3)}"
        }
    };
    

    创建一个下载服务:

    var downloader = new DownloadService(downloadOpt);
    配置事件处理器(该步骤可以省略):

    // Provide `FileName` and `TotalBytesToReceive` at the start of each downloads
    // 在每次下载开始时提供 "文件名 "和 "要接收的总字节数"。
    downloader.DownloadStarted += OnDownloadStarted;
    
    // Provide any information about chunker downloads, like progress percentage per chunk, speed, total received bytes and received bytes array to live streaming.
    // 提供有关分块下载的信息,如每个分块的进度百分比、速度、收到的总字节数和收到的字节数组,以实现实时流。
    downloader.ChunkDownloadProgressChanged += OnChunkDownloadProgressChanged;
    
    // Provide any information about download progress, like progress percentage of sum of chunks, total speed, average speed, total received bytes and received bytes array to live streaming.
    // 提供任何关于下载进度的信息,如进度百分比的块数总和、总速度、平均速度、总接收字节数和接收字节数组的实时流。
    downloader.DownloadProgressChanged += OnDownloadProgressChanged;
    
    // Download completed event that can include occurred errors or cancelled or download completed successfully.
    // 下载完成的事件,可以包括发生错误或被取消或下载成功。
    downloader.DownloadFileCompleted += OnDownloadFileCompleted;
    

    接着就可以下载文件了:

    string file = @"D:\1.html";
    string url = @"https://www.coderbusy.com";
    await downloader.DownloadFileTaskAsync(url, file);
    

    下载非 HTTP 协议的文件

    除了 WebClient 可以下载 FTP 协议的文件之外,上文所示的其他方法只能下载 HTTP 协议的文件。

    aria2 是一个轻量级的多协议和多源命令行下载工具。它支持 HTTP/HTTPS、FTP、SFTP、BitTorrent 和 Metalink。aria2 可以通过内置的 JSON-RPC 和 XML-RPC 接口进行操作。

    我们可以调用 aria2 实现文件下载功能。

    GitHub 地址:https://github.com/aria2/aria2

    下载地址:https://github.com/aria2/aria2/releases

    将下载好的 aria2c.exe 复制到应用程序目录,如果是其他系统则可以下载对应的二进制文件。

    public static async Task Download(string url, string fn)
    {
        var exe = "aria2c";
        var dir = Path.GetDirectoryName(fn);
        var name = Path.GetFileName(fn);
    
        void Output(object sender, DataReceivedEventArgs args)
        {
            if (string.IsNullOrWhiteSpace(args.Data))
            {
                return;
            }
            Console.WriteLine("Aria:{0}", args.Data?.Trim());
        }
    
        var args = $"-x 8 -s 8 --dir={dir} --out={name} {url}";
        var info = new ProcessStartInfo(exe, args)
        {
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
        };
        if (File.Exists(fn))
        {
            File.Delete(fn);
        }
    
        Console.WriteLine("启动 aria2c: {0}", args);
        using (var p = new Process { StartInfo = info, EnableRaisingEvents = true })
        {
            if (!p.Start())
            {
                throw new Exception("aria 启动失败");
            }
            p.ErrorDataReceived += Output;
            p.OutputDataReceived += Output;
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            await p.WaitForExitAsync();
            p.OutputDataReceived -= Output;
            p.ErrorDataReceived -= Output;
        }
    
        var fi = new FileInfo(fn);
        if (!fi.Exists || fi.Length == 0)
        {
            throw new FileNotFoundException("文件下载失败", fn);
        }
    }
    

    以上代码通过命令行参数启动了一个新的 aria2c 下载进程,并对下载进度信息输出在了控制台。调用方式如下:

    var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    await Download(url, save);
    

    常用接口示例

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    
    public class ComTool
    {
        public static long GetDiskFreeSpace(string Path)
        {
            long freeSpace = 0;
            var LocalDrive = DriveInfo.GetDrives();
            for (int i = 0; i < LocalDrive.Length; i++)
            {
                //Console.WriteLine("------------------------------------------");
                //Console.WriteLine(string.Format("驱动器名称:{0}", LocalDrive[i].Name));
                //Console.WriteLine(string.Format("存储空间大小:{0}字节", LocalDrive[i].TotalSize));
                //Console.WriteLine(string.Format("可用空间大小:{0}字节", LocalDrive[i].AvailableFreeSpace));
                //Console.WriteLine(string.Format("可用空闲空间:{0}字节", LocalDrive[i].TotalFreeSpace));
                //Console.WriteLine(string.Format("文件系统:{0}", LocalDrive[i].DriveFormat));
                //Console.WriteLine(string.Format("驱动器类型:{0}", LocalDrive[i].DriveType));
                //Console.WriteLine(string.Format("驱动器IsReady:{0}", LocalDrive[i].IsReady));
                //Console.WriteLine(string.Format("驱动器的根目录:{0}", LocalDrive[i].RootDirectory));
                //Console.WriteLine(string.Format("驱动器卷标:{0}", LocalDrive[i].VolumeLabel));
    
                if (Path.Contains(LocalDrive[i].RootDirectory.Name))
                {
                    Console.WriteLine(string.Format("可用空间大小:{0}字节", LocalDrive[i].AvailableFreeSpace));
                    freeSpace = LocalDrive[i].AvailableFreeSpace;
                }
    
            }
            return freeSpace;
        }
        /// <summary>
        /// 转换方法
        /// </summary>
        /// <param name="size">字节值</param>
        /// <returns></returns>
        public static String HumanReadableFilesize(double size)
        {
             
            String[] units = new String[] { "B", "KB", "MB", "GB", "TB", "PB" };
            double mod = 1024.0;
            int i = 0;
            while (size >= mod)
            {
                size /= mod;
                i++;
            }
            return Math.Round(size) + units[i];
        }
    
    
    }
    
    展开全文
  • WindowsForm窗体位置

    2017-02-20 16:19:21
     WindowsForm的窗体,是winForm程序的基本单元。窗体的大小和位置是如何控制的呢?   先看窗体的几个属性。如下图所示   一、 设置窗体起始位置居中 窗口默认是在左上角的,可以用微软定义好...

    转载地址:http://www.cnblogs.com/mfk0506/p/6196020.html

     WindowsForm的窗体,是winForm程序的基本单元。窗体的大小和位置是如何控制的呢?

     

    先看窗体的几个属性。如下图所示

     

    一、 设置窗体起始位置居中

    窗口默认是在左上角的,可以用微软定义好的FormStartPosition属性来配置为居中:

    this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

    等同于 

    这个属性的其他值也可以了解下:

    属性值

    说明

    CenterParent

    在其父窗体中居中

    Manual

    位置由Location属性决定

    WindowsDefaultBounds

    默认位置,边界也默认

    WindowsDefaultLocation

    默认位置,尺寸在窗体大小中指定

     

    其中提到了Location属性,下面详谈。

     

    二、 指定窗体位置和大小。

    窗体有Left,Right,Top,Bottom属性,似乎很完美,应该定义这四项,就能明确指定窗体的大小和位置了吧?然而并非如此。RightBottom是只读的属性,可以用它们来获取窗体边距,却不能用来指定边距。

    确定窗体位置,只需要窗体左上角这一个点的位置。Left,Top 就是这个点与屏幕左、上边距的距离,换句话说,窗体的Location属性,实际上就是(Left,Top)。 下面的语句是等价的:

    this.Location=new Point(100,100);

    this.Left = 100; this.Top = 100;

    而确定窗体的大小,用Width 宽度和Height高度,就够了。指定当前窗体的大小很简单:

     this.Width = 600;

     this.Height =480;

    窗体是有最小值和最大值的,可以通过设置MaximumSizeMinimumSize来指定。如果没有指定,最大不能超过屏幕分辨率,最小不是(0,0),而是系统自己计算出的能让这几个图标显示出来的大小:   

    有时候涉及到对于窗体大小的动态调整,就应该注意判断,不要越界。那么如果想设置窗体能根据不同屏幕的大小自动调整呢?

     

    三、 根据分辨率调整窗体大小

    首先要获取屏幕大小:

                int width = Screen.PrimaryScreen.WorkingArea.Width;

                int height = Screen.PrimaryScreen.WorkingArea.Width;

    Screen.PrimaryScrenn为获取显示器,如果有多显示器也可以用Screen.AllScreens[0],Screen.AllScreens[1]...WorkingArea为桌面工作区域,不包括任务栏等。

    然后设置宽度和高度:

                this.Width = (int)(width / 2);

                this.Height = (int)(height / 2);

     

    四、窗体最大化、最小化和全屏

    通过设置WindowsState属性为MaximizedManimized来实现窗体的最大化和最小化。如果需要全屏显示,可将窗体大小设置为屏幕大小(见三)。但此时可能需要隐藏上方的图标、标题、最大最小化和关闭按钮。方法为设置FormBorderStyleNone

     

    五、窗体置于顶层

    设置TopMost属性为True即可。

     

    由上述内容可见,基本上都是通过设置窗体的属性来实现,在学习过程中,对各种属性应该有一个基本的了解。.net将很多工作都隐藏在幕后,所以在属性窗口的设置,其实也可以通过代码来实现。如果有不清楚的地方,可以打开对应的Designer.cs文件来查看,更是大大方便了学习。可以看这一段:

               //

              // Form1

                //

                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);

                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

                this.Controls.Add(this.btnOpenNewForm);

                this.Controls.Add(this.btnChangePos);

                this.Controls.Add(this.txttop);

                this.Controls.Add(this.txtWidth);

                this.Controls.Add(this.txtHeight);

                this.Controls.Add(this.txtLeft);

                this.Controls.Add(this.label4);

                this.Controls.Add(this.label3);

                this.Controls.Add(this.label2);

                this.Controls.Add(this.label1);

                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

                this.Name = "Form1";

                //起始居中

                this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

                //窗体位置和大小

                this.Location = new System.Drawing.Point(100, 100);

                this.ClientSize = new System.Drawing.Size(454, 400);

     

                this.Text = "Form1";

                //窗体置顶

                this.TopMost = true;

                //窗体最大化

                this.WindowState = System.Windows.Forms.FormWindowState.Maximized;

                this.Load += new System.EventHandler(this.Form1_Load);

                this.ResumeLayout(false);

                this.PerformLayout();


    展开全文
  • Windows编程之虚拟桌面实现原理

    千次阅读 2020-06-07 13:56:14
    Win10中可以点击任务视图按钮,在最上面就可以创建,(虚拟桌面在Linux操作系统是一个标配,但是在Windows操作系统一直没有此功能,直到Win10才加入这项功能)。 笔记本的话四个手指左右滑动触摸板就可以切换,...
  • 自己用C#编写了一个学生信息管理系统Windows桌面应用程序,第一次实践,某些地方可能还不够完善,但其中有些函数、方法等的使用可以参考。 工具 我用的集成开发环境是Visual Studio 2019,数据库是MySQL,可视化...
  • Go实战--使用golang开发Windows Gui桌面程序(lxn/walk)

    万次阅读 多人点赞 2017-09-12 20:23:57
    golang官方并没有提供Windows gui库,但是今天还是要跟大家分享一下使用golang开发Windows桌面程序,当然又是面向github编程了。知乎上有一个问答: golang为什么没有官方的gui包?这里,主要使用第三方库lxn/walk...
  • 基于VC#2010 .NET4.0 的环境监测系统上位机软件源码; 该软件需要与下位机配合使用。 采用串口+无线网络通信方式; 可视图形显示
  • 源码不是我写的,但是我在基础上修改了一些...jQuery制作Web桌面系统界面类似WebQQ桌面布局 js有些修改。 左边是图标,双击可弹出弹框,弹框之间可进行切换,弹框可缩小放大,右下角的小图标内容是缩略图。
  • WinForm框架 是 Windows Form 的简称,是美国微软公司Microsoft开发基于 .NET Framework 平台的桌面运用程序框架, WinForm框架可用于设计窗体,采用面向对象语言C#,可快速创建绚丽漂亮的基于Windows桌面应用程序...
  • Windows 系统API 函数快速查找

    千次阅读 2018-05-19 16:56:54
    CreateScalableFontResource 为一种TureType字体创建一个资源文件,以便能用API函数AddFontResource将其加入Windows系统 DrawText 将文本描绘到指定的矩形中 DrawTextEx 与DrawText相似,只是加入了更多的功能 ...
  • VNC Viewer 连接远程电脑桌面 UI自动化测试的示例代码 #!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @Author: 思文伟 @Date: 2021/03/30 15:49:32 ''' import io import os import sys from appium ...
  • VS2008 Windows Form项目安装包生成详解

    千次阅读 2016-12-13 19:14:07
    Visual Studio 2008 Windows Form项目的发布对有经验的程序员来说,可能不值一提,但对很多新手来说却不知道如何操作,因为在很多关于Visual Studio的书籍中也没有相关介绍,权威如《C# 2005/8 高级编程》对该内容也...
  • 一个高校网上选课数据库系统,使用Windows Form桌面应用开发,功能简要如下: (1) 系统用户由三类组成:教师、学生和管理员。 (2) 管理员负责的主要功能: ① 用户管理(老师、学生及管理员的增、删、改); ② 课程...
  • Go实战--使用golang开发Windows Gui桌面程序 lxn/walk
  • C# Windows窗体应用制作的选课系统项目要求项目成果项目源码源码地址End 项目要求 北理工小学期数据库大作业 设计数据库,基本信息包括学生、课程、教师,学生从已分配教师的课程列表中选择相应的课程(课程列表项...
  • wpf 捕获桌面快照Taking screenshot is important because if we want to show something to our audience or put picture to the document we will need meaningful graphs. Windows all ready provides screenshot...
  • windows系统日志查看

    万次阅读 多人点赞 2019-05-29 09:06:16
    或者同时按下 Windows键 + R键,输入“eventvwr.msc”直接打开「事件查看器」。 2、接下来你会在窗口中看到一个列表,包括 “关键字”、 “日期和时间”、“来源”、“事件ID”、“任务类别”。 3、事件id...
  • Windows 10的虚拟桌面

    千次阅读 2019-12-27 14:56:06
    Windows 10发布后,Windows系统外壳终于内置了虚拟桌面功能。虽然该功能有些跟随Mac多重桌面的嫌疑,但它的确极大方便了桌面组织。 首先,本文将介绍一些使用虚拟桌面的快捷键。然后,讨论使用...
  • C#桌面办公应用-工资管理系统系列九 今天介绍介绍一下我自主开发的工资管理系统中的“汇总查询打印”模块,改小模块具有以下的功能:可以汇总统计员工的工资发放明细信息,可以查询指定的某个部门下的某些员工的...
  • Windows系统下CMD命令

    千次阅读 2019-02-20 10:20:06
     虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全、稳定,有的用户还在使用,所以一般Windows 的各种版本都与其兼容,用户可以在Windows 系统下运行DOS...
  • BOOT 启动的设备项 系统镜像下载地址 制作 U 启动盘 制作启动盘模式选择 操作系统的分区 操作系统支持的文件系统类型 Windows 系统分区 Linux 系统分区 DiskGenius 分区工具一些特殊功能 Win 系统 ISO 镜像安装模式...
  • 文章目录查看系统运行时间、版本等详细信息命令关机和重启方法windows_cmd命令大全简介使用说明CMD命令锦集操作详解FTP使用的内部命令如下(中括号表示可选项): 查看系统运行时间、版本等详细信息 win+r→输入cmd ...
  • 桌面精灵制作记录

    千次阅读 多人点赞 2021-05-22 23:17:51
    想做一个会跳舞的,打字驱动跳舞、可以聊天的桌面精灵 接入聊天AI 市面上的人工智能回答很多产品。比较流行的好用的有: 1.微软小娜和微软小冰,似乎是微软小娜比较好,微软小冰还处于比较基础的日常聊天,但...
  • form:https://www.cnblogs.com/Bob-wei/p/6055087.html github:https://github.com/m2nlight/WindowsServerToWindowsDesktop 下载:...
  • 2021-10-15 远程桌面爆破

    千次阅读 2021-10-15 17:20:48
    (2)Windows 11×64 虚拟机(可以被远程连接的Windows系统均可) 四、实验步骤: (1)在kali中创建密码字典(存放位置可自定义): 命令:touch /home/kali/Desktop/password.txt (2)编辑密码字典,存入...
  • 什么是WinFormhttps://docs.microsoft.com/zh-cn/dotnet/desktop/winformsWindows窗体(Windows Form),简称Wi...
  • golang开发Windows Gui桌面程序(lxn/walk)

    千次阅读 2018-12-12 12:36:00
    版权声明:本文为博主原创文章,未经博主允许不得转载。...golang官方并没有提供Windows gui库,但是今天还是要跟大家分享一下使用golang开发Windows桌面程序,当然又是面向github编程了。 知乎上有一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,034
精华内容 6,013
关键字:

windowsform桌面系统