Personal C Sharp                                                         By
HomeHow To StartExamples-DesktopExamples-WebPC# MethodsReference-DesktopReference-Web

EXAMPLES ON ACCESSING EXTERNAL OBJECTS AND PERFORMING SYSTEM OPERATIONS ====================================== Although the main purpose behind PC# was to find the simplest possible way which can allow a person with less programming experience to write his own programs using C# and the .NET, the techniques we have developed have proven to do even better jobs with advanced features like Object Serialization and Remote Method Invocation. OBJECT SERIALIZATION: ===================== Serialization is the process of converting the state of an object into a form that can be persisted or transported. As you have already seen in the demonstrative examples, when you use PC# methods you rarely need to use variables, and when you do, you can always use the variables which have been pre-defined by PC# and assigned to your programs. This makes things much easier for you. Unless you have declared your own variables which you like to serialize, Serialization and Deserialization of necessary variables, including the pre-defined ones which your programs use are totally done by PC# for you. You do not need to get involved in serialization. EXECUTING EXTERNAL PROGRAMS: ============================ Since serialization is no work, exiting your program to run something else then returning back to find everything exactly the same can easily be done. Immediately before you exit, PC# serializes all var's and save the resulting byte stream into file and immediately after your return, PC# deserializes all data and restores all vars. All it takes is a mechanism which executes the exit and return. Let us have an example to see how it works. ABOUT THE NEXT EXAMPLE: ======================= Networking Engineers use the "Ping" utility to check the connection with a host. The utility sends packets of information to the host and receives them back. The number of packets received and the time they took for the trips measure the connection quality. To use the ping utility, you need to supply it with the host's IP Address. If you don't know it, you need to run the "ipconfig" utility first which displays all TCP/IP configuration values. The next example shows how to do the two operations uninterruptedly with a continuous PC# program. ========================================================================================= EXAMPLE 1: Write a program which uses the "ipconfig" utility to get networking information, searches the data to obtain the WAN's IP Address then use the "ping" utility to check connection with that address. ========================================================================================= public class a:pcs { public override void init() { tia=toa="t"; // Use text screen for text output bli=0; // Start at block 0. base.init(); // Initialize pcs } public override void run() { if (blp==0) { // Startup block os="ipconfig /all";bli=1;xm("r");return; // run ipconfig then goto block 1 } if (blp==1) { // Re-entry with os="ipconfig" output text fns="crb12";tm(); // Display ipconfig output txs=os; // Assign text to searchable string (txs) js="IP Address";j=2;tm("s"); // Move pointer to end of second phrase // "IP Address". Then js=": ";ks="\n";tm("s"); // return string following ": " and ending // immediately before new line code in (os) os="ping "+os;bli=2;xm("r");return; // ** run "ping IPAddress" then goto blk 2 } if (blp==2) { // Re-entry with os="ping" output text fns="crb12";tm(); // Display ping utility's output string. } } } ========================================================================================= HOW TO COMPILE AND RUN THIS PROGRAM: ------------------------------------ To compile: pcp a [Enter] To run: xrun a [Enter] The "xrun" tool must be used to execute a program which requires exit and re-entry. ========================================================================================= TUTORIAL: ========= The program should be developed in two steps. In the first step you need to comment the line marked with "**" to prevent jumping to block 2. So you can see the output of the "ipconfig" utility and find how to obtain the IP address of the WAN. Then you uncomment the line and let the program continue until the text output of the "ping" utility shows on display. The "PC# Reference, Desktop" discusses how to search a string in details. Accessing utilities programmatically can be extremely valuable. You can write programs which can manage every property in your system. If you have a server you can do most of your system administration with programs. There are many utilities which allow you to create, modify or delete Active Directory objects like users, computers or services. You learn more about most of the utilities by entering the following at the command prompt: UtilityName /? then pushing [Enter] key. Here is a list of some of these utilities: ------------------------------------------ ARP Physical to IP address translation. AT Task scheduling CHKDSK Checks for disk errors COMPACT Compresses files CONVERT Converts FAT to NTFS DATE Displays date EXPAND Decompresses files FC Compares files FORMAT Formats disks FTP FTP Communication FTYPE File types IPCONFIG Displays TCP/IP Configuration values NBSTAT NetBios over TCP/IP NET ACCOUNTS Manages user accounts NET COMPUTER Adds/Removes computers from Domains NET CONFIG SERVER Server Configuration NET CONFIG WORKSTATION Workstation Configuration NET CONTINUE Resume paused service NET FILE Lists open files NET GROUP Manages Global Groups NET LOCALGROUP Manages local groups NET PAUSE Pauses a service NET PRINT Print jobs and queues NET SEND Sends messages NET SESSION Lists sessions on local and remote computers NET SHARE Manages shared printers and directories NET STATISTICS Displays Workstation and server statistics NET STOP Stops Network Services NET TIME Displays time and synchronizes time with remote computers NET USE Manages Remote Connections NET USER Manages User Accounts NET VIEW Displays available network resources NETSTAT Displays status of network connections NSLOOKUP Performs DNS resolutions NTBACKUP Backup of files PATH Displays or sets a search path for files PING Tests network connections RECOVER Recovers information from a defective disk ROUTE Manages Network Routing Table TIME Displays or sets system time TRACERT Displays the path between local computer and remote one =========================================================================================

========================================================================================= ACCESSING SCRIPTS: ================== If all those utilities are not enough for you, you can write your own script program to do the wildest operations like restarting or shutting off the system and execute the script file programmatically. Let us see how to do that. ========================================================================================= EXAMPLE 2: Write a program in "JScript" which restarts the system and show how to execute it with a C# program. ========================================================================================= The Script program: Save into a file named "restart.js". var oo = WScript.CreateObject("Shell.Application");// Create Shell object oo.ShutdownWindows(); // Launch Shutdown / Restart Dialog ========================================================================================= The C# program: Save into a file named "a.cs", compile it and run it with "xrun" public class a:pcs { public override void init() { bli=0; base.init(); } public override void run() { if (blp==0) { os="Are you sure you like to restart your computer?"; ks="yn";cm("d"); // Display msg with yes/no buttons if (os.Equals("y")) { // If user selects "yes" os="restart.js";bli=1;xm("r");return; // Run "restart.js" file } else sm("e"); // else exit } } } ========================================================================================= Use Notepad to write both programs. Name the script file "restart.js". Name the C# file "a.cs", Compile it with "pcp a" and run it with "xrun a". ========================================================================================= TUTORIAL: When we used method xm("r"), we supplied it with a block number and followed the statement with "return". This was just to keep the routine. After system restarts or shuts dowm, jumping to a new block or returning are meaningless. If you like to learn about other functions which you can do using the "Shell.Application" object check this MSDN link: IMPORTANT REMARK: ================= Some of the operations which you may like to do require Administrator privilege. You may be the administrator of your computer or network but this may not be enough. The command mode window which runs your program must also be privileged for administrator jobs. To open a privileged command mode window, click on [START][ALL PROGRAMS][ACCESSORIES]. Right click on [COMMAND PROMPT] and select "Run as Administrator". If you are using Windows 10 where security is tighter, you may need to give your ".exe" file administrator privilege also. This will be explained following Example 3. =========================================================================================

HANDLING SYSTEM PROCESSES ========================= We have another way to run an external program which does not require serialization or the use of the "xrun" tool. We can start a new system process and assign the external program to it. In this case both the main program and the external one will be running simultaneously. To start a new process which runs a file, assign the name of the file together with all following arguments to (os), then call sm("pn") You do not need to supply a requested block number in this case since it does not require moving to a new block. Here is a new version of Example 1 which uses this new method: ========================================================================================= Example 3: ========== public class a:pcs { public override void init() { tia=toa="t"; // Use text screen for text output bli=0; // Start at block 0. base.init(); // Initialize pcs } public override void run() { if (blp==0) { // Startup block os="ipconfig /all";sm("pn"); // Start a new process which runs "ipconfig" fns="crb12";tm(); // Display ipconfig output txs=os; // Assign text to searchable string (txs) js="IP Address";j=2;tm("s"); // Move pointer to end of second phrase // "IP Address". Then js=": ";ks="\n";tm("s"); // return string following ": " and ending // immediately before new line code in (os) os="ping "+os;sm("pn"); // Start a new process which runs "ping". fns="crb12";tm(); // Display ping utility's output string. } } } ========================================================================================= Accessing Batch Files and WScripts within your code: ==================================================== Accessing external scripts and utilities in PC# is unified. You assign to (os) the external file name followed with all arguments exactly as you do it at command mode and call method sm("pn") to run it as a seperate process. To return a value to PC#, simply display it on the console of that process. Your PC# program will receive everything displayed assigned to (os) The WScript which is suitable for this job is CScript which displays on the console. Let us see a simple example here on how this job is done. Proceed as follows: (1) Use Notepad to create file myscript.js which contains this line of text: WScript.Echo (WScript.Arguments(0), "is easy."); (2) Use Notepad to create file myscript.bat which contains this line of text: echo %1 is powerful. (3) Use Notepad to create the PC# file a.cs which contains the following code: public class a:pcs { public override void run() { cm("fe"); // Eliminate Form os="cscript myscript.js PC#";sm("pn");tm();// Run myscript.js with 1st par="PC#", dsply output os="myscript.bat PC#";sm("pn");tm(); // Run myscript.bat with 1st par="PC#", dsply outpt } } (4) Run the class with (pcpr a) You should get the following output: ---------------------------------------------------------- Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. PC# is easy. PC# is powerful. ----------------------------------------------------------- We are not going to say much about how to use WScript and Batch files here. We are going only to give a few comments: (1) The two script languages name their arguments differently. The first argument is called "WScript.Arguments(0)" in Wscript and "%1" in Batch files. (2) WScript adds several lines of text to our wanted text. It's output came in 5 lines. Two lines to identify the language followed with an empty line then our wanted line of text followed with one more empty line. (3) We could remove all unwanted lines by replacing the line of code: os="cscript myscript.js PC#";sm("pn");tm(); with: os="cscript myscript.js PC#";sm("pn"); // Run myscript.js with 1st par="PC#" oc='\n';om("s"); // Seperate lines into OS[] os=OS[3];tm(); // Display OS[3] only. Automating System Administration: ================================= System administration can be totally automated with a multi-tier menu which performs all necessary jobs throughout the day without ever exiting it. The menu can access internally windows utilities, CScripts and Batch files. If you are using Windows 10, Such menu needs to have administrator privilege before being pinned to taskbar. Here is how to do it (Let us assume that its name is "AdMenu.exe"): Run the menu, right click its icon on taskbar, right click the item "AdMenu.exe" and select "Properties". Click on [Advanced], check the item "Run as administrator" then click [OK][Apply][OK] Right click its icon on taskbar again and select "Pin to Taskbar". Merging PC# with all other languages: ===================================== If you have an old program written in any other language which you can run within the windows version which you currently have, you can access it in the same manner described above. This means that You assign to (os) the program name followed with all arguments exactly as you do it at command mode and call method sm("pn") All text which the program displays on the console will be received by PC# assigned to (os) after the program terminates. We mean by "terminates" exits to command mode. ========================================================================================= USING THE EVENT LOG =================== The event log contains valuable information which help in locating the source of problems whenever they take place. How to access the event log: ---------------------------- (1) Click on [start][Control Panel]. (2) Double click [Administrative tools] then [Event Viewer]. REMARK: If using Windows 10, click on [Start][All Apps][Windows Administrator Tools] [Event Viewer][Windows Logs] (3) To view the "Application" log, double click its name on the left panel. You should see the event log table. If you double click on any row, you should get detailed information about that particular entry. How to write to the event log: ------------------------------ When you handle errors by yourself (using error handling level zero) you always have the choice of either displaying error messages to the user or writing them to the event log. When you write messages to the event log you need to supply the following parameters to method sm("lw"): (1) Event Log Name: Most likely you will like to write error messages which result from a running application to the "Application" log. So you supply (js="Application") (2) Event Source: This should be your application name. It should be assigned to (ks) (3) Event Type: The type code is assigned to (oc) It can be one of the following: e=Error w=Warning i=Information s=Success Audit f=Failure Audit The default is (oc='i') (4) The Message: The message is assigned to (os) Let us have an example: Example 4: ========================================================================================= public class a:pcs { public override void init() { tia=toa="t"; // Use text screen for text output bli=0; // Start at block 0. base.init(); // Initialize pcs } public override void run() { if (blp==0) { // Startup block js="Application";ks="MyApplication"; // Use Application log, ks= Event Source oc='e';os="Error Message Logging Demo."; // Event type="Error", os=Message. sm("lw");sm("e"); // Write to event log then exit } } } ========================================================================================= Run this example with [pcpr a] then check the "Application Event Log". You should see the new entry at the top with current date and time. Double click at any column data of the new entry to see the message. ========================================================================================= ACCESSING SYSTEM REGISTRY ========================= The system registry is the place where most applications store their configuration data. Since most of the data stored there are of critical nature to the operating system, you must be careful when you access the registry. Personal C Sharp helps you in using the registry to store and retrieve any data you like for your application while making sure that your data will not interfere with other data in the registry. Before we get further, let us learn more about the registry. Registry structure: ------------------- The registry is structured like a tree. The tree starts with the root keys and extends all the way to leaf keys. This is similar to your computer storage system which starts with the drives and extends to folders and subfolders which end with single files. Registry root keys: ------------------- (1) HKEY_CURRENT_USER (2) HKEY_LOCAL_MACHINE (3) HKEY_CLASSES_ROOT (4) HKEY_USERS (5) HKEY_CURRENT_CONFIG How to protect the registry: ---------------------------- Since most of the data in the registry are of critical nature, we store all our data in one of two locations of the tree. We don't go beyond those two locations in order to minimize the possibility of errors. PC# can store your data at either of the two locations: HKEY_CURRENT_USER \ pcs \ Application Name HKEY_USERS \ pcs \ Application Name where "Application Name" is a name you supply representing the application you are working on. If you must store your data anywhere else, you should do that on your own. This way, if something went wrong and you could not delete keys programmatically, you can delete every key created by deleting the node which starts with "pcs" using the "regedit" utility or any other registry edit tool. Data Types which can be stored into the registry: ------------------------------------------------- (1) DWORD: Upto 4 bytes of hexadecimal data which stores data of type (int) (2) QWORD: Upto 8 bytes which stores data of type (long) (3) String: Stores data of type (string) (4) ExpandString: Same as "String" except that it can store environment variable symbols like %PATH% and expand them when they are retrieved. (5) MultiString: Stores a string array. (6) Binary: Stores a byte array. How to use method sm() to access the registry: ---------------------------------------------- (1) When you like to create new key-value pair or assign a new value to an existing key call sm("rw") with the following parameters: js=Application Name. ks=Key Name. ib=RootKey flag; ib=true means use HKey_USERS oc=Type code which can be: d=Dword q=Qword s=String e=ExpandString m=MultiString b=Binary Assign the Value(s) which are associated with the key to (o/ol/os/OS[]/OY[]) depending on the type. (2) When you like to read the value(s) associated with a key, call sm("rr") with: js=Application Name. ks=Key Name. ib=RootKey flag (def: HKEY_CURRENT_USER) (3) When you like to delete one key-value pair, call sm("rd") with: js=Application Name. ks=Key Name. ib=RootKey flag (def: HKEY_CURRENT_USER) (4) When you like to delete all keys associated with one application, call sm("rda") with: js=Application Name. ib=RootKey flag (def: HKEY_CURRENT_USER) ========================================================================================= Example 5: Let us assume that we have an application which contains user specific setup information of variety of types and we like to use the system registry to store them. The information include: a) The %PATH% environment variable. b) A number of type int. c) A number of type long. d) A binary array. e) A string array. To widen the demonstration, we are going to store %PATH% twice. Once as a "String" and once as an "ExpandString". ========================================================================================= public class a:pcs { public override void run() { cm("fe"); // Eliminate form since unnecessary ps="MyApplication"; // Application name. oc='s';js=ps;ks="Key1";os="%PATH%";sm("rw"); // Write %PATH% as String oc='e';js=ps;ks="Key2";os="%PATH%";sm("rw"); // Write %PATH% as ExpandString oc='d';js=ps;ks="Key3";o=255;sm("rw"); // Write int as DWORD oc='q';js=ps;ks="Key4";ol=1234567890;sm("rw"); // Write long as QWORD oc='b';js=ps;ks="Key5";OY=new byte[] {50,100,70};sm("rw"); // Write Binary array oc='m';js=ps;ks="Key6";OS=new string[] {"a","b","c"};sm("rw"); // Write String array sm("e"); // Exit } } ========================================================================================= After running this example with [pcpr a], do the following: (1) Click [start][run], type into the text field 'regedit' and click [OK]. (2) If you see a [+] beside "My Computer" click on it so the containing folders appear. (3) If you see a [+] beside "HKEY_CURRENT_USER" click on it to see its contents. (4) Double click on "pcs". (5) Double click on "MyApplication" Now you should see all the keys which you have created together with their stored values. =========================================================================================

Example 6: Now let us read back and display all the the information which we have saved into the registry. We also need to delete them all after reading them. ========================================================================================= public class a:pcs { public override void init() { toa="t"; // Use text screen for output bli=1; // Start at block 1. base.init(); // Initialize pcs } public override void run() { if (blp==1) { ps="MyApplication"; // Application name cls="r0";fns="trb14"; // Set color, font for title os=" READING DATA BACK FROM THE REGISTRY"; tm();os="";tm(); // Display title, skip a line //----------------------------- Retrieving String Data ------------------------------ cls="b0";fns="trb12";os="Reading String Data: ";tm(); // Display subtitle js=ps;ks="Key1";sm("rr");cls="S9";os="os = "+os;tm(); // Retrieve data & display //-------------------------- Retrieving ExpandString Data --------------------------- cls="b0";fns="trb12";os="Reading ExpandString Data: ";tm(); js=ps;ks="Key2";sm("rr");cls="S9";os="os = "+os;tm(); //----------------------------- Retrieving DWORD Data ------------------------------- cls="b0";fns="trb12";os="Reading DWORD Data: ";tm(); js=ps;ks="Key3";sm("rr");cls="S9";os="o = "+o;tm(); //----------------------------- Retrieving QWORD Data ------------------------------- cls="b0";fns="trb12";os="Reading QWORD Data: ";tm(); js=ps;ks="Key4";sm("rr");cls="S9";os="ol = "+ol;tm(); //--------------------------- Retrieving Byte Array Data ---------------------------- cls="b0";fns="trb12";os="Reading Byte Array Data: ";tm(); js=ps;ks="Key5";sm("rr");cls="S9";os="OY[] = { ";tm("d"); for (n=0;n< OY.Length;n++) {os=""+OY[n]+" ";tm("d");} os="}";tm("d");os="";tm(); //-------------------------- Retrieving String Array Data --------------------------- cls="b0";fns="trb12";os="Reading MultiString Data: ";tm(); js=ps;ks="Key6";sm("rr");cls="S9";os="OS[] = { ";tm("d"); for (n=0;n< OS.Length;n++) {os=""+OS[n]+" ";tm("d");} os="}";tm("d");os="";tm(); js=ps;sm("rda"); // Delete all created keys } } } ========================================================================================= After running this example, do the following: (1) Close the regedit window if still there. (2) Restart the regedit program as explained before. Notice that all keys have gone. The only item left is the folder "pcs" and the default value associated with it. You may keep it since it causes no problem. However if you like to delete it, right click on it and select [delete]. Close the regedit window then. =========================================================================================