Archive for the ‘windows’ Category

Making Database Connections to Remote SQL Server 2008 using Oracle SQL Developer

Making Database Connections

Connect to Oracle and third-party databases from Oracle SQL Developer.

Oracle SQL Developer enables developers and DBAs to browse, create, and update data in a database. Before you can perform those actions, however, you must create at least one database connection —an Oracle SQL Developer object containing the information needed to connect to a specific database as a specific user.

This column explains how to make connections from Oracle SQL Developer to an Oracle Database and third-party databases. It also discusses authorization options for Oracle Database connections and explains the role of JDBC drivers in the connection process.

All the examples in this column require Oracle SQL Developer to be running on your local machine. For some examples, you need access to a running local or remote Oracle Database instance with the sample HR schema (available in the default database installation). Other examples require access to an Oracle Internet Directory server or a third-party database.

Basic Connections

You can connect to a local or remote Oracle Database instance by using the Basic connection type. Basic connections do not require any other Oracle software to be installed on your machine—you don’t need an Oracle home.

Right-click the Connections node in Oracle SQL Developer’s Connections Navigator, and click New Connection to open the New / Select Database Connection dialog box. All of this column’s connection examples start from this dialog box.

To create a basic connection for the HR schema, follow these steps:

1. Enter HR_ORCL for Connection Name . The connection name is an arbitrary alias; conventionally, it’s a combined username and database name.

2. Enter hr for Username , and enter the hr password in the Password field. (If you check the Save Password box, the password will be stored as an encrypted file on your local machine.)

3. Select Basic from the Connection Type list.

4. Provide information for the following settings:

  • Role: This is the set of privileges to be associated with the connection. Accept default for this connection.
  • OS Authentication: Leave this unchecked for this connection.
  • Proxy Connection: Leave this unchecked for this connection.
  • Hostname: This is the host system for the Oracle Database instance. Enter an IP address, a machine name, or localhost (when connecting to a database on the same machine as Oracle SQL Developer). The default is localhost .
  • Port: This is the listener port for the database. The default port for Oracle Database is 1521.
  • SID: This is the system identifier, such as orcl (the default for Oracle Database 10g and Oracle Database 11g) or xe (the default for Oracle Database 10g Express Edition).
  • Service name: This is the network service name of the database. Select either SID or Service name.

5. Click Test to validate the new connection. Figure 1 shows the dialog box after the connection has validated successfully.

6. If your test reports “Status: Success,” click Connect . Oracle SQL Developer will save the new connection, close the dialog box, and connect to the database. (If you click Save instead of Connect , you will be able to create more new connections in the dialog box before connecting.)

Now HR_ORCL appears in Connections Navigator, and you can expand it to browse the database.

TNS Connections

The TNS connection type is an appropriate option in any of the following circumstances:

You have an Oracle client installed on your machine. You have access to many Oracle Database instances. You do not know the machine details of the system hosting the Oracle Database instance you want to connect to.
A TNS connection uses an alias entry from a tnsnames.ora file. Oracle SQL Developer uses only one tnsnames.ora file. You may have more than one on your local machine or want to use the tnsnames.ora file on a remote machine, so note that Oracle SQL Developer looks sequentially for the tnsnames.ora file in the following locations:

1. $HOME/.tnsnames.ora
2. $TNS_ADMIN/tnsnames.ora
3. /etc/tnsnames.ora (non-Windows systems)
4. $ORACLE_HOME/network/admin/tnsnames.ora
5. Registry key

On Windows systems, if a tnsnames .ora file exists but Oracle SQL Developer isn’t using it, create a TNS_ADMIN environment variable via Control Panel -> System -> Advanced -> Environment Variables , specifying the file’s location as the variable’s value.

Follow these steps to create a TNS connection in Oracle SQL Developer:

1. In the New / Select Database Connection dialog box, enter the same connection name, username, and password you used for the basic connection.

2. Select TNS from the Connection Type list. The GUI changes slightly to provide a list of all network alias entries available to you. Select an alias.

3. Click Test and Connect as before.

LDAP Connections

Oracle Internet Directory is a directory service that enables you to store and manage network service names centrally. With it, user identity information can be stored in a directory instead of in multiple databases. Oracle Internet Directory is an implementation of the LDAP directory service and a component of Oracle Identity Management. For information on how to install, set up, and configure Oracle Internet Directory, see the Oracle Internet Directory Administrator’s Guide.

To look up database services in Oracle Internet Directory and create an LDAP connection in Oracle SQL Developer, follow these steps:

1. In the New / Select Database Connection dialog box, enter a new connection name, username, and password for the database user.

2. Select LDAP from the Connection Type list.

3. Select a server from the LDAP Server list, which is populated with entries from an ldap.ora file (similar to the tnsnames.ora file). Alternatively, you can enter LDAP server details directly.

4. Fill in the LDAP Admin User and LDAP Admin Password fields.

5. Click Load to populate the DB Service list with all the database service entries from Oracle Internet Directory.

6. Select a service from the DB Service list, as shown in Figure 2.

7. Click Test and Connect as before.

Other Authentication Options

Alternatives to database authentication and LDAP authentication include operating system (OS) and proxy authentication. You can create connections in Oracle SQL Developer for users who authenticate with these mechanisms. OS authentication. With OS authentication, Oracle Database uses a database user’s OS login credentials to authenticate that user. The user doesn’t provide a username or password to access the database, and Oracle Database doesn’t store and manage the account password. Local OS authentication can be used when the client and the database server are on the same machine. Remote OS authentication is possible but is not considered secure.

To configure local OS authentication for a new user, first find the value of the OS_AUTHENT_PREFIX database initialization parameter in your system’s init.ora file. When you create this new user in the database, you must add this parameter value as a prefix to the OS username. The default value is OPS$, for backward compatibility with earlier database releases. (If the value is “”, the OS username and the database username are the same, so you don’t need to add a prefix to create the Oracle usernames.)

Establish a basic connection with the HR schema as the SYSTEM user. Execute the following from the SQL worksheet, using your database’s OS_AUTHENT_PREFIX prefix and substituting your own OS username for “sue”:

CREATE USER ops$sue IDENTIFIED EXTERNALLY;
GRANT Connect, resource to sue;

Now create a basic connection for this user from the New / Select Database Connection dialog box. Enter a connection name; select Basic for Connection Type ; fill in the Hostname and Port fields; select OS Authentication ; and provide a SID or Service name . Click Test and Connect as before.

Proxy authentication. Proxy authentication means that one JDBC connection acts as a proxy for other JDBC connections. Before you can create a connection that uses proxy authentication, you need a proxy user. In the following example, you create a new user named HR_PROXY_USER and connect that user through the existing HR user.

To create the new proxy user (HR_PROXY_USER) and grant the correct proxy authentication privileges, execute the following in the SQL worksheet:

CREATE USER HR_proxy_user IDENTIFIED BY <
                               password>;
ALTER USER HR_proxy_user GRANT CONNECT THROUGH HR AUTHENTICATED USING PASSWORD;

You also need to grant any other privileges required by the new user, such as CREATE SESSION.

Once your proxy user exists, you can create a new proxy connection for HR in Oracle SQL Developer. Select Proxy Connection in the New / Select Database Connection dialog box, and complete the details in the Oracle Proxy Connection dialog box, as shown in Figure 3.

Connecting to Third-Party Databases

Oracle SQL Developer supports browsing and reviewing data and objects in Microsoft Access, MySQL, Microsoft SQL Server, and Sybase. It also offers a SQL worksheet for ANSI SQL commands to update or create objects for these databases. Users who want to migrate from third-party databases to Oracle Database can use the Oracle SQL Developer Migration Workbench. For any of these situations, you need to create a connection to your third-party database.

Installing third-party drivers. The correct third-party driver must be installed before you can create the connection. You can install third-party drivers either manually or by using Check for Updates ( Help->Check for Updates ). For manual installation, you can download supported drivers from the following locations:

  • MySQL JDBC driver, version 5.08: dev.mysql.com/downloads/connector/j/5.0.html.
  • jTDS driver, version 1.2 (required by Microsoft SQL Server and Sybase): source forge.net/project/showfiles.php?group_id=33291. (See jtds.sourceforge.net for information about this driver.)

Microsoft Access does not require an additional driver, because it uses a JDBC/ODBC bridge.

After downloading the driver you need, expand the driver binary Java Archive (JAR) file, which is typically inside the downloaded archive file:

  • The mysql-connector-java-5.0.8.tar.gz (or .zip) download for MySQL includes mysql-connector-java-5.0.8-bin.jar.
  • The jtds-1.2-dist.zip file for Microsoft SQL Server and Sybase includes jtds-1.2.jar.

Select Tools -> Preferences -> Database -> Third Party JDBC Drivers . Click Add Entry , and add your specific JAR file. Now you can create a connection for your third-party database.

Creating a Microsoft Access connection. To create a connection for Microsoft Access, follow these steps in the New / Select Database Connection dialog box:

1. Enter a connection name.
2. Click the Access tab.
3. Click Browse to locate the .mdb file you want to work with.
4. Click Connect.

You can now expand and browse the new Microsoft Access connection in the Connections Navigator.

Creating a Microsoft SQL Server, Sybase, or MySQL connection. To create a connection to a Microsoft SQL Server, Sybase, or MySQL database in the New / Select Database Connection dialog box, follow these steps:

1. Enter a connection name, username, and password.
2. Click the SQL Server, Sybase , or MySQL tab. Figure 4 shows the SQL Server tab.

figure 1
Figure 1: Basic database connection type
figure 2
Figure 2: LDAP connection with a list of database services
figure 3
Figure 3: Creating a proxy connection
figure 43
Figure 4: Connecting to Microsoft SQL Server

3. Choose one of the password authentication options (each of these connections offers you multiple choices).
4. Fill in the Hostname and Port fields. The default port is 1433 for Microsoft SQL Server, 5000 for Sybase, and 3306 for MySQL.
5. Click Choose database to populate the database list, and select the appropriate database from the list.
6. Click Test and Connect as before.
You can now browse your Microsoft SQL Server, Sybase, or MySQL database in the Connections Navigator.

Conclusion

Oracle SQL Developer provides an array of alternatives for connecting to Oracle and third-party databases. Support for both Oracle JDBC Type IV (thin) and Type II (thick) drivers lets you access Oracle Databases via basic, TNS, or LDAP connection types. You can make connections for Oracle Database users who authenticate via database, OS, or proxy authentication. Connecting to a third-party database from Oracle SQL Developer lets you work in that database and gives you a starting point for migrating to Oracle Database.

Advertisements

Using Oracle SQLDeveloper to access SQLServer

Using Oracle SQLDeveloper to access SQLServer

It is a pretty cool feature to use Oracle’s SQLDeveper 1.1 to access SQLServer.
The steps are:

  • Download jTDS (open-source SQLServer JDBC driver) from here. Unzip and extract the jtds-1.2.jar or whatever the latest version.
  • Start Oracle’s SQLDeveloper, Tools->Preferences->Database->Third Party JDBC Drivers. Click “Add Entry” and point to the jtds-1.2.jar
  • Create a new connection, choose SQLServer tab, type in hostname, port, username and password. It appears that the initial connection name has to be the same as the database and you can click the “Retrieve database” button. Once you found the database, you can rename the connection.

Try it out.
Of course, certain things don’t work. Like explain plan and auto trace.

Per comments below, please make sure jtds 1.2 is used. Apparently, 1.3 does not work.

NTLDR is Missing Error Resolution

NTLDR Error Message

There are few different ways that the “NTLDR is missing” error may present itself, with the first listing being the most common:

  • “NTLDR is missing
    Press any key to restart”
  • “NTLDR is missing
    Press Ctrl Alt Del to restart”
  • “Boot: Couldn’t find NTLDR
    Please insert another disk”

The “NTLDR is missing” error displays very shortly after the computer is first started, immediately after the Power On Self Test (POST)is complete. Windows XP has only initially begun to load when the NTLDR error message appears.

Causes of NTLDR Errors

There are a number of possible causes for NTLDR errors, including the most common “NTLDR is missing” error message.

The most common reason for this error is when your PC is trying to boot from a hard drive or flash drive that is not properly configured to be booted from; in other words, it’s trying to boot from a non-bootable source. This also would apply to media on an optical drive or floppy drive that you’re trying to boot from.

Other possible causes include corrupt and misconfigured files, hard drive and operating system upgrade issues, corrupt hard drive sectors, an outdated BIOS, and damaged or loose IDE cables.

Fixes for NTLDR Errors

  1. Restart the PC. The NTLDR error could be a fluke.
  2. Check your floppy and optical (CD/DVD/BD) drives for media and disconnect any external drives. Often times, the “NTLDR is Missing” error will appear if your PC is trying to boot to a non-bootable floppy disk, CD/DVD/BD, or external hard drive or flash drive.

    Note: If you find that this is the cause of your problem and it’s happening a lot, you might want to consider changing the boot order in BIOS so the hard drive with Windows installed is listed first.

  3. Check the hard drive and other drive settings in BIOS and ensure they are correct. The BIOS configuration tells the computer how to use a drive so incorrect settings can cause problems, including NTLDR errors.

    Note: There is usually an Auto setting for hard drive and optical drive configurations in BIOS which is usually a safe bet if you’re not sure what to do.

  4. Restore the NTLDR and ntdetect.com files from the Windows XP CD. Restoring these two important system files from the original Windows XP CD may do the trick.
  5. Repair or replace the boot.ini file. This will prevent the NTLDR error if the cause of the problem is a boot.ini file that is not configured properly for your Windows XP installation.
  6. Write a new partition boot sector to the Windows XP system partition. If the partition boot sector has become corrupt or isn’t properly configured, you may receive the “NTLDR is Missing” error.
  7. Repair the Windows XP master boot record. NTLDR error messages may also appear if the master boot record is corrupt.
  8. Reseat all internal data and power cables. NTLDR error messages could be caused by loose or malfunctioning IDE cables.

    Try replacing the IDE cable cable if you suspect it might be faulty.

  9. Update your motherboard’s BIOS. Occasionally, an outdated BIOS version can cause the “NTLDR is Missing” error.
  10. Perform a repair installation of Windows XP. This type of installation should replace any missing or corrupt files. Continue troubleshooting if this does not resolve the issue.
  11. Perform a clean installation of Windows XP. This type of installation will completely remove Windows XP from your PC and install it again from scratch. While this will almost certainly resolve any NTLDR errors, it is a time consuming process due to the fact that all of your data must be backed up and then later restored.

    If you can’t gain access to your files to back them up, understand that you will lose them all if you continue with a clean installation of Windows XP.

  12. Replace the hard drive and then perform a new installation of Windows XP. If all else has failed, including the clean installation from the last step, you’re most likely facing a hardware issue with your hard drive.

NTLDR Errors Apply To

This issue applies to the Windows XP operating system, including Windows XP Professional and Windows XP Home Edition. Windows 7 and Windows Vista do not utilize NTLDR.

Still Having NTLDR Issues?

Let a community of PC support enthusiasts help out! Post the details of your problem in the Focus on PC Support Forums. Be sure to let them know what steps you’ve already taken to resolve the “NTLDR is missing” issue.

How To Fix Missing Hal.dll Errors in Windows XP

Hal.dll Error Message

There are few different ways that the “missing or corrupt hal.dll” error may present itself, with the first listing being the most common:

  • “Windows could not start because the following file is missing or corrupt:
    <Windows root>\system32\hal.dll.
    Please re-install a copy of the above file.”
  • “<Winnt_root>\System32\Hal.dll missing or corrupt:
    Please re-install a copy of the above file.”
  • “Cannot find \Windows\System32\hal.dll”
  • “Cannot find hal.dll”

The “missing or corrupt hal.dll” error displays shortly after the computer is first started. Windows XP has not yet fully loaded when this error message appears.

Windows 7 & Vista: Hal.dll errors in Windows Vista and Windows 7 are often a different issue entirely. See How To Fix Hal.dll Errors in Windows 7 and Windows Vista for help.

Cause

Causes of the “missing or corrupt hal.dll” error include, naturally, a damaged hal.dll DLL file or a hal.dll file that has been deleted or moved from its intended location.

Additional causes may include a damaged or missing boot.ini file or possibly a physically damaged hard drive.

Hal.dll Error Troubleshooting

  1. Restart the PC. The hal.dll error could be a fluke.
  2. Check for proper boot order in BIOS. You might see the hal.dll error if the boot order in BIOS is first looking at a hard drive other than your main hard drive.

    Note: If you’ve recently changed your boot order or recently flashed your BIOS, this may be what’s causing your problem.

  3. Run Windows XP System Restore from a command prompt. If this doesn’t work or you’re receiving the hal.dll error message before you’re able to complete this process, move on to the next step.
  4. Repair or replace the boot.ini file. This will work if the cause of the problem is actually Windows XP’s boot.ini file and not the hal.dll file, which is often times the case.

    Note: If repairing the boot.ini does correct the hal.dll issue but the problem reappears after a reboot and you’ve recently installed Internet Explorer 8 in Windows XP, uninstall IE8. In this specific situation, IE8 could be the root cause of your hal.dll problem.

  5. Write a new partition boot sector to the Windows XP system partition. If the partition boot sector has become corrupt or isn’t properly configured, you may receive the hal.dll error.
  6. Recover data from any bad sectors on your hard drive. If the physical part of your hard drive that stores any part of the hal.dll file has been damaged, you’re likely to see errors like this.
  7. Restore the hal.dll file from the Windows XP CD. If the hal.dll file is truly the cause of the problem, restoring it from the original Windows XP CD may do the trick.
  8. Perform a repair installation of Windows XP. This type of installation should replace any missing or corrupt files. Continue troubleshooting if this does not resolve the issue.
  9. Perform a clean installation of Windows XP. This type of installation will completely remove Windows XP from your PC and install it again from scratch.

    Note: While this will almost certainly resolve any hal.dll errors, it is a time consuming process due to the fact that all of your data must be backed up and then later restored.

    Important: If you can’t gain access to your files to back them up, you should understand that you will lose them all if you continue with a clean installation of Windows XP.

  10. Test the hard drive. If all else has failed, including the clean installation from the last step, you’re most likely facing a hardware issue with your hard drive but you’ll want to test it to be sure.

    If the drive fails any of your tests, replace the hard drive and then complete a “new” installation of Windows XP.

Applies To

This issue applies to the Windows XP operating system, including Windows XP Professional and Windows XP Home Edition.Windows 7 and Windows Vista might also experience hal.dll errors but the causes are so different that it constituted an entirely different troubleshooting guide: How To Fix Hal.dll Errors in Windows 7 and Windows Vista.

Still Having Hal.dll Issues?

Let a community of PC support enthusiasts help out! Post the details of your problem in the PC Support Forum. Be sure to let them know what steps you’ve already taken to resolve the “missing or corrupt hal.dll” issue.

How To Fix BOOTMGR is Missing Errors for Windows Xp, Vista and 7

Question :- Recently i changed my Hard disk as it was corrupted with bad sectors, then while booting with new Hard drive i Faced BOOTMGR is Missing and Couldn’t find BOOTMGR Errors. could any one can help me resolving my problem.

Answer :- BOOTMGR Error Message

There are few ways that the “BOOTMGR is missing” error may show up on your computer, with the first error I have listed being the most common:

  • “BOOTMGR is missing
    Press Ctrl Alt Del to restart”
  • “BOOTMGR is missing
    Press any key to restart”
  • “Couldn’t find BOOTMGR”

The “BOOTMGR is missing” error displays shortly after the computer is turned on, immediately after the Power On Self Test (POST) is complete. Windows 7 or Windows Vista has only initially started to load when the BOOTMGR error message appears.

Causes of BOOTMGR Errors

There are a number of possible causes for BOOTMGR errors, including the most common “BOOTMGR is missing” error message.

The most common reasons for BOOTMGR errors include corrupt and misconfigured files, hard drive and operating system upgrade issues, corrupt hard drive sectors, an outdated BIOS, and damaged or loose IDE cables.

Another reason you might see BOOTMGR errors is if your PC is trying to boot from a hard drive or flash drive that is not properly configured to be booted from. In other words, it’s trying to boot from a non-bootable source. This also would apply to media on an optical drive or floppy drive that you’re trying to boot from.

Fixes for BOOTMGR Errors

  1. Restart the PC. The BOOTMGR error could be a fluke.
  2. Check your optical drives, USB ports, and floppy drives for media. Often times, the “BOOTMGR is Missing” error will appear if your PC is trying to boot to a non-bootable disc, external drive, or floppy disk.Note: If you find that this is the cause of your issue and it’s happening regularly, you might want to consider changing the boot order in BIOS so the hard drive is listed as the first boot device.
  3. Perform a Startup Repair of Windows. This type of installation shouldreplace any missing or corrupt files, including BOOTMGR.Even though a Startup Repair is a common solution for BOOTMGR problems, don’t worry if it doesn’t fix your problem. Just continue troubleshooting – something will work.
  4. Write a new partition boot sector to the Windows system partitionto correct any possible corruption, configuration problem, or other damage.The partition boot sector is an important piece in the boot process so if there’s any issue with it, you’ll see problems like “BOOTMGR is Missing” errors.
  5. Rebuild the Boot Configuration Data (BCD). Similar to the partition boot sector, a corrupted or incorrectly configured BCD could cause BOOTMGR error messages.Important: The following troubleshooting steps are much less likely to help fix your BOOTMGR problem. If you’ve skipped any of the above ideas then you may have overlooked a very likely solution to this problem!
  6. Check the hard drive and other drive settings in BIOS and ensure they are correct. The BIOS configuration tells the computer how to use a drive so incorrect settings can cause problems, including BOOTMGR errors.Note: There’s usually an Auto setting in BIOS for hard disk and optical drive configurations which is usually a safe bet if you’re not sure what to do.
  7. Reseat all internal data and power cables. BOOTMGR error messages could be caused by loose or malfunctioning power or controller cables.Try replacing the PATA or SATA cable if you suspect it might be faulty.
  8. Update your motherboard’s BIOS. An outdated BIOS version can sometimes cause the “BOOTMGR is Missing” error.
  9. Perform a clean installation of Windows. This type of installation will completely remove Windows from your PC and install it again from scratch. While this will almost certainly resolve any BOOTMGR errors, it’s a time consuming process due to the fact that all of your data must be backed up and then later restored.If you can’t gain access to your files to back them up, please understand that you will lose them all if you continue with a clean installation of Windows!
  10. Replace the hard drive and then install a new copy of Windows. If all else has failed, including the clean installation from the last step, you’re most likely facing a hardware issue with your hard drive.

BOOTMGR Errors Apply To

BOOTMGR issues apply to Windows 7 and Windows Vista operating systems only. Windows XP does not utilize BOOTMGR. The equivalent function in Windows XP is NTLDR.

Still Having BOOTMGR Issues?

Let a community of PC support enthusiasts help out! Post the details of your problem in the PC Support Forum. Be sure to let ‘PC Support Guys’ know what steps you’ve already taken to resolve the “BOOTMGR is missing” issue.

A detailed Discussion about CSS3 : border-image

Another exciting new border feature of CSS3 is the property border-image. With this feature you can define an image to be used instead of the normal border of an element. This feature is actually split up into a couple of properties: border-image and border-corner-image. These two values are shorthands for:

  • border-image:
    • border-top-image
    • border-right-image
    • border-bottom-image
    • border-left-image
  • border-corner-image:
    • border-top-left-image
    • border-top-right-image
    • border-bottom-left-image
    • border-bottom-right-image

border-image currently works in Safari and Firefox 3.1 (Alpha). The syntax to use it is:

border-image: url(border.png) 27 27 27 27 round round;

Which results in:

Lorem ipsum dolor sit amet.

Or:

border-image: url(border.png) 27 27 27 27 stretch stretch;

Which then results in:

Lorem ipsum dolor sit amet.

For those of you not so lucky as to be able to see this, here are screenshots of the two examples.

Number one:
border-image first example
Number two:
border-image second example

The new CSS3 property border-image is a little tricky, but it can allow you to create flexible boxes with custom borders (or drop shadows, if that’s your thing) with a single div and a single image. In this article I explain how the border-image shorthand property works in today’s browsers.

The basic idea

The border-image shorthand property has 3 parts:

border-image: url(border-image.png) 25% repeat;

Essentially, these allow you to specify:

  1. An image to use as the border
  2. Where to slice that image, dividing the image into 9 sections
  3. How the browser should apply those sections to the edges of your element

The pertinent details

Let’s look at each part of the process in a little more detail. The first part is easy, and is familiar from the background-image property. For demonstration purposes I’ll use this image, which is 100px x 100px:

A border-image

Slicing your image

The second part can have from one to four values, much like the border-width property, and they are specified in the same order: top, right, bottom, left. You can use percentages or pixels. Strangely, the percentages require the “%”, while pixels should be listed without the “px”:

border-image: url(my-image.gif) 25% 30% 10% 20% repeat;
border-image: url(my-image.gif) 25 30 10 20 repeat;

In this case, since my image is 100px x 100px, the two rules above are equivalent – they slice the image in the same places. I’ve added some dimensions on my image to demonstrate:

A border-image

Repeat, Round, Stretch

border-image will always place the corner sections of your image into the corresponding corners of your element box, but the third part of the shorthand rule tells the browser how to treat the middle sections of your image — the ones that will go along the edges of your element. Repeat (repeat, or tile, the image) and stretch (stretch, or scale, the image) are pretty self-explanatory. Round means tile the image but only so that a whole number of tiles fit, and otherwise scale the image. Right now, Safari and Chrome interpret round asrepeat. There can be up to two values: one for the top and bottom edges of the element, and one for the left and right. Here’s an example with the top/bottom value set to repeat, and the left/right value set to stretch:

#example-one {
 border-width:25px 30px 10px 20px;
 -moz-border-image:url("border-image.png") 25 30 10 20 repeat stretch;
 -webkit-border-image:url("border-image.png") 25 30 10 20 repeat stretch;
 border-image:url("border-image.png") 25 30 10 20 repeat stretch;
}

Screenshot for Example One

LIVE DEMO, RSS READERS CLICK OVER TO SEE. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu arcu non dui consequat vestibulum non vitae eros. Donec imperdiet lorem at mi rhoncus lacinia. Phasellus porttitor ligula eu justo condimentum eget placerat arcu pharetra. Proin fringilla vulputate eros in accumsan. Sed mi nibh, pulvinar eu sollicitudin ut, feugiat non ipsum. In ornare, quam sit amet tempor suscipit, erat odio suscipit nisi, eu gravida nisl orci ut arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Border-width

border-image won’t do anything if you don’t specify a width for your border. For browsers that understand border-image, your image slices will be scaled to the specified width. If you use the border shorthand property, it provides a nice fallback for browsers that don’t:

#example-two {
 border:50px double orange;
 -moz-border-image:url("border-image.png") 25 30 10 20 repeat;
 -webkit-border-image:url("border-image.png") 25 30 10 20 repeat;
 border-image:url("border-image.png") 25 30 10 20 repeat;
}

Screenshot of Example Two

LIVE DEMO, RSS READERS CLICK OVER TO SEE.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu arcu non dui consequat vestibulum non vitae eros. Donec imperdiet lorem at mi rhoncus lacinia. Phasellus porttitor ligula eu justo condimentum eget placerat arcu pharetra. Proin fringilla vulputate eros in accumsan. Sed mi nibh, pulvinar eu sollicitudin ut, feugiat non ipsum. In ornare, quam sit amet tempor suscipit, erat odio suscipit nisi, eu gravida nisl orci ut arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Or you can specify each width individually (in this example I’ve specified widths such that the image slices aren’t scaled at all):

#example-three {
 border-color:orange;
 border-style:double;
 border-width:25px 30px 10px 20px;
 -moz-border-image:url("border-image.png") 25 30 10 20 repeat;
 -webkit-border-image:url("border-image.png") 25 30 10 20 repeat;
 border-image:url("border-image.png") 25 30 10 20 repeat;
}

Screenshot of Example Three

LIVE DEMO, RSS READERS CLICK OVER TO SEE. dolor sit amet, consectetur adipiscing elit. Aenean eu arcu non dui consequat vestibulum non vitae eros. Donec imperdiet lorem at mi rhoncus lacinia. Phasellus porttitor ligula eu justo condimentum eget placerat arcu pharetra. Proin fringilla vulputate eros in accumsan. Sed mi nibh, pulvinar eu sollicitudin ut, feugiat non ipsum. In ornare, quam sit amet tempor suscipit, erat odio suscipit nisi, eu gravida nisl orci ut arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Using a plain border at the same widths as your border-image won’t always be ideal, however, so you may want to use conditional stylesheets to give IE some different border styles altogether.

Browser quirks

Predictably, IE doesn’t understand anything of border-image. Browsers that do support border-image only support the shorthand property, not all the individual properties that aredescribed in the spec. Some potentially useful properties aren’t supported at all, especiallyborder-image-outset, which would solve this problem.

Also, the default behavior is supposed to be to discard the center section of the image, and use the ‘fill’ keyword on the border-image-slice property to preserve it:

The ‘fill’ keyword, if present, causes the middle part of the border-image to be preserved. (By default it is discarded, i.e., treated as empty.) (Read the spec)

But the current browser behavior is to preserve the middle, and there is no way to turn it off. Thus, if you don’t want your element’s content area to have a background, the center section of your image must be empty. However, you can use this filling behavior to your advantage, to create a box with a fancy border and background, with only one image.

Interactive demo

I built a border-image demo page to help me get my head around this complicated new set of CSS3 properties. You can pick an image, specify repeat, round, or stretch, and adjust the border-width and slicing. Enjoy!

Examples in the wild

CSS3 makes it possible to specify an image as an element’s border, instead of just a solid color. While on the surface this doesn’t seem particularly interesting, the way the property works makes it more than that which meets the eye. The border-image property lets you specify a single image for the purpose and then slices that image to create the desired border effect. Yes, CSS is slicing now. border-image is currently supported in all the modern browsers to various degrees except IE (as of IE9). The shorthand syntax is:

border-image: url(image.png) 25 40 12 10 stretch;

Where:

  • url: The image that should be used as the border image.
  • slicevalues: Up to four numbers that specify where the browser should slice the image:
    • The 1st value sets the offset of the first horizontal cut from the top of the image. For pixel units, do NOT include the “px” suffix.

    • The 2nd value sets the offset of the second vertical cut from the right edge of the image.

    • The 3rd value sets the offset of the third horizontal cut from the bottom of the image.

    • The 4th value sets the offset of the fourth vertical cut from the left edge of the image.

  • stretch: How the slices should be oriented inside the element’s border. Valid values are “stretch”, “repeat”, “round”, or “space”.

For slicevalues, if only one number is defined, the same value will be used for all 4 cuts. If 2 numbers are defined, the first is used for the top and bottom cuts, and the second the left and right cuts. Regardless, 4 cuts are made to the image in total, and the browser ends up with 9 slices that it uses to put together the border image of an element. Each slice is used to fill the corresponding edges of the element’s border, with the center slice covering the element itself (and should be made transparent in most cases).

This post isn’t about a detailed description of border-image– that will have to be for another post. For this post, what I want to demonstrate is how to use this property to easily add image frames to containers on your page. First, create the image you’d like to use as the frame; here I’ve whipped up 2 simple frames to illustrate the technique:

  

Note that both images above have a transparent inside so the content they are framing can show through.

Now, to the heart of the matter- to add an image border to an element, define the border-image property with slicevalues that cut up the image as desired. Also define a border-width property echoing those values. Enough talk, to some examples now! Note that the below examples do not work in IE (as of IE9):

Example 1:

Found across much of the tropics, the coconut is known for its great versatility as seen in the many domestic, commercial, and industrial uses of its different parts. Coconuts are part of the daily diet of many people. Its endosperm is known as the edible “flesh” of the coconut; when dried it is called copra. The oil and milk derived from it are commonly used in cooking and frying; coconut oil is also widely used in soaps and cosmetics. The clear liquid coconut water within is a refreshing drink and can be processed to create alcohol. The husks and leaves can be used as material to make a variety of products for furnishing and decorating. It also has cultural and religious significance in many societies that use it. -Wikipedia

CSS:

.imageborder{
border-width: 20px;
-moz-border-image: url(frame.gif) 20 stretch; /*Mozilla version*/
-webkit-border-image: url(frame.gif) 20 stretch; /*Webkit version*/
-o-border-image: url(frame.gif) 20 stretch; /*Opera version*/
-ms-border-image: url(frame.gif) 20 stretch; /*IE syntax when it does support this prop*/
border-image: url(frame.gif) 20 stretch; /*Standard version*/
}

Markup:

<div style=”width:50%;min-height:150px”>
Content text here…
</div>

Example 2:

CSS: Same as above.

Markup:

<img src=”coconut.jpg” />

Example 3:

CSS:

.imageborder2{
border-width: 25px 30px;
-moz-border-image: url(frame2.png) 25 30 stretch;
-webkit-border-image: url(frame2.png) 25 30 stretch;
-o-border-image: url(frame2.png) 25 30 stretch;
-ms-border-image: url(frame2.png) 25 30 stretch;
border-image: url(frame2.png) 25 30 stretch;
}.

Markup:

<div style=”width:470px;height:300px;background:url(ocean_thumb.jpg) center center no-repeat”>
</div>

 

If you have other examples on live sites, I’d love to see them. Leave a link in the comments!

Scripting Photoshop Using C#

Maybe someday I’ll make this look better but for now this is it.

Introduction

here’s a positive dearth of information on how to control Photoshop CS via its COM interface, particularly if you don’t intend to use AppleScript, JavaScript or VB. Yet anything you can do in those languages, you can do via any .NET language.

I’m not going to do a full-on tutorial, but I will lay out some of the things I’ve found as I’ve started to explore programming PhotoShop. Part of this comes because I’m a confirmed .NET user, and would rather write my workflow apps in C# than in VB or JavaScript. Part of it comes because Photoshop is one heck of a workhorse, but automating it can make it a real timesaver.

The first documentation you come to regarding using the COM objects exposed by Photoshop is, uh, well, nothing. So at least this might give someone a little help.

Accessing the Photoshop CS Interface via COM

I’m going to tell you how I did it in Microsoft Visual C# .NET using Microsoft .NET Framework 1.1.

I personally prefer command-line programs for the tasks I set myself, but it’s not really important. So the first thing, after you’ve created your project, is to add references to the Adobe DLLs to your project. Using Solution Explorer, right-click on “References” under your project’s name. The Add Reference dialog should pop up. Across the top of the box, there are three tabs (.NET, COM and Projects). Click the COM tab (Adobe doesn’t supply a PIA for Photoshop — if you don’t know what that is, don’t worry about it).

On the COM tab you’ll find a list of COM objects available to your .NET applications. The ones you want, of course, are from Adobe. On my machine, they’re listed as “Adobe Photoshop 8.0 Object Library” and “Adobe Photoshop 8.0 Type Library”. Which one do you want? Well, you can do pretty much everything with just the Object Library, but the Type Library is handy too. Highlight them both, click select, then OK and you’ve access to the objects.

If you now build your application, you’ll see two additional DLLs produced in your bin directories: Interop.Photoshop.dll and Interop.PhotoshopTypeLibrary.dll. You’ll need to keep these for your app to run, and redistribute them with your executable if you’re sharing with anyone else.

Hello Photoshop

Here is minimal source to show Photoshop access in action. All it does is access Photoshop (it’ll start it if it’s not running) and list the physical dimensions of all open documents.

using System;
using ps = Photoshop;

ps.ApplicationClass app = new ps.ApplicationClass();
app.Preferences.RulerUnits = ps.PsUnits.psPixels; // don't tell me this in centimeters
ps.Documents doc_arr = app.Documents;
foreach (ps.Document doc in doc_arr)
{
    Console.WriteLine(doc.FullName);
    Console.WriteLine(  "{0} x {1}",doc.Width,doc.Height);
}

Using the ps alias for the Photoshop namespace, you can access all the objects in that namespace.

Tougher Stuff

I wanted to load a .NEF image created by my Nikon D70. Sure, I could code this:

ps.Application app = new ps.ApplicationClass();
app.Preferences.RulerUnits = ps.PsUnits.psPixels;
app.DisplayDialogs = ps.PsDialogModes.psDisplayNoDialogs;
app.Load("D:\\pcpix\\__shoots\\ABC\\myfiles\\RawImages\\ABC0274.NEF");

But in spite of configuring Photoshop not to show me dialogs, still the Camera Raw dialog box popped up.

There is, of course, no documentation I found on scripting the Camera Raw dialog box more effectively. So thank goodness for ScriptListener.

There are better tutorials on this subject, but the quick upshot is, shut down Photoshop and add the ScriptListener plug-in to Photoshop. On my machine, the command line’s as simple as this (your machine may not use the same paths, of course):

copy "C:\Program Files\Adobe\Photoshop CS\Scripting Guide\Utilities\ScriptListener.8li" "C:\Program Files\Adobe\Photoshop CS\Plug-Ins\Adobe Photoshop Only\Automate"

Then restart Photoshop, and every single thing you do in the UI will end up recorded to two files in the root of the drive that holds Photoshop. So on my machine, they were recorded as C:\ScriptingListenerJS.log and C:\ScriptingListenerVB.log. The first is a record of your actions as expressed in JavaScript, and the second is in VB syntax.

By the way, don’t leave that plug-in installed all the time! It creates very large files very quickly.

Needle in a Haystack

Before we look at an excerpt from such a log, here’s a quick tip that might save you some time.

Photoshop produces a huge amount of data when you record all its actions. Even if you only do the minimum you need to in order to capture your critical action so you can figure out how to do it programmatically, you may find it hard to locate among all the other text. Goodness help you if you “scrub” a value, like layer opacity, with the mouse. I generated over 200K of text scrubbing that value from 33% to 100% back to 33% again. So how was I able to easily locate the code snippet reproduced below? There’s a simple way to put little markers into the log file.

In addition to the document you’re really working on, keep a small trivial 8-bit unlayered image around, and just before you do the operation you’re really targeting, do a quick Save As using the Photoshop UI, and give the file you create a name like SequencePoint01. Do the action whose code you’re trying to examine, then to another quick SaveAs of your trivial file, and call it SequencePoint02. If you’re wanting to reproduce a whole series of steps, just continue making sequence points, and write down what you do between each of them; you’ll find it quite easy to determine exactly which actions correspond to which code.

So let’s look at some actual code recorded by ScriptListener.

Interpreting ScriptingListenerVB.log

Because this interface is really just recording the sorts of data the Actions tools use, it’s not readable at all. Here is the output for the single action of opening my .NEF file via Camera Raw:

REM =======================================================
DIM objApp
SET objApp = CreateObject("Photoshop.Application")
REM Use dialog mode 3 for show no dialogs
DIM dialogMode
dialogMode = 3
DIM id15
id15 = objApp.CharIDToTypeID( "Opn " )
    DIM desc4
    SET desc4 = CreateObject( "Photoshop.ActionDescriptor" )
    DIM id16
    id16 = objApp.CharIDToTypeID( "null" )
    Call desc4.PutPath( id16, "D:\pcpix\__shoots\ABF\myfiles\RawImages\ABF0008.NEF" )
    DIM id17
    id17 = objApp.CharIDToTypeID( "As  " )
        DIM desc5
        SET desc5 = CreateObject( "Photoshop.ActionDescriptor" )
        DIM id18
        id18 = objApp.CharIDToTypeID( "CMod" )
        Call desc5.PutString( id18, "Nikon D70" )
        DIM id19
        id19 = objApp.CharIDToTypeID( "Sett" )
        DIM id20
        id20 = objApp.CharIDToTypeID( "Sett" )
        DIM id21
        id21 = objApp.CharIDToTypeID( "Img " )
        Call desc5.PutEnumerated( id19, id20, id21 )
        DIM id22
        id22 = objApp.CharIDToTypeID( "ClrS" )
        DIM id23
        id23 = objApp.CharIDToTypeID( "ClrS" )
        DIM id24
        id24 = objApp.CharIDToTypeID( "SMPT" )
        Call desc5.PutEnumerated( id22, id23, id24 )
        DIM id25
        id25 = objApp.CharIDToTypeID( "BtDp" )
        DIM id26
        id26 = objApp.CharIDToTypeID( "BtDp" )
        DIM id27
        id27 = objApp.CharIDToTypeID( "BD16" )
        Call desc5.PutEnumerated( id25, id26, id27 )
        DIM id28
        id28 = objApp.CharIDToTypeID( "Sz  " )
        Call desc5.PutInteger( id28, 3008 )
        DIM id29
        id29 = objApp.CharIDToTypeID( "Rslt" )
        Call desc5.PutDouble( id29, 240.000000 )
        DIM id30
        id30 = objApp.CharIDToTypeID( "ReUn" )
        DIM id31
        id31 = objApp.CharIDToTypeID( "ReUn" )
        DIM id32
        id32 = objApp.CharIDToTypeID( "PpIn" )
        Call desc5.PutEnumerated( id30, id31, id32 )
    DIM id33
    id33 = objApp.StringIDToTypeID( "Adobe Camera Raw" )
    Call desc4.PutObject( id17, id33, desc5 )
Call objApp.ExecuteAction( id15, desc4, dialogMode )

I don’t find it easy to understand, so though I could probably copy the actual script out or even translate it to C#, knowing how to do something slightly different could be rather difficult.

Aside from the obscuring, hard-to-understand variable names (well, how could a tool like ScriptListener really be much smarter?) like id22 and id25, the data from which they come is pretty much as dense. When they call desc5.PutEnumerated(id22,id23,id24), it’s not much clearer even if I don’t worry about the bad variable names. How’s this for comprehensibility?

MyActionDescriptor.PutEnumerated(  objApp.CharIDToTypeID( "ClrS" ),
                                   objApp.CharIDToTypeID( "ClrS" ),
                                   objApp.CharIDToTypeID( "SMPT" ));

Decoding Parameters to CharIDToTypeID()

Well, it turns out that this call can be recoded as the following:

MyActionDescriptor.PutEnumerated(  (int)K.phTypeColorSpace,
                                   (int)K.phTypeColorSpace,
                                   (int)K.phEnumAdobeRGB1998);

It’s the same call, the same information, but honestly I understand one and don’t understand the other.

Using the Adobe Photoshop 8.0 Type Library

In the earlier code snippet, we added one using statement:

using ps = Photoshop;

If we add two more such statements to access the type library, we gain access to an enumerated value that defines many constants used with various Photoshop function calls:

using ps = Photoshop;
using      PhotoshopTypeLibrary;
using K  = PhotoshopTypeLibrary.PSConstants;

This gives you access to pst.PSConstants (with an alias of K), an enum with many, many (2003!) enumerated names. You can explore them with Visual Studio’s object browser, but I found absolutely no documentation of any of these values or their uses. So how can you use them to clean up the output of ScriptListener?

It turns out that each of these values, like all enums, maps to a numeric value. And the enum value of PSConstants.phTypeColorSpace is the same as the number returned by objApp.CharIDToTypeID(“ClrS”).

Decoding these is as simple as taking the value returned by the call to CharIDToTypeID() and using the .NET Enum functions to convert that value back into the enum string for PSConstants.

It turns out that this only works sometimes. Many values that are be supplied to CharIDToTypeID() and StringIDToTypeID() map to a valid PSConstants ID, but many do not ( like StringIDToTypeID(“Adobe Camera Raw”) ). In those cases, you cannot use a PSConstants value to replace the output of the function as used in the ScriptListener output.

A Cleaner Camera Raw File Load

Here is the code after I did the translations and got rid of extraneous variables:

ps.ActionDescriptorClass ad = new Photoshop.ActionDescriptorClass();

// specify the filename
ad.PutPath(         (int)K.phEnumNull,
          "D:\\pcpix\\__shoots\\ABF\\myfiles\\RawImages\\ABF0008.NEF");

ps.ActionDescriptorClass ad2 = new Photoshop.ActionDescriptorClass();
ad2.PutString(      app.CharIDToTypeID("CMod"),              // camera model
                    "Nikon D70");
ad2.PutEnumerated(  (int)K.phTypeColorSpace,                 // color space
                    (int)K.phTypeColorSpace,
                    (int)K.phEnumAdobeRGB1998);
ad2.PutEnumerated(  (int)K.phTypeBitDepth,                   // bit depth
                    (int)K.phTypeBitDepth,
                    (int)K.phEnumBitDepth16);
ad2.PutInteger(     (int)K.phKeySizeKey,                     // the width... why?
                    3008);
ad2.PutDouble(      (int)K.phKeyResolution,                  // DPI
                    240.0);
int ReUnID = app.CharIDToTypeID("ReUn");                     // ???
ad2.PutEnumerated(  ReUnID,                                  // maybe this forces it
                    ReUnID,                                  // to close without interaction?
                    app.CharIDToTypeID("PpIn"));             // ...or use file's settings?

ad.PutObject(       (int)K.phKeyAs,                          // identifies the target object
                    app.StringIDToTypeID("Adobe Camera Raw"),
                    ad2);
app.ExecuteAction(  (int)K.phEventOpen,                      // what to do
                    ad,
                    (int)ps.PsDialogModes.psDisplayNoDialogs); // maybe this suppresses the dialog

Now, I’ve not got it all figured out (mostly because I don’t need to solve the remaining questions), but I can certainly parameterize the things likely to differ from invocation to invocation and wrap this in a clean function. More particularly, I know how to modify the things I don’t like as they are… like changing the bit depth to phEnumBitDepth8.

Rosetta Stone

Once I realized how much I could learn from the ScriptListener output if I could understand it better, I decided to decode all the strings I could. Fortunately, it’s easy with C# to programmatically obtain an exhaustive list of the names in an enum and their associated values, so I wrote a program that lists all of the enum names and values. For each enum value, the program also calls TypeIDToCharID() and TypeIDToStringID() to find out what string each enum corresponds to.

As you will see, some enums share a common value; they are therefore equivalent. Here is a small excerpt from this list:

                         PSConstants ->      value -> CharID  TypeIDToStringID
                          ---------- ->      ----- -> ------  ----------------
...
                     phEnumBitDepth1 -> 1111765280 ->   BD1   bitDepth1
                    phEnumBitDepth16 -> 1111765302 ->   BD16  
                    phEnumBitDepth24 -> 1111765556 ->   BD24  bitDepth24
                    phEnumBitDepth32 -> 1111765810 ->   BD32  
                     phEnumBitDepth4 -> 1111766048 ->   BD4   bitDepth4
                     phEnumBitDepth8 -> 1111767072 ->   BD8   bitDepth8
...
                phEnumChannelOptions -> 1130917455 ->   ChnO  channelOptions
        phEnumChannelsPaletteOptions -> 1130917456 ->   ChnP  channelsPaletteOptions
                      phClassChannel -> 1130917484 ->   Chnl  channel
                        phKeyChannel
                       phTypeChannel
                       phKeyChannels -> 1130917491 ->   Chns  channels
                   phKeyCharcoalArea -> 1130918465 ->   ChrA  charcoalArea
                     phEventCharcoal -> 1130918499 ->   Chrc  charcoal
...

From this you can see that the enum K.phEnumChannelOptions has the value 1130917455, which is also returned by CharIDToTypeID(“ChnO”), and StringIDToTypeID(“channelOptions”). (I got the strings by calling TypeIDToCharID(1130917455) and TypeIDToStringID(1130917455), thus the column headers).

You can also see that the value 1130917484, corresponding to CharIDToTypeID(“Chnl”) and StringIDToTypeID(“channel”), has three different PSConstants enum names that all produce the same value: phClassChannel, phKeyChannel, and phTypeChannel. Use the one that seems best to you.

I’ve sorted this list four different ways and have sometimes found each one handy. Here they are sorted by PSConstants enum name, PSConstants enum value, result of TypeIDToCharID(), and result of TypeIDToStringID().

Photoshop and .NET Unleashed

C# with .NET is a useful, powerful combination. If you want to really put Photoshop through its paces, the very useful (if a bit hard to parse) output of ScriptListener will give you access to anything you can do with Photoshop Actions. I hope this information makes this just a tiny bit easier for you.

Further Collaboration

There don’t seem to be too many people leveraging Photoshop with .NET, but it can be a potent combination. I’d welcome any feedback or suggestions — my email is john, at the domain listed at the bottom of this page.

%d bloggers like this: