سؤال

يمكنني استخدام Launch4J كغلاف لتطبيق Java الخاص بي تحت Windows 7، والذي، على فهمي، في جوهر الجوهر مثيل javaw.exe وهذا بدوره يفسر رمز جافا. نتيجة لذلك، عند محاولة تحديد طلبي إلى شريط المهام، ويندوز بدلا من دبابيس javaw.exe. وبعد بدون سطر الأوامر المطلوب، لن يتم تشغيل طلبي.

Result of pinning a Launch4j application to the taskbar

كما ترون، لا يدرك Windows أيضا أن Java هو تطبيق المضيف: يتم وصف التطبيق نفسه بأنه "جافا (TM) منصة SE Binary".

لقد حاولت تغيير مفتاح التسجيل HKEY_CLASSES_ROOT\Applications\javaw.exe لإضافة القيمة IsHostApp. وبعد هذا يغير السلوك عن طريق تعطيل تثبيت طلبي تماما؛ من الواضح أن لا ما أريد.

Result of specifying javaw.exe as a host application

بعد القراءة حول كيف يفسر ويندوز مثيلات تطبيق واحدظاهرة ناقشت في هذا السؤال)، أصبحت مهتمة بتضمين معرف نموذج مستخدم التطبيق (AppusermodelID) في تطبيق Java الخاص بي.

أعتقد أنه يمكنني حل هذا عن طريق تمرير فريدة من نوعها AppUserModelID إلى ويندوز. هناك shell32 طريقة لهذا، SetCurrentProcessExplicitAppUserModelID. وبعد بعد اقتراح غريغوري باكوسز، قمت بتنفيذها في محاولة للحصول على طلبي المعترف به كحل منفصل javaw.exe:

NativeLibrary lib;
try {
    lib = NativeLibrary.getInstance("shell32");
} catch (Error e) {
    Logger.out.error("Could not load Shell32 library.");
    return;
}
Object[] args = { "Vendor.MyJavaApplication" };
String functionName = "SetCurrentProcessExplicitAppUserModelID";
try {
    Function function = lib.getFunction(functionName);
    int ret = function.invokeInt(args);
    if (ret != 0) {
        Logger.out.error(function.getName() + " returned error code "
                + ret + ".");
    }
} catch (UnsatisfiedLinkError e) {
    Logger.out.error(functionName + " was not found in "
            + lib.getFile().getName() + ".");
    // Function not supported
}

يبدو أن هذا ليس له أي تأثير، لكن الوظيفة تعود دون خطأ. تشخيص لماذا هو شيء لغز بالنسبة لي. أي اقتراحات؟

تنفيذ العمل

التنفيذ النهائي الذي عمل هو الجواب على سؤال متابعة بلدي بشأن كيفية اجتياز AppID باستخدام jna.

لقد منحت مكافأة إجابة غريغوري باكوسز الرائعة ل JNI التي وضعتني على المسار الصحيح.

للرجوع اليها، أعتقد أن استخدام هذه التقنية يفتح إمكانية استخدام أي من واجهات برمجة التطبيقات التي تمت مناقشتها في هذه المادة في تطبيق Java.

هل كانت مفيدة؟

المحلول

ليس لدي نظام التشغيل Windows 7 ولكن هنا شيء قد يبدأك:

على الجانب جافا:

package com.stackoverflow.homework;

public class MyApplication
{
  static native boolean setAppUserModelID();

  static
  {
    System.loadLibrary("MyApplicationJNI");
    setAppUserModelID();
  }
}

وعلى الجانب الأصلي، في التعليمات البرمجية المصدر لمكتبة `myapplicationjni.dll:

JNIEXPORT jboolean JNICALL Java_com_stackoverflow_homework_MyApplication_setAppUserModelID(JNIEnv* env)
{
  LPCWSTR id = L"com.stackoverflow.homework.MyApplication";
  HRESULT hr = SetCurrentProcessExplicitAppUserModelID(id);

  return hr == S_OK;
}

طلب سؤالك صراحة محلول JNI. ومع ذلك، نظرا لأن طلبك لا يحتاج إلى أي طريقة أصلية أخرى، جني هو حل آخر سيوفر لك من كتابة التعليمات البرمجية الأصلية فقط من أجل إعادة التوجيه إلى واجهة برمجة تطبيقات Windows. إذا قررت الذهاب إلى الجنة، انتبه لحقيقة ذلك SetCurrentProcessExplicitAppUserModelID() تتوقع سلسلة UTF-16.

عندما يعمل في صندوق الرمل الخاص بك، فإن الخطوة التالية هي إضافة اكتشاف نظام التشغيل في طلبك SetCurrentProcessExplicitAppUserModelID() من الواضح أنه متوفر فقط في نظام التشغيل Windows 7:

  • قد تفعل ذلك من جانب Java عن طريق التحقق من ذلك System.getProperty("os.name"); عائدات "Windows 7".
  • إذا كنت تبني من مقتطف JNI الصغير الذي قدمته، فيمكنك تحسينه من خلال تحميل ديناميكيا shell32.dll مكتبة باستخدام LoadLibrary ثم العودة SetCurrentProcessExplicitAppUserModelID مؤشر وظيفة باستخدام GetProcAddress. وبعد إذا GetProcAddress عائدات NULL, ، وهذا يعني أن الرمز غير موجود في shell32 وبالتالي فإنه ليس ويندوز 7.

تعديل: حل JNA.

مراجع:

نصائح أخرى

هناك مكتبة Java توفر ميزات Windows 7 الجديدة ل Java. تسمى J7goodies. بواسطة كود strix. وبعد يمكن تثبيت التطبيقات التي تستخدمه بشكل صحيح على شريط مهام Windows 7. يمكنك أيضا إنشاء قوائم الانتقال الخاصة بك، إلخ.

حاول استخدام jsmooth.. وبعد أنا أستخدم دائما هذا واحد. في jsmooth هو هناك خيار تحت Skeleton بواسطة Windowed Wrapper مسمى

تطبيق Lauch Java في عملية EXE

انظر على هذه الصورة.

JSmooth

أيضا يمكن تمرير وسيطات سطر الأوامر.
أعتقد أن هذا قد يكون حلا لك.

martijn.

لقد نفذت الوصول إلى SetCurrentProcessExplictappusermodelid الطريقة باستخدام jna ويعمل بشكل جيد عند استخدام وثائق MSDN. لم أستخدم ابيا jna أبدا في الطريقة التي لديك في مقتطف التعليمات البرمجية الخاصة بك. تنفيذي يتبع jna النموذجي الاستعمال في حين أن.

أولا تعريف واجهة Shell32:

interface Shell32 extends StdCallLibrary {

    int SetCurrentProcessExplicitAppUserModelID( WString appID );

}

ثم استخدام JNA لتحميل Shell32 واستدعاء الوظيفة:

final Map<String, Object> WIN32API_OPTIONS = new HashMap<String, Object>() {
    {
       put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
       put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
    }
};
Shell32 shell32 = (Shell32) Native.loadLibrary("shell32", Shell32.class,
           WIN32API_OPTIONS);
WString wAppId = new WString( "Vendor.MyJavaApplication" );
shell32.SetCurrentProcessExplicitAppUserModelID( wAppId );

العديد من API في المقال الأخير التي ذكرتها تستخدم Windows COM والتي من الصعب استخدامها مباشرة مع JNA. لقد أجريت بعض النجاح في إنشاء DLL مخصص لاستدعاء واجهة برمجة التطبيقات هذه (على سبيل المثال، باستخدام shgetpropertystoreforwindow لتعيين معرف تطبيق مختلف للإطار المنطقي) الذي استخدمه ثم jna للوصول إلى وقت التشغيل.

SetCurrentProcessExplictAppusermodelid (أو setappid ()) سيكون في الواقع ما تحاول القيام به. ومع ذلك، قد يكون من الأسهل تعديل المثبت الخاص بك لتعيين الممتلكات Appusermodel.id على اختصارك - نقلا عن معرف نموذج طلب المستخدم الوثيقة المذكورة أعلاه:

في ال system.appusermodel.id. خاصية ملف اختصار التطبيق. يدعم اختصار (كإ Ishelllink أو CLSID_SHELLLININK أو ملف .LNK) الخصائص من خلال IPropertyStore وآليات أخرى لإعداد الممتلكات المستخدمة في جميع أنحاء القذيفة. يسمح ذلك بمكاميرا المهام بتحديد الاختصار المناسب لتعديل وتضمن أن Windows المملقين للعملية مرتبطة بشكل مناسب بزر "شريط المهام". ملاحظة: يجب تطبيق خاصية System.Appusermodel.ID على اختصار عند إنشاء هذا الاختصار. عند استخدام Microsoft Windows Installer (MSI) لتثبيت التطبيق، msishortcutproperty. يسمح الجدول بتطبيق Appusermodelid على الاختصار عند إنشاءه أثناء التثبيت.

الأخيرة jna-platform تحتوي المكتبة الآن على ارتباطات JNA ل SetCurrentProcessExplicitAppUserModelID:

https://github.com/java-native-access/jna/pull/680.

أنا ثابت الألغام دون أي إعدادات معرف. هناك خيار في Launch4J إذا كنت تستخدمه وأنت تقول إنك تفعل ذلك بعد ذلك ...

يمكنك تغيير الرأس إلى JNI واجهة المستخدم الرسومية ثم لفها حول الجرة مع JRE. الشيء الجيد هو أنه يعمل .EXE في العملية الآن بدلا من ذلك على تشغيل Javaw.exe مع جرة الخاص بك. ربما يفعل ذلك تحت غطاء محرك السيارة (غير متأكد). كما لاحظت أيضا أنه يستغرق حوالي 40-50٪ مورد وحدة المعالجة المركزية أقل وهو أفضل!

والضبط يعمل بشكل جيد وكل هذه ميزات النافذة ممكنة.

آمل أن يساعدها على شخص ما لأنني قضيت ما يقرب من يومين في محاولة لحل هذه المشكلة مع تطبيق Javafx غير المعروف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top