如何制作驱动程序的自动安装包?(100分,急)

Gargamel 2002-04-29 11:34:00
我所写的一个软件中用到了第三方的一个NDIS网络协议驱动程序。

现在的问题是:在制作应用程序的安装程序时(Visual C++开发, Installshield 打包),怎么样处理这个驱动程序,使得它在软件安装中
也可被正确装入系统?

除了拷贝驱动程序,写特定键值外,还需要作什么?必写的键值是哪些?在Installshield中具体如何操作?

请高手解答。谢谢
...全文
2311 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
10ach 2002-05-08
  • 打赏
  • 举报
回复
F:\mssql7\BINN>regrebld /?

Microsoft SQL Server Registry Rebuild App accepts the following command-line arguments:

-Backup <Directory to put backup files (Defaults to same directory as regrebld.exe)>

If the backup files already exist this will fail

-Restore <Directory location of backup files (Defaults to same directory as regrebld.exe)>

-ShortcutsOnly 1 <can only be used in Restore mode>

No command-line arguments indicate to do a full Registry Rebuild with backup, re-creating shortcuts, and verifying state of services on Windows NT. When verifying state of services Registry Rebuild should always be run from the SQL Server BINN directory.

Rebuildm.exe—Rebuild Master Database
The source directory in the following dialog box refers to the location of the original SQL Server files (that is, the distribution CD or network share point).



VSwitch.exe—Switches Between SQL Server 7.0 and 6.x Installations (Windows NT Only)
This utility can be located by clicking the Start button, pointing to Programs, pointing to Microsoft SQL Server—Switch, and then clicking SQL Server 7.0. This utility is included to offer systems in transition from SQL Server 6.x to 7.0 the capability to move between SQL Server versions 6.x and 7.0. The utility does not allow both versions of SQL Server to be run simultaneously, and it is only intended to be used during the migration phase, not in daily production. The utility copies the current registry value to either the MSSQLSERV6.x or 7.0 registry key and then moves the desired version information (6.x or 7.0) to the MSSQLServer entry. Additionally, it changes the PATH statement to reflect the Mssql or Mssql7 directory.

Remote Installation


Remote Setup is supported on Windows NT-to-Windows NT computers only; both computers must be of the same processor type. Remote Setup is not supported on a clustered Windows NT Server. Remote Setup can only be used for a new installation. Upgrades, maintenance mode, or build-to-build upgrades are not supported.

Remote Setup will only install the same version of SQL Server 7.0 on the remote computer as the one that is being run on the source computer. For example, if you are running the SQL Server 7.0 standard edition on a Windows NT Server computer and attempt to remotely install SQL Server 7.0 standard version to a Windows NT Workstation computer, the setup will fail because Windows NT Workstation only supports the client installation of the standard SQL Server 7.0 edition (Windows NT Workstation does support the desktop version of SQL Server 7.0). Use the same version of SQL Server on the local computer as the one you will be installing on remote computers.

The user account specified must be an administrator on the remote computer and have read access to the universal naming convention (UNC) path that is specified for the source files. The "logon as service" right is granted to this account on the remote computer during the remote setup process.

The "remsetup.exe" copies the generated setup.iss file to \\targetmachine\admin$, and then runs the Service Control Manager to create a remote service, therefore account supplied must be an administrator on the remote computer because it is creating a service and copying files to admin$ share.

After the user has input all of the setup information, Setup records this information in an .iss file. On the local computer, Setup then launches remsetup.exe and exits. Remsetup.exe installs the remote service, copies all files to the admin$ share, and runs an unattended installation on the remote computer.

Frequently Asked Questions
How do I start an unattended setup?

To start an unattended installation, you must first generate an .iss file. You can create this file by starting SQL Server Setup with the -r option and then going through Setup, interactively making the selections you want. After the installation completes successfully, you will have a setup.iss file in your Windows directory. You can copy or move this file to another location if you want. On subsequent installations, you can start Setup and specify a previously generated .iss file as input by using the -f1 setup command-line option. For detailed information on scripting, see the "Scripting" section earlier in this document.

How do I uninstall SQL Server 7.0?

With SQL Server 7.0, you now have three ways to uninstall the program:

On the Start menu, point to Programs, and then point to Microsoft SQL Server 7.0 and click Uninstall SQL Server 7.0.


On the Start menu, point to Settings and click Control Panel. Double-click Add/Remove Programs. Select Microsoft SQL Server 7.0 from the list and then click Add/Remove.


Run a scripted uninstallation. For detailed information on how to do this, see the "Scripting" section earlier in this document.
How do I start an unattended uninstallation?

One of the results of a successful installation is the generation of an uninstallation script file, called uninst.isu that is located in the directory you installed the program files to. To start an unattended uninstallation, you must start the UnInstallShield executable file named isuninst.exe, and direct it to your uninstallation script file. For detailed information on how to do this, see the "Scripting" section earlier in this document.

Why do I lose my dialog box selections? Whenever I type information into a dialog box, click "Back" and then click "Next" again, the information that I typed in the dialog box is lost. Why does this happen?

This is the result of InstallShield dialog boxes. Unfortunately, at this time there is no workaround other than to simply retype the original text again.

What do I need to do if I have an unsuccessful installation?

If your installation fails and you are unable to determine the cause, look for and save the sqlstp.log file in the Windows directory, as well as any other files that are left under your target program directory location (for example, C:\Mssql7). Of particular interest are the cnfgsvr.out file and any error logs in the Mssql7\Log directory.

How do I rebuild the registry? How do I rebuild the master database? How do I reconfigure my server network protocols?

Rebuild Registry, Rebuild Master, and Configure Network Protocols have all been removed from the SQL Server Setup code. However, the same functionality will be granted through new utilities.

Why do I have to exit the SQL Server Service Manager before I uninstall the program? In earlier versions of SQL Server, Setup stopped SQL Server Service Manager when it initiated an uninstallation. Now I get an error message informing me that I need to exit this application. Why is this and why can't Setup close this application for me?

In earlier versions of SQL Server, Setup would attempt to shut down these services, without being able to completely guarantee success. This was changed so that the applications must be closed manually.

Why aren't some directories deleted when the product is uninstalled? Why does the final uninstall report always report that it cannot remove folders?

UnInstallShield only removes what it installs. In general, this is the correct behavior. However, some files, such as tempdb, are created outside the bounds of the InstallShield installation. When the InstallShield uninstaller runs, it tries to delete the folders that it created (Mssql7, Binn, Data, and Log) and finds that these folders are not empty. However, the .dll that is run after UnInstallShield is complete (sqlsun.dll) removes files, such as tempdb, and these folders.

Note If error logs, trace files, or user data remain in these directories, they will not be removed.


--------------------------------------------------------------------------------
Send feedback to MSDN.Look here for MSDN Online resources.
10ach 2002-05-08
  • 打赏
  • 举报
回复
Scripting
One of the most significant changes from moving to an InstallShield-based Setup has to do with unattended installations and uninstallations. Unfortunately, conversion or support of existing .ini files in the new Setup is not provided. For each existing .ini file, a new .iss file must be created, as described in this section.

Unattended Installation
To invoke an unattended installation, you must first generate an InstallShield .iss file. Start SQL Server Setup with the k=Rc switch and proceed through the dialog boxes to install SQL Server as normal. Doing this causes Setup to record your dialog box choices in a file named setup.iss, which is located in your Windows directory — this will not install SQL Server on the local computer. After this process is completed, the file can be moved or copied to another location for use on other servers. For subsequent automated installations, start Setup and specify a previously generated .iss file as input by using the -f1 setup command-line option. The syntax for this command is:

setupsql.exe -f1 <full path to iss file> -SMS -s

If the -SMS switch is not specified, the underlying InstallShield setup process, sqlstp.exe, starts a process to perform the Setup and will immediately return control back to the user. The -s switch causes Setup to run in a silent mode.

Unattended Uninstallation
To start an unattended uninstallation, run isuninst.exe with the -y switch to suppress confirmation of the uninstallation. The -a switch will suppress the dialog box that asks if you want to remove shared files, and the -f switch points UnInstallShield at the uninstallation script file that was generated during the initial Setup. The file "isuninst.isu" is created during Setup and is found in the MSSQL7 directory. Lastly, specify the SQL Server uninstall .dll file name (sqlsun.dll). This .dll file contains specific SQL Server actions that are taken during the uninstallation. An example of the syntax for the uninstall command is:

isuninst.exe –f <path to the isu file>\uninst.isu -cc:\mssql7\sqlsun.dll -y –a

Note When you attempted to uninstall SQL Server in earlier versions of SQL Server, Setup would attempt to stop a list of applications if they were running. This was not always successful and resulted in nondeterministic behavior. Setup now stops any of the SQL Server services that are running, but also reports back to the user if any of the SQL Server 7.0 applications are running and could not be stopped. The user must stop these applications or services before running the uninstallation process, either manually or by using a tool such as the Windows NT KILL command or Net Stop.

Sample sequence to install
The following example shows the commands used to generate the setup.iss file:

Setupsql –r "creates the initial iss file"
Copy c:\winnt\setup.iss to c:\myinstalls\sample.iss
Setupsql -f1 c:\myinstalls\sample.iss -SMS –s "uses the iss file for an unattended install"

Check for required restart as indicated in the sqlstp.log and restart if necessary. Run any verifications that are required.

Sample sequence to uninstall
The following example shows the commands needed to uninstall SQL Server 7.0:

Terminate any running SQL Server executables (e.g. sqlmanager.exe)
isuninst.exe –f c:\mssql7\uninst.isu -cc:\mssql7\sqlsun.dll -y –a

Return error codes from the sqlstp.log files created by running the unattended installation
When you run the unattended installation, an error may be returned. The errors you might receive are designated by error code numbers. The following is a list of possible error code numbers and their explanations.

The most common error code is -12, because a user will use an .iss file that is generated when an unexpected dialog box appears (because of a condition of the system).

If the -f2 option is not used to specify the path for this output file, it will be placed in the Windows root directory.

0 Success
-1 General error
-2 Invalid mode
-3 Required data not found in the setup.iss file
-4 Not enough memory available
-5 File does not exist
-6 Cannot write to the response file
-7 Unable to write to the log file
-8 Invalid path to the InstallShield Silent response file
-9 Not a valid list type (string or number)
-10 Data type is invalid
-11 Unknown error during setup
-12 Dialogs are out of order
-51 Cannot create the specified folder
-52 Cannot access the specified file or folder
-53 Invalid option selected


Windows 95/98 Limitations
Because of system limitations of the platform and performance issues, Windows 95/98 installations do not have the following capabilities:

Incoming Named Pipe connections


Windows NT Authentication


Asynchronous I/O


Transaction-based publishing


Clustering


Full text search


Auto-detection of unicode files


Windows NT Event log
Additional Tools
The following additional tools are also available. These tools are available on all platforms, unless otherwise noted.

Regrebld.exe—RegistryRebuild Utility (Command Line Only)
Regrebld.exe is run automatically when Setup completes the initial installation. This creates an image of all the Mssql7 registry entries with file names of Mssql7*.rbk. Running regrebld -Restore will place the registry key images into the registry. If the keys already exist, they will be overwritten. If changes are made to the SQL Server installation, backups of the registry keys are not automatically updated. In this case, you will need to rerun regrebld.exe manually to update the information. You may want to consider rerunning regrebld.exe after adding additional network support or changing the security options. The following shows the syntax of the Regrebld command, along with the valid arguments it can take:

我不是大明 2002-05-08
  • 打赏
  • 举报
回复
来学习一下!
aha0 2002-05-08
  • 打赏
  • 举报
回复
当然,首先你得拷贝文件。
aha0 2002-05-08
  • 打赏
  • 举报
回复
老兄,看到CreateService没有?这就是安装。
Gargamel 2002-04-30
  • 打赏
  • 举报
回复
谢谢回复。

不过你给出的例子似乎更应当说是如何加载驱动程序,而不是何安装驱动程序。

天哪,哪道就没人会吗
whz_time 2002-04-30
  • 打赏
  • 举报
回复
//接上面的
//卸载驱动程序。
void DelSvr( char * szSvrName )
{
SC_HANDLE hServiceMgr, hServiceTwdm;
SERVICE_STATUS SvrSta;
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hServiceMgr == NULL )
{
printf( "DelSvr::OpenSCManager() Faild %d ! n", GetLastError() );
return;
}
else
{
printf( "DelSvr::OpenSCManager() ok ! n" );
}
hServiceTwdm = OpenService( hServiceMgr, TEXT(szSvrName), SERVICE_ALL_ACCESS );

if( hServiceTwdm == NULL )
{
CloseServiceHandle( hServiceMgr );
printf( "DelSvr::OpenService() Faild %d ! n", GetLastError() );
return;
}
else
{
printf( "DelSvr::OpenService() ok ! n" );
}
//停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。
if( !ControlService( hServiceTwdm, SERVICE_CONTROL_STOP , &SvrSta ) )
{
printf( "DelSvr::ControlService() Faild %d !n", GetLastError() );
}
else
{
printf( "DelSvr::ControlService() ok !n" );
}
//动态卸载驱动程序。
if( !DeleteService( hServiceTwdm ) )
{
printf( "DelSvr:eleteSrevice() Faild %d !n", GetLastError() );
}
else
{
printf( "DelSvr:eleteSrevice() ok !n" );
}
CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );
return;
}

驱动程序:驱动程序很简单,
只有一个文件,实现了DriverEntry,DispatchCreate,DispatchClose,GpdUnload 四个函数。

#include <ntddk.h>

#define NT_DEVICE_NAME L"\Device\Twdm1"
#define DOS_DEVICE_NAME L"\DosDevices\Twdm1"

NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp);
VOID GpdUnload(PDRIVER_OBJECT DriverObject);

//////////////////////
PDEVICE_OBJECT fdo;
BOOLEAN fSymbolicLink;


NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{

//UNREFERENCED_PARAMETER (RegistryPath);
NTSTATUS status;
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;

DbgPrint( "TWDM: DriverEntry for Twdm.sys ...... n" );
fSymbolicLink = FALSE;

//
// Create dispatch points for the IRPs.
//

DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
//DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GpdDispatch;
DriverObject->DriverUnload = GpdUnload;
//DriverObject->MajorFunction[IRP_MJ_PNP] = GpdDispatchPnp;
//DriverObject->MajorFunction[IRP_MJ_POWER] = GpdDispatchPower;
//DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl;
//DriverObject->DriverExtension->AddDevice = GpdAddDevice;

RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);

//创建设备
status = IoCreateDevice(DriverObject,
0,
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&fdo);

if (!NT_SUCCESS (status))
{
DbgPrint( "TWDM: IoCreateDevice() faild ! n" );
}
else
{
DbgPrint( "TWDM: IoCreateDevice() ok ! n" );
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

//创建符号连接
status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );
if (!NT_SUCCESS(status))
{
DbgPrint( "TWDM: IoCreateSymbolicLink() faild ! n" );
}
else
{
DbgPrint( "TWDM: IoCreateSymbolicLink() ok ! n" );
fSymbolicLink = TRUE;
}
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
}

if (!NT_SUCCESS(status))
{
if(fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}
return status;
}

NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp)
{
NTSTATUS status;
DbgPrint( "TWDM: IRP_MJ_CREATE for Twdm.sys ...... n" );
status = STATUS_SUCCESS;
return status;
} // DispatchCreate

NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp)
{ // DispatchClose
NTSTATUS status;
DbgPrint( "TWDM: IRP_MJ_CLOSE for Twdm.sys ...... n" );
status = STATUS_SUCCESS;
return status;
} // DispatchClose

VOID GpdUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING win32DeviceName;

DbgPrint( "TWDM: GpdUnload() for Twdm.sys ...... n" );

RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
if(fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}


其中驱动程序部分的一个文件,修改以下就可以了。

Mk.cmd

@echo off
echo Aouther : Qian
echo Date : 2001.9.20
echo Function : Start DDK Environment And Build Driver
call c:NTDDKbinsetenv.bat c:NTDDK checked //此处改为你的 2k ddk 的路径
rem call c:NTDDKbinsetenv.bat c:NTDDK free
echo on

d: //此处改为你的编写驱动程序的驱动器
cd workqianwdmtest1sys ////此处改为你的编写驱动程序的目录


build -b -w -nmake /a

whz_time 2002-04-30
  • 打赏
  • 举报
回复
转贴:

加载一个驱动程序,主要就是,在
SYSTEMCurrentControlSetServices 建一个键。
如:
SYSTEMCurrentControlSetServicesTwdm1
Type(1)
ErrorControl(0)
Start(3)

多数驱动程序都是通过设置 Start 的值为 0, 1, 2 。
在系统启动的过程中加载驱动程序。

在 win2k 下驱动程序的加载处理上述方式外,
还可以在应用程序里用 Service Api 实现,驱动程序的动态加载。
这时候的 Start 为 3 。

所用到的 Api 为:
OpenSCManager, CreateService, OpenService, StartService
ControlService, DeleteService, CloseServiceHandle

其中需要说明的是:
CreateService :他通过参数在注册表里自动创建驱动程序需要的键值。
DeleteService :他自动删除驱动程序在注册表里创的键值。

下面是一个,简单的例子:

应用程序:

#include "stdafx.h"
#include <windows.h>
#include <winsvc.h>
#include <conio.h>

void DelSvr( char * szSvrName ); //自动卸载驱动程序。

int main(int argc, char* argv[])
{
HANDLE hWdm;
printf("Hello World!n");

SC_HANDLE hServiceMgr, hServiceTwdm;
BOOL bRtn;
DWORD dwRtn, dwSize = 256;
char szDir[256];

if( argc > 1 ) //加任一个参数表示卸载驱动程序。
{
DelSvr( "Twdm1" );
return 0;
}

GetCurrentDirectory( dwSize, szDir );//取当前目录
strcat( szDir, "\Twdm.sys" ); //取驱动程序的全路径

LPCTSTR lpszBinaryPathName = TEXT(szDir);
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); //打开服务控制管理器

if( hServiceMgr == NULL )
{
printf( "OpenSCManager() Faild %d ! n", GetLastError() );
return 0;
}
else
{
printf( "OpenSCManager() ok ! n" );
}

hServiceTwdm = CreateService( hServiceMgr,
TEXT("Twdm1"), //SYSTEMCurrentControlSetServices 驱动程序的在注册表中的名字
TEXT("Twdm1"), // 注册表驱动程序的 DisplayName 值
SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序
SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值
SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值
lpszBinaryPathName, // 注册表驱动程序的 ImagePath 值
NULL,
NULL,
NULL,
NULL,
NULL);

if( hServiceTwdm == NULL )
{
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )
{
CloseServiceHandle( hServiceMgr );
printf( "CrateService() Faild %d ! n", dwRtn );
return 0;
}
else
{
printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! n" );
}

// 驱动程序已经加载,只需要打开
hServiceTwdm = OpenService( hServiceMgr, TEXT("Twdm1"), SERVICE_ALL_ACCESS );
if( hServiceTwdm == NULL )
{
dwRtn = GetLastError();
CloseServiceHandle( hServiceMgr );
printf( "OpenService() Faild %d ! n", dwRtn );
return 0;
}
else
{
printf( "OpenService() ok ! n" );
}
}
else
{
printf( "CrateService() ok ! n" );
}

// 启动驱动程序,调用驱动程序的 DriverEntry 函数
bRtn = StartService( hServiceTwdm, NULL, NULL );
if( !bRtn )
{
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
{
printf( "StartService() Faild %d ! n", dwRtn );
CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );
return 0;
}
else
{
if( dwRtn != ERROR_IO_PENDING )
{
printf( "StartService() Faild ERROR_IO_PENDING ! n");
}
else
{
printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! n");
}
}
}

//测试驱动程序
hWdm = CreateFile("\\.\Twdm1",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hWdm != INVALID_HANDLE_VALUE )
{
printf( "Open Driver Twdm ok ! n" );
}
else
{
printf( "Open Driver Twdm faild %d ! n", GetLastError() );
}
CloseHandle( hWdm );
CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );

//这时候你可以通过注册表,或其他查看符号连接的软件验证。
printf( "按任意键 卸载驱动程序 !n" );
getch();
//卸载驱动程序。
DelSvr( "Twdm1" );
return 0;
}

tianlinyi 2002-04-30
  • 打赏
  • 举报
回复
up
zgc_7622 2002-04-29
  • 打赏
  • 举报
回复
NDIS网络驱动程序的安装你可以参考DDK SAMPLE 的SNETCFG
Gargamel 2002-04-29
  • 打赏
  • 举报
回复
谢谢各位。大家能不能说得仔细一点?我这方面是新手,而且任务很急。
installshield 中是哪个例子有驱动安装?setupbuild又是怎么样操作或哪有例子???

再次感谢
zgc_7622 2002-04-29
  • 打赏
  • 举报
回复
NDIS网络驱动程序,我用拷贝驱动程序,写特定键值的方法,没有安装成功过,等以后有结果再告诉你。
winne_ll 2002-04-29
  • 打赏
  • 举报
回复
你可以用SetupBuilder这个软件。
tianlinyi 2002-04-29
  • 打赏
  • 举报
回复
用installshield做
zhuwenzheng 2002-04-29
  • 打赏
  • 举报
回复
Installshiled中有example

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧