使用Inno SetUp脚本打包Winform程序

Innosetup打包工具,从工具安装到脚本编写到打包发布 Innosetup打包工具,从工具安装到脚本编写到打包发布,里边有Innosetup设置管理员权限,Innosetup卸载旧程序,Innosetup检查是否64位系统等等说明 阅读详情

在开发桌面程序时,往往需要用到打包工具将程序打包为exe可执行文件。

之前在项目中用了下 InstallShield Limited Edition for Visual Studio  2015,它的功能很强大,但是需要付费使用,而且有些细粒度的操作比较复杂。

后来,我发现了一款简单方便的打包工具,即我们今天的主角Inno Setup

Inno Setup 支持pascal脚本,这样我们就能通过直接写脚本来实现功能了。

下面我们来看看我们打包过程中常见功能需求:

  1. 创建安装exe文件
  2. 创建卸载exe文件
  3. 创建各种快捷方式,桌面、快速启动栏等
  4. 安装、卸载Windows 服务
  5. 添加注册表信息
  6. 打包.Net framework 环境
  7. 安装时不能同时运行两个安装程序
  8. 安装/卸载时检测程序(或服务)是否在运行,如果在运行则先关闭程序。

程序的使用方法就不多做介绍了,打开程序新建脚本,会创建出一个基本的框架,然后我们就可以修改脚本添加功能了。

上面的1、2、3 条功能基本的脚本已经帮我们实现了。

关于操作windows服务,我这里收藏了一个极好用的脚本。

//  Code pasted from the following address, for examples and more visit it:
//  http://www.vincenzo.net/isxkb/index.php?title=Service_-_Functions_to_Start%2C_Stop%2C_Install%2C_Remove_a_Service


// function IsServiceInstalled(ServiceName: string) : boolean;
// function IsServiceRunning(ServiceName: string) : boolean;
// function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
// function RemoveService(ServiceName: string) : boolean;
// function StartService(ServiceName: string) : boolean;
// function StopService(ServiceName: string) : boolean;
// function SetupService(service, port, comment: string) : boolean;

type
    SERVICE_STATUS = record
        dwServiceType               : cardinal;
        dwCurrentState              : cardinal;
        dwControlsAccepted          : cardinal;
        dwWin32ExitCode             : cardinal;
        dwServiceSpecificExitCode   : cardinal;
        dwCheckPoint                : cardinal;
        dwWaitHint                  : cardinal;
    end;
    HANDLE = cardinal;

const
    SERVICE_QUERY_CONFIG        = $1;
    SERVICE_CHANGE_CONFIG       = $2;
    SERVICE_QUERY_STATUS        = $4;
    SERVICE_START               = $10;
    SERVICE_STOP                = $20;
    SERVICE_ALL_ACCESS          = $f01ff;
    SC_MANAGER_ALL_ACCESS       = $f003f;
    SERVICE_WIN32_OWN_PROCESS   = $10;
    SERVICE_WIN32_SHARE_PROCESS = $20;
    SERVICE_WIN32               = $30;
    SERVICE_INTERACTIVE_PROCESS = $100;
    SERVICE_BOOT_START          = $0;
    SERVICE_SYSTEM_START        = $1;
    SERVICE_AUTO_START          = $2;
    SERVICE_DEMAND_START        = $3;
    SERVICE_DISABLED            = $4;
    SERVICE_DELETE              = $10000;
    SERVICE_CONTROL_STOP        = $1;
    SERVICE_CONTROL_PAUSE       = $2;
    SERVICE_CONTROL_CONTINUE    = $3;
    SERVICE_CONTROL_INTERROGATE = $4;
    SERVICE_STOPPED             = $1;
    SERVICE_START_PENDING       = $2;
    SERVICE_STOP_PENDING        = $3;
    SERVICE_RUNNING             = $4;
    SERVICE_CONTINUE_PENDING    = $5;
    SERVICE_PAUSE_PENDING       = $6;
    SERVICE_PAUSED              = $7;

// #######################################################################################
// nt based service utilities
// #######################################################################################
function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
external 'OpenSCManagerA@advapi32.dll stdcall';

function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
external 'OpenServiceA@advapi32.dll stdcall';

function CloseServiceHandle(hSCObject :HANDLE): boolean;
external 'CloseServiceHandle@advapi32.dll stdcall';

function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
external 'CreateServiceA@advapi32.dll stdcall';

function DeleteService(hService :HANDLE): boolean;
external 'DeleteService@advapi32.dll stdcall';

function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
external 'StartServiceA@advapi32.dll stdcall';

function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
external 'ControlService@advapi32.dll stdcall';

function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
external 'QueryServiceStatus@advapi32.dll stdcall';

function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
external 'QueryServiceStatus@advapi32.dll stdcall';

function GetLastError() : cardinal;
external 'GetLastError@kernel32.dll stdcall';

function OpenServiceManager() : HANDLE;
begin
    if UsingWinNT() = true then begin
        Result := OpenSCManager('','',SC_MANAGER_ALL_ACCESS);
        if Result = 0 then
            MsgBox('the servicemanager is not available', mbError, MB_OK)
    end
    else begin
            MsgBox('only nt based systems support services', mbError, MB_OK)
            Result := 0;
    end
end;

function IsServiceInstalled(ServiceName: string) : boolean;
var
    hSCM    : HANDLE;
    hService: HANDLE;
begin
    hSCM := OpenServiceManager();
    Result := false;
    if hSCM <> 0 then begin
        hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_CONFIG);
        if hService <> 0 then begin
            Result := true;
            CloseServiceHandle(hService)
        end;
        CloseServiceHandle(hSCM)
    end
end;

function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
var
    hSCM    : HANDLE;
    hService: HANDLE;
begin
    hSCM := OpenServiceManager();
    Result := false;
    if hSCM <> 0 then begin
        hService := CreateService(hSCM,ServiceName,DisplayName,SERVICE_ALL_ACCESS,ServiceType,StartType,0,FileName,'',0,'','','');
        if hService <> 0 then begin
            Result := true;
            // Win2K & WinXP supports aditional description text for services
            if Description<> '' then
                RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName,'Description',Description);
            CloseServiceHandle(hService)
        end;
        CloseServiceHandle(hSCM)
    end
end;

function RemoveService(ServiceName: string) : boolean;
var
    hSCM    : HANDLE;
    hService: HANDLE;
begin
    hSCM := OpenServiceManager();
    Result := false;
    if hSCM <> 0 then begin
        hService := OpenService(hSCM,ServiceName,SERVICE_DELETE);
        if hService <> 0 then begin
            Result := DeleteService(hService);
            CloseServiceHandle(hService)
        end;
        CloseServiceHandle(hSCM)
    end
end;

function StartService(ServiceName: string) : boolean;
var
    hSCM    : HANDLE;
    hService: HANDLE;
begin
    hSCM := OpenServiceManager();
    Result := false;
    if hSCM <> 0 then begin
        hService := OpenService(hSCM,ServiceName,SERVICE_START);
        if hService <> 0 then begin
            Result := StartNTService(hService,0,0);
            CloseServiceHandle(hService)
        end;
        CloseServiceHandle(hSCM)
    end;
end;

function StopService(ServiceName: string) : boolean;
var
    hSCM    : HANDLE;
    hService: HANDLE;
    Status  : SERVICE_STATUS;
begin
    hSCM := OpenServiceManager();
    Result := false;
    if hSCM <> 0 then begin
        hService := OpenService(hSCM,ServiceName,SERVICE_STOP);
        if hService <> 0 then begin
            Result := ControlService(hService,SERVICE_CONTROL_STOP,Status);
            CloseServiceHandle(hService)
        end;
        CloseServiceHandle(hSCM)
    end;
end;

function IsServiceRunning(ServiceName: string) : boolean;
var
    hSCM    : HANDLE;
    hService: HANDLE;
    Status  : SERVICE_STATUS;
begin
    hSCM := OpenServiceManager();
    Result := false;
    if hSCM <> 0 then begin
        hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_STATUS);
        if hService <> 0 then begin
            if QueryServiceStatus(hService,Status) then begin
                Result :=(Status.dwCurrentState = SERVICE_RUNNING)
            end;
            CloseServiceHandle(hService)
            end;
        CloseServiceHandle(hSCM)
    end
end;

有了这个脚本,windows 服务怎么玩都可以了,在[code]  下把这个文件加上就可以使用其中的方法了。

接下来要操作注册表了,在[Registry]下写脚本我们就可以操作注册表了,格式如下:

[Registry]
Root: HKLM; Subkey: "SOFTWARE\ODBC\ODBC.INI\bsjdw101100";ValueType: string; ValueName: "AutoStop"; ValueData: "Yes"
Root: HKLM; Subkey: "SOFTWARE\ODBC\ODBC.INI\bsjdw101100";ValueType: string; ValueName: "Debug"; ValueData: "No"

修改的东西包括,注册表路径、值类型、key和value。

再往下,我们就要写打包.Net framework 进安装包。XP 没有自带.Net framework 环境,有的可能会带 2.0 。win 7 自带 .Net framework 3.5(包含 .NET 2.0 and 3.0) ,Windows 8 默认安装了 .NET Framework 4.5 (包含 4.0)。但是.Net 4.0是不向下兼容.Net 3.5的,所以即使你装了4.0 你的程序可能还是用不了。感兴趣可以参考Net Framework各个版本区别

下面我们来看看这些脚本怎么写?

首先我们要把.Net 环境加入到打包程序中

[file]
Source: "D:\NetFx20SP2_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion {#IsExternal}; Check: NeedsFramework
<pre name="code" class="plain">//添加执行操作
[Run]
Filename: {tmp}\NetFx20SP2_x86.exe; Parameters: "/q:a /c:""install /l /q"""; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: "Installing .NET Framework if needed"
Filename: {win}\Microsoft.NET\Framework\v2.0.50727\CasPol.exe; Parameters: "-q -machine -remgroup ""{#MyAppName}"""; WorkingDir: {tmp}; Flags: skipifdoesntexist runhidden; StatusMsg: "Setting Program Access Permissions..."
Filename: {win}\Microsoft.NET\Framework\v2.0.50727\CasPol.exe; Parameters: "-q -machine -addgroup 1.2 -url ""file://{app}/*"" FullTrust -name ""{#MyAppName}"""; WorkingDir: {tmp}; Flags: skipifdoesntexist runhidden; StatusMsg: "Setting Program Access Permissions..."

 

检查目标系统中是否有.Net 环境(以2.0为例),有则安装,无则不装。

//判断是否需要安装.NET Framework 2.0 SP1(或以上)
function NeedsFramework(): Boolean;
begin
  Result := (IsDotNET20Detected = false);
end;

function IsDotNET20Detected(): boolean;
var
    success: boolean;
    sp: cardinal;
begin
    
    success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'SP', sp);
    Result :=  success and (sp >= 1);
end;

接着,我们要建立互斥变量来限制只能运行一个安装程序。

function InitializeSetup():boolean;
var bResult:boolean;

begin
    Result := true;
    
    //检测是否有另一个安装程序在运行
    bResult :=  CheckForMutexes('MutexBugskySetup');
    if  bResult = true then
    begin
       MsgBox('另一安装程序已经在运行,此安装程序将退出。',mbInformation,MB_OK);
       Result := false;
       Exit;
    end else
    begin
        //没有就创建互斥量
        CreateMutex('MutexBugskySetup');
    end;
end;

接下来我们要检查安装和卸载时是否程序正在运行,为了提示用户保存数据,所以要关闭程序后再安装。

<pre name="code" class="plain">function InitializeSetup():boolean;

var ResultCode:Integer;
var hwnd:HWND;
var CloseNum:integer

begin //先检测进程中程序是否在运行 hwnd := FindWindowByWindowName('{#MyAppName}'); CloseNum := 0; if hwnd <> 0 then begin ResultCode := MsgBox('检测程序正在运行,是否关闭程序继续安装?'#13 #10'选择“是”继续安装;选择“否”,退出安装。',mbInformation,MB_YESNO); //继续安装 if ResultCode = IDYES then begin Result := true; end else begin Result := false; Exit; end; end; while ((hwnd <> 0) and (CloseNum < 5)) do begin //关闭服务程序,尝试5次。 PostMessage(hwnd,18,0,0); Sleep(100); CloseNum := CloseNum + 1; hwnd := FindWindowByWindowName('{#MyAppName}'); end; if IsServiceRunning('{#MyAppServiceName}') then begin StopService('{#MyAppServiceName}'); end end;

end;

卸载的时候,只要在CurUninstallStepChanged()方法中做同样的事就行了。

 

好了,就写到这里了,具体的语法和API请参考 Inno Setup帮助文档。


参考:

http://www.cnblogs.com/xiaogangqq123/archive/2012/03/19/2405730.html

http://stackoverflow.com/questions/2456987/upgrading-windows-service-using-inno-setup












WinForm用微软打包工具打包 下载扩展点击扩展 —> 管理扩展安装完之后重启VS就好了。 阅读详情

相关推荐

【小白专用】WinForm项目打包成一个exe安装包教程(VS2022)

winform程序打包为安装文件

zgscwxd的博客 1万+

Inno Setup打包winform、wpf程序可判断VC++和.net环境

Inno SetUpd打包客户端程序、Winform、wpf程序 可判断安装时缺少的环境如Vc++和.net版本

二十多岁头发茂密的年轻人的博客 2882

不止于打包:用Inno Setup Compiler为你的WinForm/WPF应用添加URL Scheme唤醒功能(SpringBoot示例)

本文详细介绍了如何利用Inno Setup Compiler为WinForm/WPF应用添加URL Scheme唤醒功能,实现从浏览器链接直接唤醒桌面应用并传递参数。通过注册表配置、应用端参数处理和安全增强措施,开发者可以轻松实现类似微信、钉钉的深度链接功能,提升用户体验和应用交互性。

368

使用Inno Setup打包Winform程序

使用Inno Setup打包Winform程序步骤: ①  注意:程序中所有引用的dll的属性“复制到本地”必须设置为true; ②  在VS中将解决方案配置从Debug改为Release,然后启动程序; ③  删除本地Release文件夹中的所有.pdb文件; ④  运行Inno Setup,选择“文件”菜单中的“新建”,一步一步操作(可设置打包程序名称、安装密码等),在其中的某一步选择

Anigado1992的博客 2684

WinForm程序打包工具InnoSetup使用说明图文教程

WinForm程序开发测试好了,如果将Debug/Release里面的文件发给客户使用,会让客户觉得你不够专业,但是使用VS自带的打包工具太繁琐太复杂,稍微有一个地方没有配置好,就可能会造成打包失败或达不到预期的效果。有没有一种更加简单Winform程序打包工具呢?答案是有的。InnoSetup可以配置创建快捷方式、开始菜单文件夹、快捷菜单等等,具有配置简单,条理清晰等特点,基本可以满足日常的程序...

阿斌分享 4324

WinForm程序打包成安装包?这款老工具依然好用(附详细配置步骤)

本文详细介绍了如何使用Inno Setup这款经典工具将WinForm程序打包成专业的安装程序。针对传统.NET Framework项目,特别是使用旧版Visual Studio的开发者,文章提供了从环境准备、脚本配置到解决.NET依赖和兼容性问题的完整步骤,帮助开发者高效生成可交付的exe安装包。

weixin_29228203的博客 317

WinForm 程序打包成 exe 安装包:Inno Setup 实战指南

在 Windows 桌面软件交付中,WinForm 应用通常由 exe、dll、配置文件和 .NET 运行库共同构成,单纯压缩包分发容易引发缺 dll、配置丢失、快捷方式与卸载入口缺失等问题。安装包的本质是用脚本描述文件落盘、注册表与快捷方式创建、卸载清理及运行库检测,把发布目录封装成可维护的 Windows 安装程序。它的技术价值在于统一安装路径、权限模型和升级/卸载体验,降低部署故障与支持成本。常见于内部工具、桌面业务系统、企业批量部署及 CI 自动出包场景。围绕这些需求,Inno Setup 以 in

weixin_42619742的博客 303

是德频谱分析仪相位噪声测量实战指南:从原理到精准操作

本文详细介绍了是德频谱分析仪在相位噪声测量中的实战操作指南,从基础概念到高级技巧全面解析。通过5G基站时钟测量等实际案例,展示如何利用是德N9030B等设备精准测量相位噪声,并分享设备预热、参数设置、环境干扰排除等关键操作要点,帮助工程师提升测量精度和效率。

jenkins8butler的博客 229

windows端软件打包简易方法

本文介绍了使用InnoSetup将Windows桌面端软件打包成正式安装包的方法。首先需要准备好Release编译后的项目文件(包括主程序exe和所有依赖文件),然后通过InnoSetup的脚本向导逐步设置:填写应用信息、选择安装目录、添加程序文件、配置快捷方式等。重点包括勾选创建卸载选项、添加简体中文支持、设置安装包输出路径等关键步骤。整个过程无需编写代码,通过可视化界面即可完成专业安装包的制作,适合需要将内部工具转为正式交付给客户使用的场景。最终生成的Setup.exe安装包支持标准安装流程,包含开始菜

WangMing_X的博客 363

Abaqus中使用Python提取裂缝数据并用matplotlib库绘图

ABAQUS后处理PYTHON二次开发代码:提取裂缝数据并用matplotlib库绘图

qq_42568527的博客 3470

Android Qcom USB Driver学习(十三)

该系列文章总目录链接与各部分简介: Android Qcom USB Driver学习(零) Android Qcom USB Driver学习(八) Android Qcom USB Driver学习(九)deals with the USB Power Delivery resources used by one or more ports on the basis of the local device policy the basis of the local device policy.opera

Android驱动开发 2611

Inno Setup 打包winform程序exe

使用开源info setup打包winfrom安装程序exe

tutouxiaoyaonie的博客 1671

SoC设计中的RDC陷阱:如何避免异步复位导致的亚稳态问题

本文深入探讨了SoC设计中由异步复位引发的复位域交叉(RDC)陷阱及其导致的亚稳态风险。通过分析实际案例,文章系统性地提出了以同步复位优先、异步复位同步释放为核心的设计原则,并介绍了电路级加固与验证策略,为构建稳健的SoC复位架构提供了实用指南。

weixin_29280657的博客 419

Inno Setup 打包 WinForm exe 生产级安装包实战

桌面应用交付中,安装包制作并非简单压缩 exe,而是把运行环境、文件落位、快捷入口和卸载清理固化为可重复执行的安装契约。以 Inno Setup 为代表的脚本化打包工具,通过纯文本 iss 脚本声明安装流程,并可在编译阶段检测 .NET 运行库、生成桌面和开始菜单快捷方式、支持 /SILENT 静默安装与命令行分发。其技术价值在于降低目标机器环境差异带来的启动失败和权限问题,同时便于接入 CI 完成版本注入、代码签名与产物校验。对于中小型 WinForm 桌面程序、内部工具和企业批量部署场景,Inno Se

weixin_28839439的博客 270

cadence capture CIS 之添加数据库

2021-08-20 cadence capture CIS 之添加数据库准备一、添加数据源 准备 1、数据库文件(*.mdb) 2、电脑上安装好 cadence 软件 一、添加数据源 打开“ ODBC数据源管理器” ( 路径:C:\Windows\SysWOW64\odbcad32.exe ) ...

weixin_42256550的博客 6054

别再只用跳层连接了!手把手教你用DASI和MDCR模块提升红外小目标检测精度

本文详细介绍了如何利用DASI和MDCR模块提升红外小目标检测精度。通过分析传统跳层连接的缺陷,提出维度感知的特征选择性融合(DASI)和多尺度感受野精炼器(MDCR)的创新方案,显著提升小目标检测性能。实验证明,该方法在多个场景下AP@0.5提升达15.4%,特别适用于安防监控和遥感图像分析。

weixin_28715081的博客 224

使用免费的Inno Setup制作Winform安装包

1. 先展示几张效果图: 2. 下载免费的Inno Setup程序 https://jrsoftware.org/isdl.php 3. Inno Setup程序入门 Inno Setup的安装目录下面有很多demo,供我们参考 4. 我的Inno Setup打包实例 ; -- Example1.iss -- ; Demonstrates copying 3 files and c...

cgs的博客 942

APP爬虫:Airtest的使用和爬取实战详解

Airtest是一个跨平台的自动化测试工具,主要用于移动应用和游戏的UI自动化测试。它支持图像识别、触摸操作、文本输入等功能,能够模拟真实用户的操作行为。此外,Airtest还具备强大的日志记录和报告生成功能,方便开发者进行调试和分析。图像识别:通过截图匹配元素,无需依赖 UI 层次结构。跨平台支持:支持 Android、iOS 和 Windows 应用。简单易用:提供 IDE 和脚本录制功能,降低使用门槛。

数据知道的博客 9619

不止于打包:用Inno Setup为你的WinForm/WPF应用添加URL Scheme唤醒功能

本文深入探讨了如何利用Inno Setup为WinForm/WPF应用实现URL Scheme唤醒功能,从协议注册到参数处理的完整流程。通过详细的脚本解析和C#实战代码,帮助开发者实现网页到客户端的无缝跳转,提升用户体验和应用留存率。

weixin_32520601的博客 235

2021年全网最细 VirtualBox 虚拟机安装 Ubuntu 20.04.2.0 LTS及Ubuntu的相关配置

目录一、VirtualBox 虚拟机的安装1. VirtualBox 的下载和安装2. 设置 VirtualBox 存储文件夹3. 在 VirtualBox 创建虚拟机二、Linux 操作系统(Ubuntu)的安装1. Linux 操作系统(Ubuntu)的下载2. 安装 Ubuntu3. 启动 Ubuntu三、配置 Ubuntu1. 设置终端2. 设置共享剪贴板3. 设置共享文件夹 一、VirtualBox 虚拟机的安装 VirtualBox 是由德国 Innotek 公司开发,由 Sun Microsy

XAMO Lab|代码、调试与复盘笔记 2万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C# winform利用Inno Steup图文打包教程

Inno Steup下载连接:链接:https://pan.baidu.com/s/19uYSHxYuqnT2-XL-100DeA 提取码:f6vs 下载好之后,打开Inno Steup软件 第一步 创建一个空白的脚本文件,下一步,完成 第二步 新建 不勾选 下一步 继续下一步 继续下一步 下图为上一步勾选的内容 之后继续下一步 填好之后下一步 可以什么都不用填,继续下一步...

sanpu 1384

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

使用开源安装包制作工具Inno Setup制作软件安装包

大家在进行Winform、MFC开发的时候,如果工程中引用了大量的dll,和配置文件的时候,整个release文件夹会显得文件又多又繁琐,特别是发送给客户使用过程中,还要担心某个dll被误删除,而导致软件无法使用。这个时候我们如果把整个release文件夹制作成安装包,安装完以后,桌面只显示一个快捷方式,那是很方便又简洁。 本文给大家推荐一款开源的安装制作软件Inno Setup,Inno Setup是Jordan Russell和Martijn Laan的Windows程...

王小波门下走狗 4125

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

inno setup 打包exe程序

inno setup 用于打包生成安装程序, 是通过的一个脚本 可以将 exe 执行文件以安装的形式,解压,添加依赖,创建快捷方式。 例如,我们写了个winform,我们怎么通过安装的形式,给客户的机器安装呢,这时就可以使用inno setup 打包工具来将我们的winfrom程序及其相关的文件打包成一个安装程序。 打开安装程序呈现如下结果: 跟我们普通的安装一个程序是一...

dgnwy6921的博客 217

打包工具Inno Setup的使用

对于一些相对简单的程序使用InnoSetup相当合适,官网地址 http://www.jrsoftware.org/isinfo.php,下面一起看看如何使用吧。 前提:已经有一个开发完毕的程序,这里就以我做的Winform程序为例。 1.打开InnoSetup,创建空白脚本文件。 2.使用脚本向导创建脚本。 3.填写程序的基本信息。 4.

風☆小贤‘s 烂笔头 3111
上一篇: 程序员必读书单
下一篇: WebBrowser(IE) 与 JS 相互调用
TaiSung
博客等级 码龄15年 49粉丝 132原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值