Task 753: .URL File Format
Task 753: .URL File Format
The .URL file format is a simple INI-style text file used for Windows Internet Shortcuts. The properties intrinsic to the file format, as per the specifications, are contained within the [InternetShortcut] section. The following is a list of all identified properties:
- URL: String representing the fully qualified URL to the target resource.
- WorkingDirectory: String representing the working directory for the shortcut.
- IconIndex: Integer representing the index of the icon within the icon file.
- IconFile: String representing the path to the file containing the icon.
- Modified: Hexadecimal string representing the last modification time in inverted FILETIME structure format.
- ShowCommand: Integer representing the window show state (e.g., 1 for normal, 3 for maximized, 7 for minimized).
- HotKey: Integer representing the keyboard shortcut combination.
Additional sections, such as [DEFAULT] and [DOC#...] for extended frame state persistence, may appear in some files, but the above properties are the core ones intrinsic to the format.
After conducting searches, direct download links for .URL files are limited due to their simple text nature and infrequent hosting. Two examples are:
- https://raw.githubusercontent.com/MarcBresson/cpasbien/master/cpasbien.url
- https://filesamples.com/samples/document/url/sample.url (illustrative; actual availability may vary based on site updates).
The following is an HTML code snippet with embedded JavaScript that can be embedded in a Ghost blog post. It creates a drag-and-drop area for a .URL file and dumps the properties to the screen upon drop.
- The following is a Python class for handling .URL files. It uses the configparser module to parse the INI structure, reads the properties, prints them to console, and allows writing back to a file.
import configparser
class URLFile:
def __init__(self, filename):
self.filename = filename
self.config = configparser.ConfigParser()
self.config.read(filename)
self.properties = {}
if 'InternetShortcut' in self.config:
self.properties = dict(self.config['InternetShortcut'])
def print_properties(self):
props_list = ['URL', 'WorkingDirectory', 'IconIndex', 'IconFile', 'Modified', 'ShowCommand', 'HotKey']
for prop in props_list:
value = self.properties.get(prop, 'Not present')
print(f"{prop}: {value}")
def set_property(self, key, value):
if 'InternetShortcut' not in self.config:
self.config['InternetShortcut'] = {}
self.config['InternetShortcut'][key] = value
self.properties[key] = value
def write(self, filename=None):
if filename is None:
filename = self.filename
with open(filename, 'w') as configfile:
self.config.write(configfile)
- The following is a Java class for handling .URL files. Since Java's Properties class does not directly support sections, manual parsing is used for reading and writing.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class URLFile {
private String filename;
private Map<String, String> properties = new HashMap<>();
public URLFile(String filename) {
this.filename = filename;
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;
boolean inSection = false;
while ( (line = reader.readLine()) != null ) {
line = line.trim();
if (line.equals("[InternetShortcut]")) {
inSection = true;
} else if (inSection && line.contains("=")) {
String[] parts = line.split("=");
if (parts.length == 2) {
properties.put(parts[0].trim(), parts[1].trim());
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void printProperties() {
String[] propsList = {"URL", "WorkingDirectory", "IconIndex", "IconFile", "Modified", "ShowCommand", "HotKey"};
for (String prop : propsList) {
String value = properties.getOrDefault(prop, "Not present");
System.out.println(prop + ": " + value);
}
}
public void setProperty(String key, String value) {
properties.put(key, value);
}
public void write(String filename) throws IOException {
try (FileWriter writer = new FileWriter(filename)) {
writer.write("[InternetShortcut]\n");
for (Map.Entry<String, String> entry : properties.entrySet()) {
writer.write(entry.getKey() + "=" + entry.getValue() + "\n");
}
}
}
}
- The following is a JavaScript class for handling .URL files. It uses asynchronous file reading for browser contexts and manual parsing.
class URLFile {
constructor(file) {
this.file = file;
this.properties = {};
}
async read() {
const text = await this.file.text();
const lines = text.split(/\r?\n/);
let inSection = false;
lines.forEach((line) => {
line = line.trim();
if (line === '[InternetShortcut]') {
inSection = true;
} else if (inSection && line.includes('=')) {
const [key, value] = line.split('=').map(part => part.trim());
this.properties[key] = value;
}
});
}
printProperties() {
const propsList = ['URL', 'WorkingDirectory', 'IconIndex', 'IconFile', 'Modified', 'ShowCommand', 'HotKey'];
propsList.forEach((prop) => {
const value = this.properties[prop] || 'Not present';
console.log(`${prop}: ${value}`);
});
}
setProperty(key, value) {
this.properties[key] = value;
}
write() {
let text = '[InternetShortcut]\n';
for (const [key, value] of Object.entries(this.properties)) {
text += `${key}=${value}\n`;
}
// To save, create a Blob and trigger download
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = this.file.name || 'output.url';
a.click();
URL.revokeObjectURL(url);
}
}
- The following is a C++ class for handling .URL files. It uses fstream for file I/O and manual parsing for the INI structure.
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
class URLFile {
private:
std::string filename;
std::map<std::string, std::string> properties;
public:
URLFile(const std::string& fn) : filename(fn) {
std::ifstream file(fn);
if (!file) {
std::cerr << "Error opening file." << std::endl;
return;
}
std::string line;
bool inSection = false;
while (std::getline(file, line)) {
line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
if (line == "[InternetShortcut]") {
inSection = true;
} else if (inSection && line.find('=') != std::string::npos) {
size_t pos = line.find('=');
std::string key = line.substr(0, pos);
std::string value = line.substr(pos + 1);
properties[key] = value;
}
}
file.close();
}
void printProperties() {
std::string propsList[7] = {"URL", "WorkingDirectory", "IconIndex", "IconFile", "Modified", "ShowCommand", "HotKey"};
for (int i = 0; i < 7; ++i) {
auto it = properties.find(propsList[i]);
std::string value = (it != properties.end()) ? it->second : "Not present";
std::cout << propsList[i] << ": " << value << std::endl;
}
}
void setProperty(const std::string& key, const std::string& value) {
properties[key] = value;
}
void write(const std::string& fn = "") {
std::string outFile = fn.empty() ? filename : fn;
std::ofstream file(outFile);
if (!file) {
std::cerr << "Error writing file." << std::endl;
return;
}
file << "[InternetShortcut]" << std::endl;
for (const auto& pair : properties) {
file << pair.first << "=" << pair.second << std::endl;
}
file.close();
}
};