Привет. У меня всегда были проблемы с решениями выше (и на других сайтах). Я, как разработчик, программирую аддон для API. API разрешает использование любых внешних библиотек или сторонних инструментов. Установка также состоит из смеси кода в jar или zip-файлах и файлах классов, расположенных непосредственно в некоторых каталогах. Таким образом, мой код должен был работать на всех настройках. После большого количества исследований я придумал метод, который будет работать, по крайней мере, на 95% всех возможных настроек.
Следующий код - это в основном метод переполнения, который всегда будет работать.
Этот код сканирует данный пакет для всех классов, включенных в него. Он будет работать только для всех классов в текущем ClassLoader
.
/**
* Private helper method
*
* @param directory
* The directory to start with
* @param pckgname
* The package name to search for. Will be needed for getting the
* Class object.
* @param classes
* if a file isn't loaded but still is in the directory
* @throws ClassNotFoundException
*/
private static void checkDirectory(File directory, String pckgname,
ArrayList<Class<?>> classes) throws ClassNotFoundException {
File tmpDirectory;
if (directory.exists() && directory.isDirectory()) {
final String[] files = directory.list();
for (final String file : files) {
if (file.endsWith(".class")) {
try {
classes.add(Class.forName(pckgname + '.'
+ file.substring(0, file.length() - 6)));
} catch (final NoClassDefFoundError e) {
// do nothing. this class hasn't been found by the
// loader, and we don't care.
}
} else if ((tmpDirectory = new File(directory, file))
.isDirectory()) {
checkDirectory(tmpDirectory, pckgname + "." + file, classes);
}
}
}
}
/**
* Private helper method.
*
* @param connection
* the connection to the jar
* @param pckgname
* the package name to search for
* @param classes
* the current ArrayList of all classes. This method will simply
* add new classes.
* @throws ClassNotFoundException
* if a file isn't loaded but still is in the jar file
* @throws IOException
* if it can't correctly read from the jar file.
*/
private static void checkJarFile(JarURLConnection connection,
String pckgname, ArrayList<Class<?>> classes)
throws ClassNotFoundException, IOException {
final JarFile jarFile = connection.getJarFile();
final Enumeration<JarEntry> entries = jarFile.entries();
String name;
for (JarEntry jarEntry = null; entries.hasMoreElements()
&& ((jarEntry = entries.nextElement()) != null);) {
name = jarEntry.getName();
if (name.contains(".class")) {
name = name.substring(0, name.length() - 6).replace('/', '.');
if (name.contains(pckgname)) {
classes.add(Class.forName(name));
}
}
}
}
/**
* Attempts to list all the classes in the specified package as determined
* by the context class loader
*
* @param pckgname
* the package name to search
* @return a list of classes that exist within that package
* @throws ClassNotFoundException
* if something went wrong
*/
public static ArrayList<Class<?>> getClassesForPackage(String pckgname)
throws ClassNotFoundException {
final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
try {
final ClassLoader cld = Thread.currentThread()
.getContextClassLoader();
if (cld == null)
throw new ClassNotFoundException("Can't get class loader.");
final Enumeration<URL> resources = cld.getResources(pckgname
.replace('.', '/'));
URLConnection connection;
for (URL url = null; resources.hasMoreElements()
&& ((url = resources.nextElement()) != null);) {
try {
connection = url.openConnection();
if (connection instanceof JarURLConnection) {
checkJarFile((JarURLConnection) connection, pckgname,
classes);
} else if (connection instanceof FileURLConnection) {
try {
checkDirectory(
new File(URLDecoder.decode(url.getPath(),
"UTF-8")), pckgname, classes);
} catch (final UnsupportedEncodingException ex) {
throw new ClassNotFoundException(
pckgname
+ " does not appear to be a valid package (Unsupported encoding)",
ex);
}
} else
throw new ClassNotFoundException(pckgname + " ("
+ url.getPath()
+ ") does not appear to be a valid package");
} catch (final IOException ioex) {
throw new ClassNotFoundException(
"IOException was thrown when trying to get all resources for "
+ pckgname, ioex);
}
}
} catch (final NullPointerException ex) {
throw new ClassNotFoundException(
pckgname
+ " does not appear to be a valid package (Null pointer exception)",
ex);
} catch (final IOException ioex) {
throw new ClassNotFoundException(
"IOException was thrown when trying to get all resources for "
+ pckgname, ioex);
}
return classes;
}
Эти три метода предоставляют вам возможность находить все классы в данном пакете. Вы используете его следующим образом:
getClassesForPackage("package.your.classes.are.in");
Метод сначала получает текущий ClassLoader
. Затем он извлекает все ресурсы, содержащие указанный пакет, и итерации этих URL
s. Затем он создает URLConnection
и определяет тип URl, который у нас есть. Это может быть либо каталог (FileURLConnection
), либо каталог внутри jar или zip-файла (JarURLConnection
). В зависимости от типа соединения мы будем вызывать два разных метода.
Сначала давайте посмотрим, что произойдет, если это FileURLConnection
. Сначала он проверяет, существует ли переданный файл и является ли он каталогом. Если это так, он проверяет, является ли это файлом класса. Если это так, то объект Class
будет создан и помещен в ArrayList
. Если это не файл класса, а каталог, мы просто повторяем его и делаем то же самое. Все остальные случаи / файлы будут игнорироваться.
Если URLConnection
является JarURLConnection
, будет вызван другой метод private helper. Этот метод выполняет итерацию по всем записям в архиве zip / jar. Если одна запись является файлом класса и находится внутри пакета, объект Class
будет создан и сохранен в ArrayList
.
После того, как все ресурсы были проанализированы, он (основной метод) возвращает ArrayList
содержит все классы в данном пакете, о которых знает текущий ClassLoader
.
Если процесс завершается с ошибкой в любой момент, а ClassNotFoundException
будет зависеть от подробной информации о конкретной причине.
Я полагаю, что это корректно:
using (X509Store store = new X509Store(StoreName.TrustedPeople, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadWrite);
store.Add(cert); //where cert is an X509Certificate object
}
У меня хорошо работает следующее:
private static void InstallCertificate(string cerFileName)
{
X509Certificate2 certificate = new X509Certificate2(cerFileName);
X509Store store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
}