Solved

ipconfig NT

Posted on 2000-05-15
15
518 Views
Last Modified: 2013-12-03
How can I get the MAC no, IP no and description/name of all network cards, that are installed in my local NT computer?
In other words: How can I do exactly what "ipconfig /all" does? (Please don't suggest to execute ipconfig as a child process).
I need that for NT4 and win2000.

Thank you!
0
Comment
Question by:drdt3
  • 4
  • 4
  • 3
  • +3
15 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 2810617
See http://support.microsoft.com/support/kb/articles/Q118/6/23.asp ("HOWTO: Get the MAC Address for an Ethernet Adapter")

and this 'ifconfig' port for Win32 (not by me ;-) :

/********************************************************************

 ifconfig v 0.1 for WinNT by AlCoHoLiC
 
      Unsupported and uncommented source code of small command line
      utility which allows you to change IP address and related params
      *WITHOUT* stupid rebooting of your NT box. This proggy wasn't fully
      tested, I'm pretty sure it has many many bugs. Use it at your own risk.
      I'm giving this code to PUBLIC DOMAIN. If you will made modification
      or find some nasty bug feel free to      contact me. Also if you'll find
      something useful in my code and/or       you'll use it in your program,
      an email would be nice.

      
      http:\\www.slon.sk
      mail: slon@slon.sk


*********************************************************************/

#include <windows.h>
#include <stdio.h>
#include <string.h>

#include <winsock.h>

void usage(void);
void display_adapter(char *adapter);
void display_params(char *adapter);
void print_error(DWORD err);
BOOL set_ip(int nIdx, DWORD dwIPaddr, DWORD dwNetmask, DWORD dwGateways[], int nGwCount, char *adapter);

#define      REGKEY_TCPIP_LINKAGE                  "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"
#define      REGKEY_BINDINGS                              "Bind"

#define      REGKEY_ADAPTER_TCPIP                  "SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters\\Tcpip"
#define      REGKEY_IP_ADDRESS                        "IPAddress"
#define      REGKEY_SUBNET_MASK                        "SubnetMask"
#define      REGKEY_DEFAULT_GATEWAY                  "DefaultGateway"

#define MAX_BINDINGS_BUFFER_SIZE            256                  // maximum buffer sizes
#define MAX_IPADDRESS_BUFFER_SIZE            256                  
#define MAX_NETMASK_BUFFER_SIZE                  256                  
#define MAX_DEFAULTGW_BUFFER_SIZE            256                  

#define      MAX_DUMMY_BUFFER_SIZE                  256                  // dummy buffer

#define      DEVICE_PREFIX_LENGTH                  8                  // lengt of \Device\ prefix

#define IP_ADDRESS_STRING_LENGTH            17                  // 16+1 just to be safe

typedef int (CALLBACK* DHCPPROC)(int, unsigned short *, int, int, DWORD, DWORD, int);


int main(int argc, char **argv){

      int idx, param_start;
      BOOL bResult = FALSE;
      DWORD dwIPaddr, dwNetmask;
      DWORD dwGateways[10];
      int nGwCount=0;

      printf("\nifconfig v0.1 for WinNT 4.0 by AlCoHoLiC\n\n");
      

      switch (argc){

            case 1:      // no args given just display stats      
                        display_adapter(NULL);
                        break;

            case 2:      
                        if (!stricmp(argv[1],"-h") || !strcmp(argv[1],"-?") || !strcmp(argv[1],"?") || !stricmp(argv[1],"/h") || !stricmp(argv[1],"/?"))
                              usage();      // luser needs help
                        else
                              display_adapter(argv[1]);            // let's assume argv[1] is adapter name
                        break;

            default:
                        

                  if (!strnicmp(argv[2],"-i:", 3) || !strcmp(argv[1],"/i:")){

                              idx = atoi((const char *)&argv[2][3]);
                              param_start = 3;


                  } else {

                              idx = 0;
                              param_start = 2;
                  }

                  if (argc < (param_start + 2) || argc > 10 + param_start){
                        usage();
                        return 1;
                  
                  }

                  dwIPaddr = inet_addr(argv[param_start++]);
                  dwNetmask = inet_addr(argv[param_start++]);

                  if (dwIPaddr ==INADDR_NONE || dwNetmask == INADDR_NONE){
                        printf("Error parsing IP Address/Subnet Mask\n");
                        return 1;
                  }

                  for (int i = param_start; i < argc; ++i){

                        dwGateways[i-param_start] = inet_addr(argv[i]);
                        ++nGwCount;
      
                  }


                  bResult = !set_ip(idx, dwIPaddr, dwNetmask, dwGateways, nGwCount, argv[1]);
                  break;
      

      }

      return (int)bResult;
}


void usage(void){


      printf("\nifconfig can be used to display or set up IP address, subnet mask and/or default");
      printf("\ngateway for specified interface.\n");
      printf("\nUsage: ifconfig");
      printf("\n       ifconfig adapter");
      printf("\n       ifconfig adapter [-i:idx] ip_address netmask [default_gw1] [default_gw2] ...");
      printf("\n       ifconfig ? | -h | -?\n");
      printf("\nIf issued without arguments, ifconfig just displays all network adapters and associated");
      printf("\nIP addresses, netmasks and default gateways. If the single adapter argument is given,");
      printf("\nit displays parameters of the specified adapter only. Otherwise, it assumes that things");
      printf("\nhave to be set up.\n");
      printf("\n*NOTE*: idx is ZERO based index, to change first bound address idx = 0\n");

}


void display_adapter(char *adapter){

      HKEY      hkLinkage;
      BYTE      bindings[MAX_BINDINGS_BUFFER_SIZE];
      DWORD      dwType;
      DWORD      dwLength;
      char *      lpPtr;


      if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_TCPIP_LINKAGE, 0L, KEY_READ, &hkLinkage) != ERROR_SUCCESS){
            printf("FATAL ERROR: Cannot open registry key (%s)\n", REGKEY_TCPIP_LINKAGE);
            return;
      }

      dwLength = MAX_BINDINGS_BUFFER_SIZE;

      if (RegQueryValueEx(hkLinkage, REGKEY_BINDINGS, NULL, &dwType, bindings, &dwLength) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error reading registry key (%s)\n", REGKEY_BINDINGS);
            goto exit;
      }

      lpPtr = (char *)&bindings;

      if (adapter == NULL){                  // enumerate all adapters and print params
      
            while (*lpPtr != '\0'){
      
                  printf("Adapter %s: \n\n", lpPtr+DEVICE_PREFIX_LENGTH);
                  display_params(lpPtr+DEVICE_PREFIX_LENGTH);
                  lpPtr+=(strlen(lpPtr)+1);
                  printf("\n\n");
                  
            }

      } else {                                    // we have to find requested adaptername
      
            while (*lpPtr != '\0'){

                  if (!stricmp(lpPtr+DEVICE_PREFIX_LENGTH, adapter)){
                        printf("Adapter %s: \n\n", lpPtr+DEVICE_PREFIX_LENGTH);
                        display_params(lpPtr+DEVICE_PREFIX_LENGTH);
                        printf("\n\n");
                        goto exit;                                                            // done
                  }

                  lpPtr+=(strlen(lpPtr)+1);
                  
            }      // not found, notify user

            printf("FATAL ERROR: Adapter doesn't exist. (%s)\n", adapter);

      }


exit:

      RegCloseKey(hkLinkage);

}


void display_params(char *adapter){

      HKEY      hkAdapter;
      DWORD      dwType;
      DWORD      dwLength;
      BYTE      ip_address[MAX_IPADDRESS_BUFFER_SIZE];
      BYTE      subnet_mask[MAX_NETMASK_BUFFER_SIZE];
      BYTE      default_gw[MAX_DEFAULTGW_BUFFER_SIZE];
      char      dummy[MAX_DUMMY_BUFFER_SIZE];
      char      *lpIPAddress, *lpSubnetMask, *lpDefaultGw;


      // sanity check
      if (strlen(adapter) + strlen(REGKEY_ADAPTER_TCPIP) >= MAX_DUMMY_BUFFER_SIZE){
            printf("FATAL ERROR: Adapter name too long!\n");
            return;
      }
      
      sprintf(dummy,REGKEY_ADAPTER_TCPIP, adapter);                  // create keyname from template & adaptername

      if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, dummy, 0L, KEY_READ, &hkAdapter) != ERROR_SUCCESS){
            printf("FATAL ERROR: Cannot open registry key (%s)\n", REGKEY_ADAPTER_TCPIP);
            return;
      }

      dwLength = MAX_IPADDRESS_BUFFER_SIZE;

      if (RegQueryValueEx(hkAdapter, REGKEY_IP_ADDRESS, NULL, &dwType, ip_address, &dwLength) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error reading registry key (%s)\n", REGKEY_IP_ADDRESS);
            goto exit;
      }

      dwLength = MAX_NETMASK_BUFFER_SIZE;

      if (RegQueryValueEx(hkAdapter, REGKEY_SUBNET_MASK, NULL, &dwType, subnet_mask, &dwLength) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error reading registry key (%s)\n", REGKEY_SUBNET_MASK);
            goto exit;
      }

      dwLength = MAX_DEFAULTGW_BUFFER_SIZE;

      if (RegQueryValueEx(hkAdapter, REGKEY_DEFAULT_GATEWAY, NULL, &dwType, default_gw, &dwLength) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error reading registry key (%s)\n", REGKEY_DEFAULT_GATEWAY);
            goto exit;
      }

      lpIPAddress = (char *)&ip_address;
      lpSubnetMask = (char *)&subnet_mask;

      while (*lpIPAddress != '\0'){

            printf("\tIP Address . . . . . : %s\n",lpIPAddress);
            printf("\tSubnet Mask. . . . . : %s\n\n",lpSubnetMask);

            lpIPAddress+=(strlen(lpIPAddress)+1);
            lpSubnetMask+=(strlen(lpSubnetMask)+1);

      }

      lpDefaultGw = (char *)&default_gw;

      while (*lpDefaultGw != '\0'){
            printf("\tDefault Gateway. . . : %s\n", lpDefaultGw);
            lpDefaultGw+=(strlen(lpDefaultGw)+1);
      }


exit:

      RegCloseKey(hkAdapter);

}


void print_error(DWORD err){

      LPVOID lpMsgBuf;
      
      FormatMessage(      FORMAT_MESSAGE_ALLOCATE_BUFFER |
                              FORMAT_MESSAGE_FROM_SYSTEM |
                              FORMAT_MESSAGE_IGNORE_INSERTS,
                              NULL,
                              err,
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                              (LPTSTR) &lpMsgBuf,    
                              0,    
                              NULL );      

      printf((const char *)lpMsgBuf);
      
      LocalFree( lpMsgBuf );

}


BOOL set_ip(int nIdx, DWORD dwIPaddr, DWORD dwNetmask, DWORD dwGateways[], int nGwCount, char *adapter){

      HKEY            hkAdapter = 0;
      WCHAR            wsAdapter[80];  
      DWORD            dwLength;
      HINSTANCE      hDhcpDll;                    
      DHCPPROC            pNotifyConfigChangeProc;                    
      DWORD            dwType;
      int                  i;

      BYTE            ip_address[MAX_IPADDRESS_BUFFER_SIZE];
      BYTE            subnet_mask[MAX_NETMASK_BUFFER_SIZE];
      BYTE            default_gw_out[MAX_DEFAULTGW_BUFFER_SIZE];
      BYTE            ip_address_out[MAX_IPADDRESS_BUFFER_SIZE];
      BYTE            subnet_mask_out[MAX_NETMASK_BUFFER_SIZE];

      int                  nIPaddrLen, nNetmaskLen, nDefaultGwLen;

      char            *lpIPAddress, *lpIPAddressOut, *lpSubnetMask, *lpSubnetMaskOut, *lpDefaultGwOut;

      char            dummy[MAX_DUMMY_BUFFER_SIZE];

      // sanity check
      if (strlen(adapter) + strlen(REGKEY_ADAPTER_TCPIP) >= MAX_DUMMY_BUFFER_SIZE){
            printf("FATAL ERROR: Adapter name too long!\n");
            return FALSE;
      }

      sprintf(dummy,REGKEY_ADAPTER_TCPIP, adapter);                  // create keyname from template & adaptername

      if (MultiByteToWideChar(CP_ACP, 0, adapter, -1, wsAdapter,80) == 0){
            printf("FATAL ERROR: Cannot convert adapter name\n");
            return FALSE;
      }

      if ((hDhcpDll=LoadLibrary("dhcpcsvc"))==NULL){                                    // load DHCP client service library
            printf("FATAL ERROR: Cannot load DHCPCSVC.DLL\n");            // and get our function address
            return FALSE;
      }
      
      if ((pNotifyConfigChangeProc=(DHCPPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange"))==NULL){
            printf("FATAL ERROR: Cannot find function DhcpNotifyConfigChange in DHCPCSVC.DLL\n");
            goto err;
      }
 
      if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, dummy, 0L, KEY_ALL_ACCESS, &hkAdapter) != ERROR_SUCCESS){
            printf("FATAL ERROR: Cannot write to registry key (%s)\n", REGKEY_ADAPTER_TCPIP);
            goto err;
      }
      
      dwLength = MAX_IPADDRESS_BUFFER_SIZE;

      if (RegQueryValueEx(hkAdapter, REGKEY_IP_ADDRESS, NULL, &dwType, ip_address, &dwLength) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error reading registry key (%s)\n", REGKEY_IP_ADDRESS);
            goto err;
      }

      dwLength = MAX_NETMASK_BUFFER_SIZE;

      if (RegQueryValueEx(hkAdapter, REGKEY_SUBNET_MASK, NULL, &dwType, subnet_mask, &dwLength) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error reading registry key (%s)\n", REGKEY_SUBNET_MASK);
            goto err;
      }

      lpDefaultGwOut = (char *)&default_gw_out;
      memset(&default_gw_out, '\0', MAX_DEFAULTGW_BUFFER_SIZE);            // zero destination buffers
      nDefaultGwLen=0;

      if (nGwCount){

            for (i=0;i<nGwCount;++i){
                  
                  sprintf(dummy, "%d.%d.%d.%d", LOBYTE(LOWORD(dwGateways[i])), HIBYTE(LOWORD(dwGateways[i])), LOBYTE(HIWORD(dwGateways[i])), HIBYTE(HIWORD(dwGateways[i])));
                  strcpy(lpDefaultGwOut, dummy);
                  lpDefaultGwOut+=(strlen(dummy)+1);
                  nDefaultGwLen += (strlen(dummy)+1);
            
            }
      
            ++nDefaultGwLen;
      }

      lpIPAddress = (char *)&ip_address;
      lpSubnetMask = (char *)&subnet_mask;
      lpIPAddressOut = (char *)&ip_address_out;
      lpSubnetMaskOut = (char *)&subnet_mask_out;

      memset(&ip_address_out, '\0', MAX_IPADDRESS_BUFFER_SIZE);            // zero destination buffers
      memset(&subnet_mask_out, '\0', MAX_NETMASK_BUFFER_SIZE);

      i = nIPaddrLen = nNetmaskLen = 0;

      while (*lpIPAddress != '\0'){

            if (i == nIdx){            // desired address & netmask, replace

                  sprintf(dummy, "%d.%d.%d.%d", LOBYTE(LOWORD(dwIPaddr)), HIBYTE(LOWORD(dwIPaddr)), LOBYTE(HIWORD(dwIPaddr)), HIBYTE(HIWORD(dwIPaddr)));
                  strcpy(lpIPAddressOut, dummy);
                  lpIPAddressOut+=(strlen(dummy)+1);
                  nIPaddrLen += (strlen(dummy)+1);

                  sprintf(dummy, "%d.%d.%d.%d", LOBYTE(LOWORD(dwNetmask)), HIBYTE(LOWORD(dwNetmask)), LOBYTE(HIWORD(dwNetmask)), HIBYTE(HIWORD(dwNetmask)));
                  strcpy(lpSubnetMaskOut, dummy);
                  lpIPAddressOut+=(strlen(dummy)+1);
                  nNetmaskLen +=(strlen(dummy)+1);

            } else {                  // just copy

                  strcpy(lpIPAddressOut, lpIPAddress);
                  strcpy(lpSubnetMaskOut, lpSubnetMask);

                  lpIPAddressOut+=(strlen(lpIPAddress)+1);
                  lpSubnetMaskOut+=(strlen(lpSubnetMask)+1);

                  nIPaddrLen +=(strlen(lpIPAddress)+1);
                  nNetmaskLen +=(strlen(lpSubnetMask)+1);
            }

            lpIPAddress+=(strlen(lpIPAddress)+1);
            lpSubnetMask+=(strlen(lpSubnetMask)+1);

            ++i;
      }

      ++nNetmaskLen;
      ++nIPaddrLen;

      if (i < nIdx){
            printf("FATAL ERROR: No such address\n");
            goto err;
      }


      if (RegSetValueEx (hkAdapter, REGKEY_IP_ADDRESS, 0L, REG_MULTI_SZ, ip_address_out,nIPaddrLen) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error writing registry key (%s)\n", REGKEY_IP_ADDRESS);
            goto err;
      }

      if (RegSetValueEx (hkAdapter, REGKEY_SUBNET_MASK, 0L, REG_MULTI_SZ, subnet_mask_out,nNetmaskLen) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error writing registry key (%s)\n", REGKEY_SUBNET_MASK);
            goto err;
      }

      if (RegSetValueEx (hkAdapter, REGKEY_DEFAULT_GATEWAY, 0L, REG_MULTI_SZ, default_gw_out,nDefaultGwLen) != ERROR_SUCCESS){
            printf("FATAL ERROR: Error writing registry key (%s)\n", REGKEY_DEFAULT_GATEWAY);
            goto err;
      }



      RegCloseKey(hkAdapter);


      __try {

            if ((pNotifyConfigChangeProc)(0, wsAdapter, 1, nIdx, dwIPaddr, dwNetmask, 0) != ERROR_SUCCESS){

                  printf("FATAL ERROR: Error setting IP address\n");
                  return FALSE;

            }
      
      } __except(1) {
      
                  printf("FATAL ERROR: DhcpNotifyConfigChange triggered an exception\n");
      
      }
      
      FreeLibrary(hDhcpDll);
 
      return TRUE;

      

err:
      if (hkAdapter)
            RegCloseKey(hkAdapter);

      FreeLibrary(hDhcpDll);
 
      return FALSE;
}


0
 
LVL 23

Accepted Solution

by:
chensu earned 1000 total points
ID: 2811199
In the search for the self or how to find out your IP address and other stuff in Win95 and WinNT
http://www.caip.rutgers.edu/~arni/ws2/stas.htm

ifconfig for WinNT 4.0
http://www.slon.sk/slon/projects.htm

For Windows 2000, you may use the Internet Protocol Helper.

http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/rras/iphpport_7vz9.htm
0
 
LVL 86

Expert Comment

by:jkr
ID: 2811285
>>ifconfig for WinNT 4.0
>>http://www.slon.sk/slon/projects.htm

Well, that's the source of the code I posted - thanx chensu for posting this link, I forgot where I found it...

0
 
LVL 5

Expert Comment

by:proskig
ID: 2811335
The code above does not work if address was assigned with DHCP
0
 
LVL 5

Expert Comment

by:proskig
ID: 2811337
But in general it is correct ;-)
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 2812248
drdt3,

I have spent a lot of time exploring the ipconfig/winipcfg for Win95-98-2000-NT.

Now I have the exact code of the undocumented calls which ipconfig uses, both for 95-98 and NT4.0.

It's easy to get all information you want on Win2000/98, using the GetAdaptersInfo(). I should note that 98 has a memory leak, so it is unacceptable to use GetAdaptersInfo for frequent calls on Win98.

I have written the special functions which emulates GetAdaptersInfo and GetNetworkParams equally fine on 95-98-NT-2000. I should note that those functions retrive exactly the same information and use exactly the same way as the original ipconfigs do. The  code takes ~1600 lines of C++.

The info about undocumented 95/98 calls you may find on my page http://skyscraper.fortunecity.com/gigo/311 -> Undoc. windows -> IP config.
I have not placed the info about NT there.

I'll give you the source code of the functions mentioned above for 2000 points+grade A.

Two words about the links above.

http://www.caip.rutgers.edu/~arni/ws2/stas.htm
^^^ The authors just don't know what are they talking about. They say: <<There is one thing common to IPCONFIG, NETSTAT, ROUTE and ARP utilities. All of them use a DLL called INETMIB1.DLL>>. It's absolutely WRONG, at least regarding to IPCONFIG. It's easy to check.

http://www.slon.sk/slon/projects.htm
^^^ Probably, in _some_ circumstances, this code will work. But original NT's ipconfig uses a lot of undocumented calls, like DeviceIoControl, NtDeviceIoControlFile etc, and works in ALL cases.
 
Again, I offer the portable on all Windows platforms, _original_, safe code.


0
 
LVL 15

Expert Comment

by:NickRepin
ID: 2812269
BTW, the Win95 and NT use the same code for some functions.
For example, getNICinfo() in the nipcfg98.cpp (see my page) is almost the same as NT's ipconfig uses.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 86

Expert Comment

by:jkr
ID: 2812492
>> undocumented calls, like DeviceIoControl

Huh! So I'm using undocumented functions ;-)
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 2812693
>>> undocumented calls, like DeviceIoControl
>>Huh! So I'm using undocumented functions ;-)

Well, as to DeviceIoControl, let's say 'not fully documented'. There are a lot of UNDOCUMENTED control codes which can be used with DeviceIoControl.

-------

drdt3,

I forgot to say - in my comments above I mean IPCONFIG.EXE /ALL.

0
 
LVL 10

Expert Comment

by:Lischke
ID: 2816329
Wow, although the code you have to offer, Nick, is surely very useful, but asking for 2000 points is quite overconfident in my opinion. Does this conform to the rules and spirit of Experts-Exchange?

Ciao, Mike
0
 
LVL 5

Expert Comment

by:proskig
ID: 2816405
I have got another proposal, for whom who does not have 2000 spare points but knows any programming language. Just run ipconfig /all, redirect output to a file and parse this file. But I am not sure whether it works for Win 95 and 98 :-(
0
 

Author Comment

by:drdt3
ID: 2816559
We use the IPHelper-functions. They are usable in NT4 SP5 too!

Thanks for the tip.

0
 
LVL 5

Expert Comment

by:proskig
ID: 2816718
What are IPHelper functions?
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 2816962
It was successfully solved without 2000 points it seems.
In spite of the SP6 I have, it still doesn't support GetAdaptersInfo.
0
 

Author Comment

by:drdt3
ID: 2817260
GetAdaptersInfo doesn't work under NT4, but GetIpAddrTable and GetIfTable do, that was good enough for us.

proskig, look at chensu's answer. There's a link that explains the IPHelper functions.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now