How do I find iTunes library folder on Mac and Windows? - windows

I made an application that parse the iTunes library to retrieve its content. It works fine in most cases but if a user moved his library somewhere else than the default iTunes folder (see: http://lifehacker.com/238296/ultranewb--how-to-move-your-itunes-library-to-an-external-drive), then I need a way to find this path.
On Mac, I was looking into ~/Library/Preferences/com.apple.iTunes.plist. There is a setting called "alis:1:iTunes Library Location" but it contains several parameters all concatenated and converted to hexadecimal.
On Windows, I found this file "C:\Documents and Settings\\Application Data\Apple Computer\iTunes\iTunesPrefs.xml" that contains a setting "iTunes Library XML Location:1" but this one is encoded.
Any help would be greatly appreciated.
Thanks!

On Windows, the iTunes Library XML Location:1 entry in iTunesPrefs.xml is a Base 64 encoded Unicode string, so you'll need to decode it before you can use it. On my PC, it decodes to C:\Documents and Settings\Emerick\My Documents\My Music\iTunes\iTunes Music Library.xml.
It should be relatively easy to decode this value using your language of choice; your platform may even provide utility libraries that make this trivial. In C#, for example, the decoding function would look something like this:
static public string DecodeBase64(string encodedData)
{
byte[] encodedBytes = System.Convert.FromBase64String(encodedData);
return System.Text.UnicodeEncoding.Unicode.GetString(encodedBytes);
}

I can't help you with the Windows stuff, but on the Mac what you're seeing in that prefs file is old-school alias handle data. Take a look at or just use Chris Hanson's BDAlias class to convert it to a path.
http://github.com/rentzsch/bdalias

As the others point out "alis:1:iTunes Library Location" is alias data. Here's how I find the path from the data in OS X using Python.
#!/usr/bin/env python
import commands, plistlib
from Carbon import File
from os.path import expanduser
PLIST_PATH = '~/Library/Preferences/com.apple.iTunes.plist'
PLIST_KEY = 'alis:1:iTunes Library Location'
def resolve_path_from_alias_data( alis ):
fs_ref = File.Alias( rawdata=alis ).FSResolveAlias( None )[0]
file_path = fs_ref.as_pathname()
return file_path
plist_str = commands.getoutput( '/usr/bin/plutil -convert xml1 -o - "' + expanduser( PLIST_PATH ) + '"' )
plist_data = plistlib.readPlistFromString( plist_str )
alis_data = plist_data[ PLIST_KEY ].data
file_path = resolve_path_from_alias_data( alis_data )
print repr( file_path )
Unfortunately, iTunes no longer uses "alis:1:iTunes Library Location" so this no longer works. Now iTunes 11 uses an entry called "RDoc:132:Documents" which seems to be completely different. I have posted a similar question with the appropriate iTunes 11 details.
Actually, my answer works just fine as of OS X 10.9.1. I'm not sure whether it stopped due to some error I made, or if Apple quietly reverted something. Either way, it's working again on my Mac.

Related

filepath Base on windows not working after cross compilation (Golang)

If I have a path on linux/OSX such as filepath := /Users/jamesbond/some/where/file.txt
then I can do
name := path.Base(filepath)
and name will be file.txt
however on windows this does not work. The returned value of name is still /Users/jamesbond/some/where/file.txt
I guess I can see why, as the function base has
for len(path) > 0 && path[len(path)-1] == '/' {
path = path[0 : len(path)-1]
}
i.e its clearly really only setup for linux/OSX style file paths.
I am cross compiling from OSX for windows. I guess that the library on windows has the corect / in the SDK, but how can I handle this regardless of OS? Is there a way to convert or something before, then use Base function?
What would be the recommended way to write this code once and it work on all OSes?

How to ship or export an sdl project made in codeblocks

The project uses external image files and codeblocks is configured to find the library and header files for SDL. How can I turn the project into a format so that it can be easily shipped ? I intend to create a single executable file or an installer which is portable .
How can I do this ?
I've done that many times.
You just have to put the necessary DLLs (I use SDL 1.2, so SDL.dll, SDL_image.dll,zlib.dll, ...) where the executable is, which may be not so good with codeblocks/VC++ tree and the Debug/bin & Release/bin directories but would work with a .bat file which could run the executable.
OR
Consider that your development project is NOT the one the users will see.
Do you think that Microsoft guys code all system32 commands in one single source directory?
So develop however you like and then create a deliver script to put everything in the root directory. Like that you don't have the constraints of delivered product while you are developping and reverse.
I recommend this approach.
Checkout My bagman SDL remake to see what I mean
When I create the archive for distribution, I use a custom script that I include here. This one has all the works, libmpeg for mp3 decompression, and all. If you unzip the Bagman archive, it works right away on a windows PC.
Here's my directory tree
Bagman\bin
Bagman\exploit
Bagman\icons
Bagman\music
Bagman\obj
Bagman\resource
Bagman\sound
Bagman\src
Bagman\work
Bagman\bin\Debug
Bagman\bin\Debug256
Bagman\bin\Release
Bagman\exploit\mkf
Bagman\obj\Amiga
Bagman\obj\Debug
Bagman\obj\Debug256
Bagman\obj\NDS
Bagman\obj\NDSEMU
Bagman\obj\Release
Bagman\obj\Debug\src
Bagman\obj\Debug\src\characters
Bagman\obj\Debug\src\engine
Bagman\obj\Debug\src\gfx
Bagman\obj\Debug\src\screens
Bagman\obj\Debug\src\sys
Bagman\obj\Debug256\src
Bagman\obj\Debug256\src\characters
Bagman\obj\Debug256\src\engine
Bagman\obj\Debug256\src\gfx
Bagman\obj\Debug256\src\sys
Bagman\obj\NDS\src
Bagman\obj\NDS\src\characters
Bagman\obj\NDS\src\engine
Bagman\obj\NDS\src\gfx
Bagman\obj\NDS\src\sys
Bagman\obj\NDSEMU\src
Bagman\obj\NDSEMU\src\characters
Bagman\obj\NDSEMU\src\engine
Bagman\obj\NDSEMU\src\gfx
Bagman\obj\NDSEMU\src\sys
Bagman\obj\Release\src
Bagman\obj\Release\src\characters
Bagman\obj\Release\src\engine
Bagman\obj\Release\src\gfx
Bagman\obj\Release\src\sys
Bagman\resource\1x
Bagman\resource\maps
Bagman\resource\1x\images
Bagman\resource\1x\sprites
Bagman\src\characters
Bagman\src\engine
Bagman\src\gfx
Bagman\src\screens
Bagman\src\sys
Here's the python script that copies all necessary files in the user archive:
import sys,os,zipfile,re,shutil,glob
import find,which # custom modules I created myself
MODULE_FILE = sys.modules[__name__].__file__
PROGRAM_DIR = os.path.abspath(os.path.dirname(MODULE_FILE))
ROOTDIR=os.path.realpath(os.path.join(PROGRAM_DIR,os.pardir))
PRODUCT_NAME="Bagman"
music=False
dev=False
version = "1.2"
print("making archive for version "+version)
os.chdir(ROOTDIR)
archname=PRODUCT_NAME+"-win32-"+version+".zip"
zfn = os.path.join(ROOTDIR,os.pardir,archname)
if os.path.exists(zfn):
os.remove(zfn)
zf = zipfile.ZipFile(zfn,mode="w",compression=zipfile.ZIP_DEFLATED)
dll_list = ["SDL.dll","SDL_Mixer.dll"]+["smpeg.dll","libgcc_s_sjlj-1.dll","libstdc++-6.dll","libgcc_s_dw2-1.dll"] # MP3 playing needs the second part
items_list = ["bagman*.bat","*.cbp","*.dev","*.txt","COPYING","resource","exploit","sound","src"]
real_items_list = []
for i in items_list:
real_items_list.extend(glob.glob(i))
for d in dll_list:
print("processing '"+d+"'")
dp = which.which(d)
if len(dp)==0:
raise Exception("%s not found in PATH" % d)
zf.write(dp[0],arcname=PRODUCT_NAME+"/"+d)
for i in real_items_list:
print("processing '"+i+"'")
if os.path.isfile(i):
zf.write(i,arcname=PRODUCT_NAME+"/"+i)
else:
fnd = find.Find()
items = fnd.init(i)
for f in items:
if i == "resource" and os.path.basename(f) in ["settings","soundbank.bin"]:
pass
else:
fi = f.replace(os.sep,"/")[2:]
if os.path.isfile(fi):
if fi.endswith("~"):
pass
else:
zf.write(fi,arcname=PRODUCT_NAME+"/"+fi)
else:
zfi = zipfile.ZipInfo(PRODUCT_NAME+"/"+fi+"/")
zf.writestr(zfi, '')
zfi = zipfile.ZipInfo(PRODUCT_NAME+"/bin/")
zf.writestr(zfi, '')
zfi = zipfile.ZipInfo(PRODUCT_NAME+"/bin/Release/")
zf.writestr(zfi, '')
zfi = zipfile.ZipInfo(PRODUCT_NAME+"/bin/Debug/")
zf.writestr(zfi, '')
zf.write("bin/Release/bagman.exe",arcname=PRODUCT_NAME+"/bin/Release/bagman.exe")
zf.close()
I know that there are existing python modules which will help you achieve such things (distutils). I did not use them because I wasn't aware of them.

How to get HTML data out of of the OS X pasteboard / clipboard?

I do have to send a report regarding pasting some clipboard content into a web rich editor and I need a way to dump/restore the clipboard content to (probably) HTML.
How can I do this?
It seems that pbcopy / pbpaste do alway give me text even if I use the pbpaste -P rtf or pbpaste -P HTML
Three years later, in more civilized times, we have Swift. You can write a short Swift script to pull exactly what you need off of OS X's pasteboard.
Put the following Swift 4 snippet into a new text file. I named mine pbpaste.swift:
import Cocoa
let type = NSPasteboard.PasteboardType.html
if let string = NSPasteboard.general.string(forType:type) {
print(string)
}
else {
print("Could not find string data of type '\(type)' on the system pasteboard")
exit(1)
}
Then, copy some html, and run swift pbpaste.swift from the directory where you put that file.
Yay, html! Uggh, OS X added a ton of custom markup (and a <meta> tag?!) — but hey, at least it's not plain text!
Notes:
NSPasteboard.PasteboardType.html is a special global that evaluates to the string "public.html"
Obviously this is html specific, so you'd probably want to either:
Name it pbpaste-html.swift, or
Read the desired type from the command line arguments
It's kind of slow, because it's being interpreted on the fly, not compiled and executed. Compilation gives me a 10x speed-up:
xcrun -sdk macosx swiftc pbpaste.swift -o pbpaste-html
Then just call ./pbpaste-html instead of swift pbpaste.swift.
I realise you've already found this, but for the benefit of people who turn up here from Google, the solution given for RTF data at Getting RTF data out of Mac OS X pasteboard (clipboard) works fine for getting HTML out of the clipboard, too.
That is, the command
osascript -e 'the clipboard as «class HTML»' | perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'

How to get the parent folder of a Windows user's profile path using C++

I am trying get the parent folder of a Windows user's profile path. But I couldn't find any "parameter" to get this using SHGetSpecialFolderPath, so far I am using CSIDL_PROFILE.
Expected Path:
Win7 - "C:\Users"
Windows XP - "C:\Documents and Settings"
For most purposes other than displaying the path to a user, it should work to append "\\.." (or "..\\" if it ends with a backslash) to the path in question.
With the shell libary version 6.0 you have the CSIDL_PROFILES (not to be confused with CSIDL_PROFILE) which gives you what you want. This value was removed (see here), you have to use your own workaround.
On any prior version you'll have to implement your own workaround, such as looking for the possible path separator(s), i.e. \ and / on Windows, and terminate the string at the last one. A simple version of this could use strrchr (or wcsrchr) to locate the backslash and then, assuming the string is writable, terminate the string at that location.
Example:
char* path;
// Retrieve the path at this point, e.g. "C:\\Users\\username"
char* lastSlash = strrchr(path, '\\');
if(!lastSlash)
lastSlash = strrchr(path, '/');
if(lastSlash)
*lastSlash = 0;
Or of course GetProfilesDirectory (that eluded me) which you pointed out in a comment to this answer.

Delete file in windows 7 using VB.NET

I have written following code in vb.net to delete the file.
If File.Exists(strPath & "\ReportEng.ini") = True Then
File.SetAttributes(strPath & "\ReportEng.ini", FileAttributes.Normal)
File.Delete(strPath & "\ReportEng.ini")
End If
File.Copy("\\192.168.0.1\SAP_Shared\AddonExtra\ReportEng.ini", strPath & "\ReportEng.ini")
This code works perfectly in windows xp. But in Windows 7,I can not delete it. This OS is hectic OS from developer's point of view. Some or other problem occurs and Microsoft has not considered the developer while building this OS.
How do I delete file in Windows 7 ?
It's so easy to do so;
If My.Computer.FileSystem.FileExists("C:\somefile.ext") Then 'Check whether file exists
My.Computer.FileSystem.DeleteFile("C:\somefile.ext") 'Delete the file!
End If
Have a nice day!
You don't need to delete the file: there is an overload File.Copy Method (String, String, Boolean) which allows overwriting.
You didn't say what error you get. I suspect it is because the user doesn't have write access to the directory. You should probably be using a subdirectory of the directory returned by Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) or maybe .LocalApplicationData, and definitely not the directory containing the program.
Also, using Path.Combine(strPath, "ReportEng.ini") is how you're meant to combine paths - it'll take care of, e.g., the trailing path separator for you.
The preferred method for interfacing with the Windows file system uses the following namespace:
Imports Microsoft.VisualBasic.FileIO.FileSystem
To delete a file:
Dim FileLocation As String = strPath & "\ReportEng.ini"
If Not GetDirectoryInfo(FileLocation).Exists Then
GetFileInfo(FileLocation).Delete()
End If

Resources