Runtime: دعم توزيع ملف واحد

تم إنشاؤها على ٥ أكتوبر ٢٠١٨  ·  225تعليقات  ·  مصدر: dotnet/runtime

تتعقب هذه المشكلة التقدم المحرز في ميزة توزيع ملف واحد .NET Core 3.0.
إليك مستند التصميم وخطة التدريج للميزة.

area-Single-File

التعليق الأكثر فائدة

من المتوقع أن تكون البداية الأولى أبطأ بكثير - فهي تستخرج التطبيق على القرص - الكثير من الإدخال / الإخراج.

كان من المفترض ألا يحدث هذا أبدًا ، فأنت تجعل تجربة المستخدم مروعة بالتصميم ، واختيارًا مروعًا ، وهذا هو ما تجعل المستخدمين يكرهون التكنولوجيا التي يستخدمها المطور لهم

كما ذكر من قبل Safirion ، نحن نعمل على التحسين التالي للملف الفردي والذي يجب أن يشغل معظم الكود المدار من. exe مباشرة (بدون استخراج إلى القرص). لا يمكن أن أعد قطار إطلاق حتى الآن.

لماذا يتم إصدار هذا رسميًا الآن إذا كان سيتغير قريبًا؟ يجب وضع علامة معاينة / تجريبية

في رأيي ، هذا مضيعة للوقت والموارد ، ركز على تجميع AOT وهز الأشجار ، ضع كل مواردك هناك ، توقف عن الاختراقات

ال 225 كومينتر

من باب الاهتمام ، كيف يمكن مقارنة هذه المبادرة مع CoreRT؟ يبدو أنها جهود مماثلة ؟

هل هو مرتبط بـ " رمز مستخدم أصلي محتمل " ، أي أنه سيظل يسمح بترجمة الشفرة بواسطة JIT ، وليس فقط AOT؟

أيضًا ، أفترض أن مكونات وقت التشغيل (" الكود الأصلي (وقت التشغيل ، المضيف ، الأجزاء الأصلية من إطار العمل .. ") ستكون من مكونات CoreCLR repo؟

أنت تطرح أسئلة رائعة ، ولكن نظرًا لأن هذا لا يزال مبكرًا في التصميم ، فليس لدي إجابات رائعة حتى الآن.

من باب الاهتمام ، كيف يمكن مقارنة هذه المبادرة مع CoreRT؟ يبدو أنها جهود مماثلة؟

من المحتمل أن تكون هناك نتائج متشابهة إلى حد ما (ملف واحد) ، ولكن قد يكون للتصميم خصائص أداء أو ميزات مختلفة تعمل / لا تعمل. على سبيل المثال ، يمكن أن يكون التصميم المحتمل هو تجميع كافة الملفات الموجودة في تطبيق .NET Core المستقل ذاتيًا في ملف واحد. هذه 10 ميجابايت وقد تبدأ بشكل أبطأ ، ولكن من ناحية أخرى ، ستسمح بالإمكانيات الكاملة لـ CoreCLR ، بما في ذلك تحميل المكونات الإضافية ، وانبعاث الانعكاس ، والتشخيصات المتقدمة. يمكن اعتبار CoreRT الطرف الآخر من الطيف - إنه ميغابايت من رقم واحد ولديه وقت بدء تشغيل سريع جدًا ، ولكن من خلال عدم وجود JIT ، لا يمكنه تحميل المكونات الإضافية أو استخدام انبعاث الانعكاس ويكون وقت الإنشاء أبطأ من معظم. NET devs معتادون على ملفات. يحتوي حاليًا على بعض القيود الأخرى التي يمكن أن تتحسن بمرور الوقت ، ولكنها قد لا تكون أفضل من خلال .NET Core 3.0 (ربما تتطلب التعليقات التوضيحية للانعكاس ، وتفقد بعض سيناريوهات التشغيل المتداخل ، والتشخيصات المحدودة على Linux). هناك أيضًا أفكار في مكان ما بين الاثنين. إذا كان لدى الأشخاص مقايضات يرغبون في إجرائها / تجنبها ، فسنكون فضوليين لمعرفة المزيد عنها.

هل هو مرتبط بـ "رمز مستخدم أصلي محتمل" ، أي أنه سيظل يسمح بترجمة الشفرة عبر JIT ، وليس فقط AOT؟

من خلال "رمز المستخدم الأصلي" ، كنت أعني أن تطبيقك قد يحتوي على بعض التعليمات البرمجية الأصلية لـ C ++ (إما مكتوبة بواسطتك أو بواسطة مكون تابع لجهة خارجية). قد تكون هناك حدود لما يمكننا القيام به باستخدام هذا الرمز - إذا تم تجميعه في ملف dll ، فإن الطريقة الوحيدة لتشغيله هي خارج القرص ؛ إذا كان ملف .lib ، فقد يكون من الممكن ربطه ، لكن هذا يؤدي إلى مضاعفات أخرى.

أيضًا ، أفترض أن مكونات وقت التشغيل ("الكود الأصلي (وقت التشغيل ، المضيف ، الأجزاء الأصلية من إطار العمل ..") ستكون من مكونات CoreCLR repo؟

بناءً على كل ما سبق ، سنكتشف أي اتفاقيات إعادة شراء متضمنة. تتضمن "الأجزاء الأصلية من إطار العمل" ملفات CoreFX الأصلية مثل ClrCompression و Unix PAL.

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

بعض السيناريوهات التي تهمنا. كيف سيعمل هذا من حيث المنصة المشتركة؟
أفترض أنه سيكون لدينا "ملف" منفصل لكل منصة؟

فيما يتعلق بالكود الأصلي ، كيف يمكنني اختيار مكونات أصلية مختلفة بناءً على النظام الأساسي؟

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

ayende ، أقتبس من تعليق morganbr :

قد يكون التصميم المحتمل هو تجميع كافة الملفات الموجودة في تطبيق .NET Core المستقل ذاتيًا في ملف واحد.

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

morganbr أقدر لك قضاء بعض الوقت في تقديم مثل هذه الإجابة التفصيلية

سأكون مهتمًا بمعرفة إلى أين يذهب التصميم ، فهذه مبادرة ممتعة حقًا

لدي بعض الأسئلة للأشخاص الذين يرغبون في استخدام ملف واحد. ستساعدنا إجاباتك في تضييق خياراتنا:

  1. ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)
  2. هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟
  3. هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟
  4. هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟
  5. هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟
  6. ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟
  7. هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟
  8. هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟
  1. تطبيق Console / UI على جميع الأنظمة الأساسية.
  2. ربما كعنصر طرف ثالث.
  3. ربما نعم.
  4. نعم ، خاصةً إذا كان هناك نظام بسيط يشبه ClickOnce.
  5. يمكن تحمل بعض التباطؤ الأولي. هل يمكن أن تساعد النقطة 3 في ذلك؟
  6. يعتمد على الأصول. يجب أن يكون حجم Hello world بترتيب ميغابايت.
  7. لا يهم إذا كان مجرد إنتاج.
  8. مثل إدراج أشياء انعكاس في القائمة البيضاء؟ نعم.

morganbr ، هل تعتقد أنه من الأفضل طرح هذه الأسئلة على جمهور أوسع ؛ على سبيل المثال ، على نطاق أوسع من الأشخاص الذين يعرفون عن مشكلة GitHub هذه؟

على سبيل المثال ، يمكن أن يكون التصميم المحتمل هو تجميع كافة الملفات الموجودة في تطبيق .NET Core المستقل ذاتيًا في ملف واحد.

النظر في ضغطها. أو باستخدام نظام ملفات مضغوط في الملف؟

tpetrina ، شكرا! تغطي النقطة 3 زوجًا من زوايا التصميم:

  1. لا يسير اهتزاز الشجرة جيدًا مع تحميل المكونات الإضافية التي لم يرها شاكر الشجرة لأنه قد يلغي الرمز الذي يعتمد عليه المكون الإضافي.
  2. ليس لدى CoreRT حاليًا طريقة لتحميل المكونات الإضافية
    النقطة 5 تدور حول ما إذا كنا سنحسن الحجم أو وقت بدء التشغيل (وكم)
    النقطة 8 ، نعم كنت أفكر في الغالب في أشياء انعكاس

TheBlueSky ، لقد اتصلنا بأشخاص آخرين أيضًا ، لكن من المفيد الحصول على مدخلات من الأشخاص المتحمسين في مجتمع GitHub.

benaadams ، الضغط على الطاولة ، لكنني أفكر حاليًا في أنه متعامد مع التصميم العام. تشير التجارب الخفيفة إلى أن الضغط قد يؤدي إلى تقليل الحجم بنسبة 50٪ تقريبًا بتكلفة عدة ثوانٍ من وقت بدء التشغيل (ووقت الإنشاء). بالنسبة لي ، هذه مقايضة جذرية بدرجة كافية ، إذا فعلناها ، يجب أن تكون اختيارية.

morganbr عدة ثوان من وقت بدء التشغيل عند استخدام الضغط؟ أجد صعوبة في تصديق ذلك عند التفكير في أن UPX تدعي سرعات إزالة الضغط

حوالي 10 ميجابايت / ثانية على Pentium 133 القديم ، حوالي 200 ميجابايت / ثانية على Athlon XP 2000+.

@ morganbr ، الإجابات بالنسبة لي هي:

1) الخدمة (تشغيل تطبيق وحدة التحكم Kestrel ، بشكل أساسي). يعمل كخدمة Windows / Linux Daemon أو في عامل إرساء.
2) نعم
3) نعم ، عادةً ما تتم إدارة التجميعات باستخدام AssemblyContext.LoadFrom . يتم توفيرها من قبل المستخدم النهائي.
4) نعم ، هذا متوقع. في الواقع ، لقد قمنا بالفعل بتجميع إطار العمل بأكمله على أي حال ، لذلك لا تغيير من هذا المنظور.
5) كخدمة ، لا نهتم كثيرًا بوقت بدء التشغيل. 5 ثوان ستكون معقولة.
6) 75 ميغا بايت هو على الأرجح الحد الأقصى. يعتمد الكثير على الحجم الفعلي المضغوط ، حيث يتم تسليم جميع العبوات مضغوطة.
7) بالنسبة إلى إصدارات الإصدارات ، تُقبل أوقات الإنشاء الأطول (حتى الأطول بكثير).
8) نعم بالتأكيد. الحجم لا يهم كثيرًا ، لكن الأصغر هو الأفضل.

شيء لم أراه مذكورًا وهو مهم جدًا هو قابلية تصحيح هذا الخطأ.
آمل ألا يؤدي هذا إلى إفساد آثار المكدس ، ونريد أن نكون قادرين على تضمين ملفات pdb أو نوعًا من رموز التصحيح.

فيما يتعلق بالضغط ، ضع في الاعتبار حقيقة أنه في جميع الحالات تقريبًا ، تكون آلية التسليم الفعلية مضغوطة بالفعل.
على سبيل المثال ، حزم nuget.
المستخدمون أيضًا على دراية جيدة بفك ضغط الأشياء ، لذلك لا يمثل ذلك مشكلة كبيرة.
أعتقد أنه يمكنك الضغط على الجانب.

شكراayende! أنت محق في أنني كان يجب أن أستدعي قابلية التصحيح. أعتقد أنه لا يوجد سوى عدد قليل من الطرق البسيطة التي يمكن أن يتأثر بها تصحيح الأخطاء:

  1. قد لا يكون من الممكن استخدام التحرير والمتابعة في ملف واحد (بسبب الحاجة إلى طريقة لإعادة إنشاء التجميع الأصلي وإعادة تحميله)
  2. قد ينتج عن إنشاء الملف الفردي PDB أو بعض الملفات الأخرى المطلوبة للتصحيح بخلاف تلك التي تأتي مع التجميعات الخاصة بك.
  3. إذا تم استخدام CoreRT ، فقد يحتوي على بعض ميزات التصحيح التي يتم ملؤها بمرور الوقت (خاصة في Linux / Mac).

عندما تقول "تضمين ملفات pdb" ، هل تريد تلك _داخل_ الملف الفردي أو مجرد القدرة على إنشائها والتشبث بها في حال احتجت إلى تصحيح أخطاء إنشاء الملف الفردي؟

1) ليست مشكلة بالنسبة لنا. E&C غير مناسب هنا لأنه من المحتمل أن يتم استخدامه فقط للنشر الفعلي ، وليس يومًا بعد يوم.
2) من الناحية المثالية ، لدينا ملف واحد لكل شيء ، بما في ذلك PDBs ، وليس ملفًا واحدًا ومجموعة من pdbs على الجانب. يوجد بالفعل خيار PDB المضمن ، إذا نجح ذلك ، فسيكون رائعًا.
3) عندما أتحدث عن التصحيح ، أنا أتحدث أكثر عن وقت الإنتاج بدلاً من إرفاق المصحح مباشرة. وبشكل أكثر تحديدًا ، قم بتكديس معلومات التتبع بما في ذلك أرقام الملفات والأسطر ، والقدرة على حل الرموز عند قراءة التفريغ ، وما إلى ذلك.

  1. الخدمات بشكل رئيسي ولكن بعض واجهة المستخدم
  2. البعض يفعل ، لكن هذا لن يكون عاجلاً
  3. نعم
  4. نعم
  5. بضع ثوانٍ على ما يرام
  6. لا يهمنا. مجموع حجم dll جيد
  7. من الناحية المثالية لا
  8. الحجم ليس من الأهمية الأساسية بالنسبة لنا

سؤال آخر بالنسبة لنا هو ما إذا كنت قادرًا على القيام بذلك للمكونات الفردية أيضًا (ربما حتى على مراحل)؟ على سبيل المثال ، لدينا مكتبة dlls تستخدم الكثير من التبعيات. إذا تمكنا من حزم هذه الأشياء ، فسيوفر الكثير من آلام إدارة الإصدار وما إلى ذلك.

  1. الخدمات وبعض واجهة المستخدم.
  2. ليس الان.
  3. نعم. من الناحية المثالية ، يمكن تحميل المكونات الإضافية من مجلد وإعادة تحميلها في وقت التشغيل.
  4. نعم
  5. ليست مشكلة طالما أننا لا ندفع 10-15 +.
  6. مجموع حجم DLL ، أو ما شابه.
  7. نعم. بالنسبة إلى وقت إنشاء الإنتاج ، لا يمثل حقًا مشكلة طالما أن إنشاءات التصحيح / الاختبار تكون سريعة بشكل معقول.
  8. يعتمد ، لكن الخيار سيكون في متناول اليد.
  1. الخدمة وواجهة المستخدم.
  2. بعض الأحيان.
  3. نعم عادة.
  4. نعم.
  5. من الأفضل أن تكون أقل من 5 ثوانٍ.
  6. مدة واجهة المستخدم أقل من 5 ثوانٍ ، الخدمة غير مهمة.
  7. وقت الإنشاء ليس مهمًا ، وتأثير التحسين هو الأكثر أهمية.
  8. نعم.

tpetrinaayendebencyoungKosyneexpcat لقد أجبت بنعم على السؤال 3 ("هل سيحمل تطبيقك المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في إنشاء تطبيقك؟") - هل يمكنك إخبارنا بالمزيد عن استخدامك قضية؟

تتمثل نقطة البيع الرئيسية لتوزيع ملف واحد في وجود ملف واحد فقط للتوزيع. إذا كان تطبيقك يحتوي على مكونات إضافية في ملفات منفصلة ، فما القيمة التي ستحصل عليها من توزيع ملف واحد يحتوي على ملفات متعددة على أي حال؟ لماذا يعتبر "app.exe + plugin1.dll + plugin2.dll" أفضل من "app.exe + coreclr.dll + clrjit.dll + ... + plugin1.dll + plugin2.dll"؟

app.exe + 300+ dlls - وهو الوضع الحالي اليوم محرج حقًا.
app.exe + 1-5 dlls التي عادة ما يتم تحديدها من قبل المستخدم نفسه أسهل بكثير.

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

لم نكن نخطط للقيام بذلك ، لكننا نريد أن نكون قادرين على القيام بذلك إذا دعت الحاجة.

ayende موافق ، نفس الشيء معنا.

أيضًا ، إذا تمكنا من ذلك على مستوى dll ، فيمكننا حزم التبعيات داخل تجميعاتنا حتى لا تتعارض مع تجميعات العميل. أي عن طريق اختيار إصدار من NewtonSoft ، فأنت تقوم حاليًا بتعريفه لجميع البرامج والمكونات الإضافية وتجميعات الجهات الخارجية في نفس المجلد ، ولكن إذا كان بإمكانك تضمينه ، فإن الجهات الخارجية تتمتع بالمرونة وتزيد من توافق الإصدار

أتفق مع ayende .

شكرا للجميع على إجاباتك! استنادًا إلى عدد الأشخاص الذين سيستخدمون رمزًا أصليًا أو يحتاجون إلى تحميل المكونات الإضافية ، نعتقد أن النهج الأكثر توافقًا الذي يمكننا إدارته هو المكان المناسب للبدء. للقيام بذلك ، سوف نتبع نهج "حزمة واستخراج".

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

إن أصعب تفاصيل هذه الخطة هو مكان استخراج الملفات إليه. نحتاج إلى حساب عدة سيناريوهات:

  • أول تشغيل - يحتاج التطبيق فقط إلى الاستخراج إلى مكان ما على القرص
  • عمليات الإطلاق اللاحقة - لتجنب دفع تكلفة الاستخراج (من المحتمل عدة ثوانٍ) عند كل عملية إطلاق ، سيكون من الأفضل أن يكون موقع الاستخراج محددًا والسماح للإطلاق الثاني باستخدام الملفات المستخرجة عند الإطلاق الأول.
  • الترقية - إذا تم تشغيل إصدار جديد من التطبيق ، فلا ينبغي أن يستخدم الملفات المستخرجة بواسطة إصدار قديم. (والعكس صحيح أيضًا ؛ قد يرغب الأشخاص في تشغيل إصدارات متعددة جنبًا إلى جنب). يشير ذلك إلى أن المسار الحتمي يجب أن يعتمد على محتويات التطبيق.
  • إلغاء التثبيت - يجب أن يتمكن المستخدمون من العثور على الأدلة المستخرجة لحذفها إذا رغبت في ذلك.
  • تحمل الخطأ - إذا فشل الإطلاق الأول بعد الاستخراج الجزئي لمحتوياته ، فيجب أن يعيد التشغيل الثاني عملية الاستخراج
  • التشغيل على مستوى عالٍ - يجب تشغيل العمليات كمسؤول فقط من مواقع قابلة للكتابة من قِبل المسؤول لمنع العمليات منخفضة التكامل من العبث بها.
  • تشغيل غير مرتفع - يجب تشغيل العمليات بدون امتيازات المسؤول من مواقع يمكن للمستخدم الكتابة عليها

أعتقد أنه يمكننا حساب كل هؤلاء من خلال إنشاء مسار يتضمن:

  1. دليل أساسي معروف جيدًا (مثل٪ LOCALAPPDATA٪ \ dotnetApps على Windows ومواقع ملف تعريف المستخدم على أنظمة تشغيل أخرى)
  2. دليل فرعي منفصل لملف مرتفع
  3. هوية التطبيق (ربما اسم exe فقط)
  4. معرّف الإصدار. من المحتمل أن يكون إصدار الرقم مفيدًا ، ولكنه غير كاف لأنه يحتاج أيضًا إلى دمج إصدارات التبعية الدقيقة. قد يكون دليل أو تجزئة لكل بناء مناسبًا.

معًا ، قد يبدو هذا شيئًا مثل c: \ users \ username \ AppData \ Local \ dotnetApps \ elevated \ MyCoolApp \ 1.0.0.0_abc123 \ MyCoolApp.dll
(حيث يُطلق على التطبيق اسم MyCoolApp ، يكون رقم إصداره هو 1.0.0.0 وعلامة التجزئة / الدليل الخاص به هو abc123 وقد تم تشغيله بشكل مرتفع).

سيكون هناك أيضًا عمل مطلوب لتضمين الملفات في المستخرج. في نظام Windows ، يمكننا ببساطة استخدام الموارد الأصلية ، ولكن قد يحتاج Linux و Mac إلى عمل مخصص.

أخيرًا ، قد يحتاج هذا أيضًا إلى تعديلات في المضيف (للعثور على الملفات المستخرجة) والتشخيصات (للعثور على DAC أو ملفات أخرى).

CC @ swaroop- sridharjeffschwMSFT @ vitek-karas

أشعر أن هذا العلاج أسوأ من المرض. إذا كان علينا التعامل مع الدلائل الخارجية (المختلفة عبر أنظمة التشغيل) ، والتحديث ، وإلغاء التثبيت وما شابه ، فهذا يتعارض مع سبب رغبتي في هذه الميزة في المقام الأول (الحفاظ على كل شيء بسيطًا ومحمولًا ومكتفيًا ونظيفًا).

إذا كان يجب أن يكون الأمر كذلك تمامًا ، بالنسبة لمشروعي ، فإنني أفضل كثيرًا ملف تنفيذي رئيسي واحد والملفات التي تم فك حزمها لتعيش في دليل بجانب ذلك الملف القابل للتنفيذ ، أو ربما القدرة على تحديد المكان الذي يذهب إليه هذا الدليل.

هذا أنا فقط على الرغم من أنني أشعر بالفضول لسماع آراء الآخرين أيضًا.

يجب أن أوافق هنا ، يمكن أن يؤدي استخدام دليل مختلف إلى العديد من المشكلات المثيرة - على سبيل المثال ، إذا قمت بوضع ملف التكوين بجانب exe ولا يتم التقاط هذا exe لأن الدليل "الحقيقي" موجود في مكان آخر.
قد تكون مساحة القرص مشكلة ، وكذلك أقفال الملفات العشوائية بسبب سياسات الوصول وما إلى ذلك ص.
أرغب في استخدام هذه الميزة ، ولكن ليس إذا أضافت مجموعة من أوضاع الفايل التي كان من المستحيل اكتشافها من قبل.

متفق عليه مع Kosyne - يبدو أن الحل الأولي المقترح يعمل ببساطة على أتمتة "المثبت" من نوع ما. إذا كان هذا هو الحد الأقصى للمشكلة التي نحاول حلها مع مدير تنفيذي واحد ، فأعتقد أننا سنقوم جميعًا ببساطة بتنفيذ هذه الأتمتة بأنفسنا.

يجب أن يكون الهدف الرئيسي لاقتراح exec الفردي أن تكون قادرًا على تشغيل ملف تنفيذي على نظام غير مُدار. من يدري ما إذا كان لديه حق الوصول للكتابة إلى أي دليل "تثبيت" وجهة مختار؟ ومن المؤكد أنه لا ينبغي أن يترك آثارًا خاصة به بعد الإطلاق (وليس بشكل افتراضي).

كتعديل بسيط على الاقتراح الحالي لتلبية ما ورد أعلاه: ألا يمكننا فك الضغط في الذاكرة والركض من هناك؟

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

موقع الملف مهم. على سبيل المثال ، في حالتنا ، قد يعني ذلك:

  • العثور على ملف التكوين (الذي نقوم بإنشائه بسرعة إن لم يكن موجودًا والسماح للمستخدم بالتخصيص)
  • البحث عن / إنشاء ملفات البيانات ، والتي عادة ما تكون مرتبطة بـ exe المصدر.
  • يجب أن يتطابق PID / اسم العملية ، لضمان المراقبة / الدعم المناسب.

يحتاج أحد مستخدمينا إلى تشغيل برنامجنا من قرص DVD ، كيف يعمل ذلك ، على نظام قد لا يحتوي في الواقع على قرص HD للتشغيل.

أوافق على أنه من الأفضل عمل كل شيء في الذاكرة. والقلق بشأن وقت بدء التشغيل ليس بهذه الضخامة ، وسأكون بخير دفع هذا مقابل كل إعادة تشغيل ، أو القيام بخطوة يدويًا للتخفيف من ذلك إذا لزم الأمر.

مشكلة أخرى هنا هي الحجم الفعلي. إذا كان هذا مجرد مثبت (فعال) ، فهذا يعني أننا نتحدث عن أحجام ملفات لتطبيق معقول في 100 ميجابايت ، أليس كذلك؟

يبدو أن بناء الحل المقترح لا يتطلب (العديد من التغييرات في CLR). يمكن للمستخدمين بالفعل بناء حل من هذا القبيل. ليس هناك فائدة من إضافة هذا إلى CoreCLR. خاصة ، لأن حالة الاستخدام لهذا ضيقة ومحددة إلى حد ما.

GSPP يبدو هذا في الأساس شيئًا يمكنني القيام به اليوم باستخدام 7z-Extra ، أوافق على أنه إذا كان هذا هو الحال ، فسيكون من الأفضل عدم امتلاكه على الإطلاق.

آسف لقد تأخرت في هذا الحفل ، لقد وصلت إلى هنا بعد اتباع رابط تم نشره في تذكرة مكررة كنت أتتبعها.
بعد قراءة أحدث التعليقات هنا ، يؤسفني أن أرى أنك تفكر في التعبئة والاستخراج. يبدو هذا وكأنه مبالغة ، فلماذا لا تبدأ بالقدرة على نشر SFA لتطبيقات وحدة التحكم الأساسية؟ يبدو لي أنه ينبغي أن يكون من الممكن إنشاء تطبيق وحدة تحكم بدائية مع بعض الشبكات ، و IO ، وبعض التبعيات الخارجية (nuget ، إلخ) الموجودة في ملف واحد.
أعتقد أن ما أحاول قوله هو أنه بدلاً من جمع متطلبات الجميع ، اجمع متطلبات لا أحد وبدلاً من ذلك ابدأ صغيرًا بتكرار أول يكون منطقيًا للجميع ويعطي نتائج سريعة.

يبدو هذا كشيء يمكنني القيام به اليوم باستخدام 7z-Extra

أنت محق في أن عدد الحلول الحيادية لبيئة البرمجة لمعالجة هذه المشكلة موجود اليوم. مثال آخر من بين العديد من الأمثلة: https://www.boxedapp.com/exe_bundle.html

ستكون القيمة المضافة هنا هي التكامل في أدوات dotnet بحيث يمكن للمستخدمين غير الخبراء القيام بذلك بسهولة. يمكن للمستخدمين الخبراء القيام بذلك اليوم من خلال دمج الأدوات الموجودة معًا كما أشرت.

أنا شخصياً أتفق معك في أنه ليس من الواضح أننا نتخذ القرار الصحيح هنا. كان لدينا الكثير من النقاش حول هذا داخل الفريق الأساسي.

إن وضع متدرب عليها والخروج بأداة عالمية (موصى بها ، ولكنها غير مدعومة) من شأنه أن يكون جيدًا أيضًا ، ويمكن أن يكون التثبيت سهلًا إلى حد ما أيضًا.

على نحو فعال ، نحن نتحدث عن dotnet publish-single-file وهذا من شأنه أن يفعل كل ما هو مطلوب وراء الكواليس.

لا أرى أي شيء مطلوب فعليًا بواسطة إطار العمل أو وقت التشغيل لدعم هذا السيناريو ، ومن خلال جعل هذا الشيء خارج إطار العمل بشكل صريح ، فإنك ستسمح للمستخدمين بمزيد من الحرية حول كيفية تعديل هذا.
لا توجد "حاجة" للحصول على العلاقات العامة (مع كل الحفل المرتبط ، والاتفاق الخلفي ، والأمن ، وما إلى ذلك) التي قد تحصل عليها إذا كنت ترغب في إجراء تغيير على إطار العمل.
أنت مجرد تفرع من مشروع جانبي مشترك واستخدامه.

لاحظ أنه بقدر ما أرغب في هذه الميزة ، فأنا أفضل عدم وجود شيء ما (مما يعني أنه سيكون دائمًا موجودًا) يمكن القيام به أيضًا من الخارج.

أريد أن أطرح سؤالاً أعلى مستوى: ما هو الدافع الرئيسي للعملاء الراغبين في توزيع ملف واحد؟
هل هي بالدرجة الأولى:

  1. تغليف؟ إذا كان الأمر كذلك ، بغض النظر عما إذا كان الحل هو صندوق بريد أو أداة طرف ثالث ، ما هي الخصائص الأكثر أهمية؟
    أ) وقت بدء التشغيل (بعد التشغيل الأول)
    ب) القدرة على التشغيل في بيئات غير قابلة للكتابة
    ج) عدم ترك الملفات ورائها بعد التشغيل
    د) عدم الاضطرار إلى تشغيل المثبت
    2) الأداء؟
    أ) السرعة (الربط الثابت للرمز الأصلي ، وتجنب الأحمال المتعددة للمكتبة ، والتحسينات عبر الوحدات النمطية ، وما إلى ذلك)
    ب) حجم الكود (تحتاج إلى شهادة واحدة فقط ، هز الشجرة ، إلخ)
    3) أي أخرى؟

أنا قلق بعض الشيء من أن هذه الميزة يقرأها البعض على أنها ليست مهمة جدًا ، أو على الأقل قد لا تكون هدفًا جيدًا لتضمينها في مجموعة الميزات الأساسية هنا. أود فقط أن أكرر أنني أعتقد أنه سيكون قويًا للغاية لأي تطبيق يعمل كخدمة أو وحدة فرعية لتطبيق أكبر. واحد قد لا تكون أنت ، المؤلف ، مطورًا له. لا أريد أن أضطر إلى تمرير متطلبات التبعية التي لا يمكن حلها إلا من خلال التثبيتات (تلقائية أو غير ذلك) ، أو أخطاء ما بعد التنفيذ على القرص التي قد تحتاج إلى زيادة أمان إضافية من قبل المستخدم ، وما إلى ذلك.
في الوقت الحالي ، لا يعد .NET اختيارًا جيدًا لهذه المشكلة المتخصصة. ولكن يمكن أن يكون (ويجب أن يكون IMO).

يجب أن يكون الملف القابل للتنفيذ المترجم:

  • حزم جميع التبعيات ذات الصلة
  • لا تحتوي على أخطاء تنفيذية (لا يوجد قرص يكتب)

Re @ swaroop-sridhar أجرؤ على القول بأن كل تطبيق سيكون له ترتيب فريد خاص به لاحتياجات الأداء ولذا أتخيل أن أفضل نهج بعد معالجة الحل الأساسي هو اختيار الفاكهة المعلقة المنخفضة والانطلاق من هناك.

@ swaroop-sridhar بالنسبة لي ، يتعلق الأمر بالتغليف وسهولة الاستخدام للمستخدم النهائي.
لا حاجة للتعامل مع تثبيت أشياء على مستوى النظام ، ما عليك سوى النقر والتشغيل.

هذا مهم لأننا نسمح بتضمين برنامجنا ، كما أن إدارة ملحق ملف واحد أسهل كثيرًا.

strich النقطة المتعلقة بالتضمين فكرة جيدة. يتم استخدامنا بشكل شائع كمكون في بنية الخدمة المصغرة ، وسيؤدي تقليل عبء النشر إلى تسهيل ذلك.

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

لأكون صادقًا ، أفضل رؤية خيار أفضل تمامًا. على سبيل المثال ، من الممكن تحميل ملفات dll من الذاكرة ، بدلاً من الملفات (تتطلب بعض العمل ، لكن ممكن).
إذا حدث ذلك ، يمكنك تشغيل الشيء _entire_ فقط من الذاكرة ، مع إجراء التفريغ على ذاكرة خالصة وبدون نقرات على القرص.

هذا شيء يجب أن يدخل في جوهره ، لأنه سيتطلب على الأرجح تعديلات على وقت التشغيل لتمكين ذلك.
وسيكون ذلك ذا قيمة في حد ذاته وخارجها. وليس شيئًا يمكننا فعله حاليًا.

لذلك فإن أحد الأمثلة الجيدة هو إلقاء نظرة على تجربة أدوات Go مثل Hashicorp's Consul. ملف exe واحد يمكنك إسقاطه على أي جهاز أثناء التشغيل. لا توجد برامج تثبيت ، ولا نسخ مجلدات حولها ، ولا تبحث عن ملفات التكوين في قوائم مئات الملفات ، إنها تجربة مستخدم نهائية رائعة حقًا.

بالنسبة إلينا ، لست متأكدًا من أن النهج الموجود في الذاكرة سيعمل لأننا نرغب أيضًا في أن يعمل هذا مع ملفات dlls الإضافية أيضًا (لذا فإن إسقاط المكون الإضافي سيكون أيضًا ملفًا واحدًا بدلاً من كل تبعياته) ، ولكن أي تقدم سيكون كن جيد. لقد ألقينا نظرة على Fody.Costura وهو يعمل جيدًا مع بعض الأشياء ولكن لدينا مشكلات مع .NET Core لذلك.

لذلك فإن أحد الأمثلة الجيدة هو إلقاء نظرة على تجربة أدوات Go مثل Hashicorp's Consul

إيه ، بالنسبة لأدوات مثل القنصل ، فإن الحل المثالي سيكون ضارًا ، وليس ارتجالًا مستخرجًا ذاتيًا.

mikedn لماذا هذا؟ لا أرى ما علاقة تجميع AOT أو JIT بطريقة النشر؟

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

لماذا هذا؟ لا أرى ما علاقة تجميع AOT أو JIT بطريقة النشر؟

لأنه يمنحك ما تريده بالضبط - ملف exe واحد يمكنك إسقاطه على أي جهاز (حسنًا ، أي جهاز به نظام تشغيل مناسب ، إنه ملف أصلي بعد كل شيء) وتشغيله. كما أنه يميل إلى استخدام موارد أقل ، وهو أمر جيد بالنسبة لوكلاء مثل القنصل. إنه يعادل إلى حد كبير ما يقدمه لك Go ، أكثر من مجرد حل استخراج ذاتي.

mikedn أعتقد ، لكن

1) لم يكن موجودًا بالفعل في شكل إنتاج (على حد علمي)!
2) نستخدم الكثير من الميزات الديناميكية (جيل IL ، انعكاس عشوائي)
3) ما زلنا نريد أن نتمكن من إضافة مكونات إضافية (مضغوطة بشكل مثالي مرة أخرى)

انظر لأن هذه المشكلة كانت تتعلق بسؤال الأشخاص عما يريدون ، فنحن نعطي رأينا فقط! لا نريد حقًا التبديل إلى نموذج وقت تشغيل مختلف فقط للحصول على هذه الميزة. بالنسبة لي ، إنها مخاوف متعامدة

لا أرى ما علاقة تجميع AOT أو JIT بطريقة النشر؟

بدون JIT ، من الأسهل الحصول على أشياء مثل قصة تصحيح الأخطاء بشكل جيد بما فيه الكفاية. جزء JIT يجعل المشكلة أصعب ولهذا لن تجدها في Go. هذه هندسة ، لذلك إما أن تلقي بالمزيد من المهندسين على المشكلة الأصعب وتتعايش مع التعقيد الجديد ، أو تضع نطاقًا في مكان آخر. يدور المستخرج الذاتي حول تحديد نطاقه لأن عدد المهندسين ذوي المهارات اللازمة محدود.

قد يكون الأشخاص الذين لديهم مشروعات تشبه مشروعات Go (لا توجد متطلبات JIT) سعداء جدًا باستخدام CoreRT ، إذا كانوا جيدًا مع التسمية "التجريبية" الموجودة عليها. من السهل جدًا أن تجرب هذه الأيام. يستخدم نفس مجمع القمامة ، ومولد الكود ، و CoreFX ، ومعظم CoreLib مثل CoreCLR الكامل ، وينتج ملفات تنفيذية صغيرة الحجم (ذات رقم واحد ميغا بايت) قائمة بذاتها.

إنه غير موجود بالفعل في شكل إنتاج (على حد علمي)!

نعم ، كان تعليقي موجهًا في الغالب إلى مرضى التصلب العصبي المتعدد: ابتسامة : . لديهم كل هذه المشاريع / الأفكار المتوازية والمترابطة والمستمرة (corert ، illinker) والآن يضيفون واحدًا آخر ، هذا الشيء المستخرج الذاتي ، كما أشار الكثيرون بالفعل ، إنه نوع من "meh ، يمكننا فعل ذلك أنفسنا "نوعًا ما. ويأتي مع سلبيات أيضًا ، مثل استخراج الملفات إلى دليل "مخفي".

نستخدم الكثير من الميزات الديناميكية (جيل IL ، انعكاس عشوائي)

هذا شيء قد يرغب المجتمع ككل في التفكير فيه مرة أخرى. من المؤكد أنه من المفيد أن تكون قادرًا على القيام بذلك ولكنه نوع من التعارض مع الرغبات الأخرى مثل نشر ملف واحد. لا يزال بإمكانك الحصول على نشر ملف واحد ولكن هذا يأتي بتكلفة - ملف كبير نوعًا ما. إذا كنت موافقًا على ذلك ، فهذا جيد تمامًا. ولكن من واقع خبرتي ، كلما زاد حجم الملف ، كلما أصبح جانب "الملف الفردي" أقل فائدة.

MichalStrehovsky بالتأكيد ، هناك خيارات مختلفة. ومع ذلك ، لا يمكننا استخدام التجربة (كان الوقت المقنع للانتقال إلى .NET Core صعبًا بدرجة كافية) ولا أعتقد أن الاستخراج إلى مجلد مؤقت سيعمل في حالتنا أيضًا. ومع ذلك ، فإن أسوأ الحالات هي أننا نواصل العمل كما نحن ولا نستخدم هذه الميزة.

إنه شيء نود على الرغم من أنه سار بالطريقة التي نريدها :)

mikedn أوافق. تعد الحلول المتوازية المتعددة أكثر إرباكًا. أعتقد أن حلنا المثالي سيكون نوعًا من نهج ILLinker / Weaver الفائق ، لكنني سعيد بترك هذا الأمر يحدث وأرى إلى أين ننتهي.

أنا متحمس حقًا بشأن هذه الوظيفة ، لكن TBH أنا غير متحمس أيضًا بشأن الاقتراح الأولي الذي نشرته @ morganbr. تتشابه إجاباتي على قائمة الأسئلة التي طرحتها مع ما نشره الآخرون (لذلك أعتقد أن هناك مجموعة مشتركة مطلوبة من القدرات) ، لكن IMHO الحل المقترح لـ "فك الضغط إلى القرص" ليس على الإطلاق ما أتمنى رؤيته نفذت وكما قال آخرون سيكون أسوأ من "المرض". تضمين التغريدة

أتفق مع strich وayende
يجب أن يكون الملف القابل للتنفيذ المترجم:
حزم جميع التبعيات ذات الصلة
لا تحتوي على عناصر تنفيذية (لا يوجد قرص يكتب)

قد لا يكون تحميل ملفات dll. من الذاكرة بدلاً من القرص أمرًا سهلاً ، ولكن هذا هو نوع القدرات التي تستحقها IMO الخبرة العميقة لمطوري MSFT ذوي المستوى المنخفض (ومن ثم الاستفادة في CoreClr) مقابل الاقتراح أعلاه الذي يمكن تنفيذه فقط على أنه أداة خارجية (ولديها بالفعل ، راجع https://github.com/dgiagio/warp). إذا تم تحقيق ذلك ، أتساءل كم سيكون الفارق الزمني بين التشغيل الأول والتشغيل اللاحق؟ للإلهام / على سبيل المثال ، أعتقد أن Linux 3.17+ به memfd_create والذي يمكن استخدامه بواسطة dlopen.

في موضوع آخر ، أتساءل عما إذا كانت متطلبات دعم المكونات الإضافية تزيد من فهرسة اقتراح التصميم؟ هل يستحق تفعيل هذه الوظيفة ، بحيث لا يتحمل سوى الأشخاص الذين يحتاجون إلى هذه الإمكانية العقوبات المحتملة (عدم اهتزاز الأشجار وما إلى ذلك) وأي شخص آخر (الأغلبية الكبيرة؟) سيقلل حجم النشر ، وفوائد الأداء (؟)

بالرجوع إلى الوراء @ swaroop- sridharMichalStrehovsky ، أستطيع أن أرى حالتين واسعتي الاستخدام قد يكون لهما أهداف / رغبات مختلفة بما يكفي لجعل من الصعب استيعاب الجميع بحل واحد:

  • تريد أدوات CLI بشكل مثالي التشغيل السريع في كل مرة ، وقابلة للتوزيع صغيرة ؛ ربما يكون مناسبا لـ CoreRT؟
  • يمكن للخدمة المصغرة أن تتسامح على الأرجح مع التشغيل الأول الأطول (من الناحية المثالية أقل من 1 ثانية) ، والقابل للتوزيع الأكبر ، في مقابل وظائف أكثر ثراءً مثل ميزات JIT والتعليمات البرمجية الديناميكية.

آمل أن يكون هذا التفريغ العقلي منطقيًا إلى حد ما ، فأنا لا أحاول أن أكون مغفلًا ، ولكن فقط أقدم ملاحظات لأنني مهتم جدًا بهذا الموضوع. نشكرك على عملك الشاق ، والتماس مساهمات المجتمع! :)

حول الإضافات.
في الأساس ، الشيء الوحيد الذي أرغب فيه هو _ لا _ أن يتم حظره على مكالمات Assembly.LoadFrom أو LoadLibrary .
لست بحاجة إلى أي شيء آخر ويمكنني أن أفعل الباقي بمفردي.

ayende هل يمكنك أن تشرح بمزيد من التفصيل ما الذي تقصده بعبارة "تم حظره على LoadFrom وما شابه ذلك"؟

على سبيل المثال ، تضمنت بعض الاقتراحات الخاصة بهذا الأمر CoreRT ، مما يعني أننا (على الأرجح) لن نكون قادرين على تحميل ملف dll مُدار.
ولكن طالما يمكنني توفير مسار إلى ملف dll مُدار والحصول على تجميع أو الاتصال بـ LoadLibrary على ملف dll أصلي ، فأنا على ما يرام مع كونه آلية البرنامج المساعد.

أنا أقول هذا لأوضح أن سيناريوهات البرنامج المساعد ليست شيئًا يجب أن يؤخذ بعين الاعتبار ، بل هو شيء لا يجب حظره.

قضيت بعض الوقت في البحث في الكود ، وللوهلة الأولى ، يبدو أنه من الممكن (التحدث عن Windows فقط لتبسيط الأمور):

  • قم بتجميع CoreCLR بأكمله في exec (دعنا نقول أنه كمورد مضمن أو شيء من هذا القبيل).
  • قم بتعداد ملفات dll الأصلية ، واستدع شيئًا مثل MemoryModule (https://github.com/fancycode/MemoryModule) لتحميلها في الذاكرة
  • استدعاء وقت التشغيل وتحميل تجميع من الذاكرة.

سأفترض أن هذا _ليس بهذه البساطة. على سبيل المثال ، لا يوفر ICLRRuntimeHost2::ExecuteAssembly أي طريقة لمنحه مخزنًا مؤقتًا ، فقط ملف على القرص.
هذا يجعلها أول (مما أنا متأكد من أنه سيكون كثيرًا) تظهر سدادة لجعلها تعمل بالفعل.

أنا متأكد تمامًا من وجود الكثير من التعليمات البرمجية التي قد تشير إلى الأشياء ذات الصلة كملفات قد تفشل ، ولكن هذا هو نوع الأشياء التي أعنيها عندما أقول إنني أريد ملفًا واحدًا exec ولماذا هذا النوع من يجب تنفيذ الحل في CoreCLR وليس خارجيًا (كما في المثال المضغوط).

استدعاء شيء مثل MemoryModule

الثنائيات التي تم تحميلها باستخدام MemoryModule غير قابلة للتشخيص (على سبيل المثال ، لن تعمل أي من مصححات الأخطاء العادية أو ملفات التعريف وما إلى ذلك) ، وتتخطى MemoryModule جميع إجراءات الأمان المضمنة في نظام التشغيل (مثل مضادات الفيروسات وما إلى ذلك). إنه ليس شيئًا يمكننا شحنه كحل مدعوم.

سأفترض أن هذا ليس بهذه البساطة.

حسنًا ، ستكون هناك حاجة إلى واجهات برمجة تطبيقات جديدة (مُدارة وغير مُدارة) لدعم التنفيذ من حزمة ملفات فردية غير موسعة. البرامج والمكتبات الحالية لن "تعمل فقط".

هل يمكن أن يكون طلبًا معقولًا لواجهة فحص مكافحة البرامج الضارة
تم تنفيذه بواسطة مهندسي Windows على MemoryModule مثلما تم تنفيذه مؤخرًا من أجل
كل. net التجميعات بما في ذلك تلك المحملة من mem؟

https://twitter.com/WDSecurity/status/1047380732031762432؟s=19

تحرير: بدت Hmm MemoryModule وكأنها شيء مضمن في نظام التشغيل لتحميل الوحدات الأصلية ولكن يبدو أنه ليس كذلك ، ربما يكون هذا سببًا كافيًا لتجاهل اقتراحي أعلاه

في الأربعاء ، 5 ديسمبر 2018 ، 01:46 كتب Jan Kotas [email protected] :

استدعاء شيء مثل MemoryModule

الثنائيات التي تم تحميلها باستخدام MemoryModule غير قابلة للتشخيص (على سبيل المثال لا شيء من
ستعمل عليها مصححات الأخطاء العادية ، ومصفحات التعريف ، وما إلى ذلك) ، و MemoryModule
يتخطى جميع الإجراءات الأمنية لأنظمة التشغيل المبنية (مثل برامج مكافحة الفيروسات وما إلى ذلك). ليس
شيء يمكننا شحنه كحل مدعوم.

سأفترض أن هذا ليس بهذه البساطة.

حسنًا ، ستكون هناك حاجة إلى واجهات برمجة تطبيقات جديدة (مُدارة وغير مُدارة)
دعم التنفيذ من حزمة ملفات فردية غير موسعة. الموجود
البرامج والمكتبات لن "تعمل فقط".

-
أنت تتلقى هذا لأنك مشترك في هذا الموضوع.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/dotnet/coreclr/issues/20287#issuecomment-444314969 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AEBfudvVHxpbeKa-L_vTQjbnNZZsn6Meks5u1xdlgaJpZM4XK-X_
.

شكرا لكل الردود.
سننشر خطة محدثة لدعم توزيع الملف الفردي قريبًا.

NinoFloris انظر dotnet / coreclr # 21370

أدرك أنني تأخرت في هذه المناقشة ، لذا اعتذاري إذا لم يساعد ذلك.

لتكرار ما قاله mikedn ، قد يكون من المربك الحصول على كل هذه الحلول المتوازية ، وهذا يطرح السؤال عن مكان تركيز MS في المستقبل. حقيقة أن العمل الرائع الذي تم إنجازه على CoreRT لا يزال يُوصف بأنه تجريبي بدون خريطة طريق رسمية وبوظائف مماثلة يتم تنفيذها في CoreCLR (CPAOT ، الآن نشر ملف واحد) يجعل من الصعب اتخاذ قرارات العمل بناءً على التكنولوجيا. لا أريد أن أختار الحصان الخطأ مرة أخرى (سيلفرلايت ...).

لماذا لا تلتزم بوقت التشغيل الرائع في CoreRT وتركز العمل على دمج JIT (والتوسع في عمل المترجم الفوري حتى يصبح جاهزًا) في CoreRT لأولئك الذين يريدون إمكانات إطار العمل الكاملة مع الاستمرار في إنشاء كود أصلي لهم؟ ألن يكون من الممكن ، في حالة الرغبة في قدرات JIT ، الاحتفاظ بالبيانات الوصفية و JIT داخل ملف تنفيذي تم تجميعه محليًا لـ CoreRT؟
ألن يكون هذا أفضل ما في العالم؟ على سبيل المثال. سيكون لديك أصغر الملفات التنفيذية ، وأسرع وقت بدء التشغيل ، ويمكن توسيع قيود كود AOT في CoreRT من خلال وجود JIT في مكانه ، والاحتفاظ بالبيانات الوصفية ورمز IL لأولئك الذين يرغبون في الاحتفاظ بوظائف إطار العمل الكاملة.
يجب أن يكون التركيز في المنظمة البحرية الدولية على "أفضل حل ممكن" بدلاً من التركيز على الوظائف قصيرة المدى التي قد تصرف الانتباه عن الأهداف طويلة المدى.

ربما أكون مخطئًا ولكني أعتقد أن نشر ملف واحد كجزء من CoreCLR سيؤدي إلى تشتيت انتباه العملاء بعيدًا عن CoreRT والذي سيكون في كثير من الحالات حلاً أفضل بالنسبة لهم. على سبيل المثال. إذا تم تصنيف هذا على أنه "الآن يمكنك نشر كود .NET الخاص بك كملف واحد" ومع ذلك فإنه يقوم بإنشاء ملفات ضخمة ، وسيعاني من أداء بدء التشغيل وما إلى ذلك ، فيمكنني أن أرى الناس يبدأون في الشكوى من "وقت تشغيل .NET المتضخم" مرة أخرى . بينما تمتلك .NET بالفعل حلاً رائعًا لذلك بالضبط في CoreRT ، بينما تفتقر إلى الدعم الرسمي / التزام المنتج الرسمي بالمضي قدمًا.

ربما يكون قلقي هو أنني أرغب في رؤية منتجات أقل توازيًا (نقلاً مرة أخرى عنmikedn) والمزيد من التركيز على الالتزام العميق بالمنتجات الموجودة هنا وتوسيعها ودعمها (بما في ذلك مشاركة خرائط الطريق).

منتجات أقل توازيًا

لدينا منتج واحد فقط: .NET Core. CoreRT ليس منتجًا منفصلاً ولن يفعل ذلك أبدًا. هذا حول إضافة خيارات لهذا المنتج الواحد. فيما يلي بعض الأمثلة على الخيارات المتوفرة لدينا اليوم: محطة عمل GC وخادم GC ؛ نشر التطبيق المستقل مقابل نشر التطبيق المعتمد على الإطار.

أتفهمjkotas ، وأنا أوافق تمامًا على أن إضافة الخيارات عادة ما تكون رائعة. إذا استبدلت استخدامي لكلمة "منتجات" بـ "خيارات / حلول" على الرغم من أنني ما زلت متمسكًا باهتمامي بعدم معرفة ما إذا كان التزام منتجنا بـ CoreRT كخيار / حل داخل المنتج الإجمالي لـ .NET Core هو شيء نتمتع به يمكن أن تراهن بأمان على أن يتم دعمها في سنوات عديدة قادمة. تخيل ما سيكون عليه الأمر إذا قامت واجهات برمجة التطبيقات بإجراء تغييرات غير متوقعة مع مرور الوقت وتم إيقافها فجأة دون أن تعرف ما إذا كان يمكنك الوثوق بواجهة برمجة التطبيقات للبقاء هناك أم لا. بالنسبة إلى كيان غير تابع لـ MS ، تشعر الأدوات / الخيارات التي تشكل جزءًا من المنتج بنفس الطريقة. نحن نعتمد على العديد من إمكانيات CoreRT التي لن نكون قادرين على القيام بها (على الأقل حاليًا) مع CoreCLR (أحدها القدرة على حماية ملفاتنا التنفيذية باستخدام PACE وتجريد الكثير والكثير من البيانات الوصفية ، IL ، وما إلى ذلك ، ربط ثابت وثابت ، وفهم أسهل للمنصة الأساسية ، واحتمال بناء التشويش مباشرة في المترجم ، وما إلى ذلك). في الأساس ، أشعر أن عملك وعمل ميشال والآخرين على CoreRT يجب أن يحظى بالأولوية فقط لأنه يعد IMO أحد أفضل الأشياء التي حدثت في النظام البيئي .NET منذ أن تم تصميمه لأول مرة. في أي وقت ، هناك حديث عن أداة / خيار جديد يمكن النظر إليه داخليًا على أنه منافس لـ CoreRT بدلاً من خيار CoreRT ليتم استكماله وتوسيع نطاقه لي يبدو وكأنه تخصيص خاطئ للموارد. آسف لم أقصد سحب المناقشة ، أردت فقط التأكد من فهمك لمدى تقدير عمل CoreRT وأن البعض منا هنا يعتقد أنه يجب أن يكون مستقبل النظام الأساسي.
سأمتنع عن تلويث هذه المناقشة أكثر. أتمنى كل التوفيق للفرق وأتطلع إلى كل ما توصلت إليه ، أنا متأكد من أنه سيكون رائعًا.

christianscheuer لقد كانت ملاحظاتك حول هذه المشكلة وحول المشكلات الأخرى المرتبطة بـ CoreRT قيّمة للغاية. أنت لا تلوث هذه المناقشة على الإطلاق.

هناك حديث عن أداة / خيار جديد يمكن النظر إليه داخليًا على أنه منافس مع CoreRT

بين الفريق الأساسي ، تحدثنا عن عدد من الخيارات المختلفة أو الطموحة أو الأكثر جنونًا. أنا لا أعتبر "فك الضغط إلى القرص" منافسًا مهمًا مع CoreRT full AOT. يستهدف كل منها شريحة مختلفة من مستخدمي / تطبيقات .NET.

اقترح فريق إدارة المنتجات لدينا الذي يجمع البيانات من العديد من القنوات المختلفة (بما في ذلك مشكلات جيثب أو محادثات العملاء وجهًا لوجه) أن أكبر فائدة هي حل مثل ما هو مقترح هنا. ما زلنا نتحقق من أن لدينا جميع البيانات المتعلقة بهذا الحق وأنه سيكون لها النتيجة المرجوة.

لا يمكنني أن أعدك عندما يتم شحن تقنية CoreRT كجزء من منتج .NET Core المدعوم في هذه المرحلة. أعلم أن لديها نقاط قوة فريدة وأنا متأكد من أننا سنقوم بشحن حل مدعوم كهذا لشريحة من مستخدمي .NET المهمين الذين يستفيدون منها في النهاية.

يكون توزيع الملف الفردي منطقيًا إذا:

  • لا يؤثر على وقت بدء التشغيل (وإلا فإن أصغر التطبيقات فقط ستكون قادرة على استخدامه)
  • يعمل بمثابة VFS (نظام ملفات افتراضي) يسمح لك بالوصول إلى التجميعات والموارد كما لو كانت من القرص ، من مجلد التطبيق).
  • لا يؤثر على "قابلية الوصول" للتطبيق. IE: يجب أن تكون Microsoft قادرة على تصحيح التجميعات الهامة حتى لو كانت مضمنة من خلال توفير التجاوزات في مكان آخر ، على مستوى النظام.

التجميعات باعتبارها موارد مضمنة ، مستخرجة ونسخًا إلى مجلد مؤقت ليست حلاً مطلوبًا من Microsoft. يمكن تنفيذها بسهولة من قبل أي عميل يحتاجها.

هناك حاجة إلى حل ملف واحد "حقيقي" وسيوفر قيمة كبيرة.

jkotas تعليقاتك تبدو حقيقية بالنسبة لي. سأواجه صعوبة في إقناع مطوري .NET (LOB / backoffice / Integations) في شركتي للتبديل إلى CoreRT لأنه سيكون قفزة كبيرة بالنسبة لهم (خاصة بالنظر إلى التسمية التجريبية) ، لكن يمكنهم رؤية القيمة في حل بسيط نسبيًا (للاستخدام) لـ Core مثل هذا الموضوع قيد المناقشة. شكرا

@ popcatalin81 أنا في الواقع سأختلف بشدة مع نقاطك هنا.

وقت بدء التشغيل ليس ذا مغزى للعديد من التطبيقات. يسعدني أن أبادل 50٪ - 100٪ زيادة في وقت بدء التشغيل لأي خدمة تعمل لفترة طويلة بغرض تقليل التعقيد التشغيلي لنشرها.

حتى إذا أضفنا 30 ثانية إلى وقت بدء تشغيل إحدى الخدمات ، فإن هذا لا يعني حقًا على المدى الطويل للخدمات.
بالنسبة للتطبيقات التي تواجه المستخدم ، من المحتمل أن يكون هذا قاتلًا ، ولكن حتى يتم إصدار 3.0 ، فإن جميع تطبيقات CoreCLR إلى حد كبير إما وحدة تحكم أو خدمات.

لا يعني ذلك أن CoreCLR لديه بالفعل وضع يمكنك من خلاله تجميع إطار العمل مع تطبيقك (النشر المستقل).
في حالتنا (RavenDB) ، نحن نعتمد على ذلك لعدة أغراض. أولاً ، القدرة على اختيار إطار العمل الخاص بنا بغض النظر عما يستخدمه مستخدمونا. هذه فائدة رئيسية بالنسبة لنا ، لأنها تعني أننا لسنا بحاجة إلى استخدام إطار العمل المثبت عالميًا وبالتالي لسنا مقيدين بأي شيء قرر المسؤول أنه سيكون إطار العمل (اعتدنا أن نأخذ في الاعتبار أننا سنعمل على NET 4.0 في بعض الأحيان ، حتى بعد سنوات من إصدار 4.5 ، على سبيل المثال ، وكان ذلك بمثابة ألم).
جانب آخر مهم هو أنه يمكننا العمل مع مفترقنا الخاص من إطار العمل. هذا مفيد للغاية إذا واجهنا أشياء يجب علينا تغييرها.

كجزء من ذلك ، نأخذ ملكية دورات التصحيح ولا نريد أن يعبث أي شخص آخر بذلك.

أنا لا أفكر في VFS ، لكنني لا أعتقد أن هذا سيكون مطلوبًا. وأنا على ما يرام تمامًا مع الاضطرار إلى المرور عبر واجهة برمجة تطبيقات مخصصة / القفز عبر بعض الأطواق للوصول إلى التجميعات / ملفات dll / الموارد الأصلية التي يتم وضعها بهذه الطريقة.

لقد أشرت إلى هذه المشكلة من خلال briacht لمدة يومين ، لذلك تأخرت حقًا في المناقشة.
فقط أريد أن أضيف 2 سنتي!

أولاً إجاباتي على أسئلة @ morganbr :

  1. تطبيق Windows ، يخلط بين WPF و WinForms.
  2. لا حاليا
  3. نعم ، باستخدام Assembly.Load في أشكال مختلفة
  4. نعم
  5. يعتمد الأمر على ما إذا كانت هذه عقوبة عند كل شركة ناشئة. نعم إذا كانت بضع أجزاء من الألف من الثانية ، ولكن 5 ثوانٍ: لا. إذا كانت مرة واحدة ، فلا توجد مشكلة في 5 ثوانٍ.
  6. 50 ميغا بايت كبيرة بالفعل مقارنة بـ <2 ميغا بايت ... ولكن إذا كان هذا يعني أن وقت تشغيل dotnet مضمن ... حسنًا. ربما يمكنني تقديم تنزيل مع وبدون.
  7. لا يهم وقت الإصدار بشكل مباشر ، ولكن لا ينبغي أن يزعج مزود CI باستخدام الكثير من وحدة المعالجة المركزية لفترة زمنية طويلة.
  8. نعم!

التطبيق الذي أتحدث عنه Greenshot ، الإصدار الحالي الذي تم إصداره لا يزال إلى حد كبير يستهدف .NET Framework 2.0 (نعم بالفعل) ولكنه يعمل بدون مشاكل في الإصدار الأحدث (التوافق الجيد مع الإصدارات السابقة)! يبلغ حجم تنزيل Zhe ، بما في ذلك برنامج التثبيت ولكن بدون .NET Framework ، حوالي 1.7 ميجا بايت. يحتوي الدليل الذي بدأ منه هذا على 1 .exe و 4 .dlls ، وهناك أيضًا 11 وظيفة إضافية في دليل فرعي.

كنت أقرأ التعليقات السابقة ، ويبدو الكثير منها وكأنك تريد شيئًا به وظائف سأستخدم مثبّتًا لها. هذا أمر منطقي إلى حد ما ، حيث لا يوجد حاليًا حل مستقل للنظام الأساسي.

كنت أناقش الموضوع الحالي مع بعض الأشخاص في Microsoft في أغسطس ، وكان تركيزي الرئيسي هو الحديث عن ربط كل شيء معًا لتقليل حجم التطبيق وتعقيده للنشر وأيضًا تقليل تحميل التجميع الذي يستغرق الكثير من الوقت أثناء بدء التشغيل من طلبي.

مع الإصدار التالي من Greenshot ، والذي يستهدف .NET Framework 4.7.1 و dotnet core 3.0 جنبًا إلى جنب ، فإن التنزيل الناتج لـ dotnet core 3.0 يحتوي حاليًا على حوالي 103 dll (!!!) و exe واحد و 15 وظيفة إضافية . الحجم الإجمالي حوالي 37 ميغا بايت وأكبر ملف هو MahApps.Metro.IconPacks.dll (12 ميغا بايت !!) والذي يحتوي على معظم الرموز التي نستخدمها ، والتي ربما تكون حوالي 4٪ من الملف. نفس الشيء مع العديد من ملفات dll الأخرى ، سأفترض أن 50٪ من استخدام الشفرة بشكل عام كثير!

إذا كان المستخدم لا يريد تثبيت التطبيق ، فما عليك سوى تنزيل ملف .zip والعثور على الملف القابل للتنفيذ بين حوالي 118 ملفًا ... ليست تجربة رائعة حقًا! الحجم أكبر بحوالي 35 ميغا بايت (17x) ، فأين فائدة المستخدم؟

في الأشهر التي سبقت ظهور dotnet core 3.0 ، كنت أستخدم Fody.Costura لفعل ما تم وصفه هنا. التعبئة أثناء البناء والتفريغ عند بدء التشغيل! حتى أنه جعل ملفًا تنفيذيًا واحدًا دون استخراج الملفات ممكنًا عن طريق اختراق ملف ولكن. ولكنه تسبب أيضًا في الكثير من المشكلات ، لذلك ليس هذا هو الحل المفضل لدي.

آمل في الحصول على حل قياسي إلى حد ما يمكنني القول: إنه يعمل فقط ™
ربما يكون من المنطقي تحديد بنية المجلد القياسية ، حتى نتمكن من وضع الملفات القابلة للتنفيذ ، التمهيدي ، ملفات الترخيص وغيرها في الجذر ولدينا أدلة مختلفة "معروفة" لملفات مختلفة (dotnet core ، التبعيات ، إلخ). قد يسهل هذا الأمر على الأدوات للعمل ، ويوفر وظائف حيث يمكن للجميع أن يقرروا ما الذي يريدون استخدامه وما لا يستخدمه. في بعض الأحيان ، يؤدي تشغيل zip على الدليل إلى حل بعض المشكلات.

امتلاك حل مشابه لـ Fody.Costury هو بالتأكيد في وقت ما يمكنني التصوير باستخدامه لتبسيط نشر Greenshot ، لكنه لا يقلل بشكل مباشر من الحجم ووقت التحميل. لذلك آمل أن يكون هناك بعض الوقت الذي يقضيه هنا أيضًا!

ayende واسمحوا لي أن أختلف معك أيضًا :)

في حين أن الخدمات الحقيقية ، لا تتأثر تطبيقات الويب والتطبيقات التي تعمل لفترة طويلة المستندة إلى الخادم بشكل عام بتكلفة بدء التشغيل لمرة واحدة ، إلا أن هذه التطبيقات في الوقت نفسه ليست هي التي ترى معظم الفوائد من نموذج توزيع ملف واحد. (الغراب هو استثناء وليس القاعدة ؛))

من وجهة نظري ، فإن توزيع الملف الفردي يستهدف بشكل أساسي التطبيقات والأدوات المساعدة التي تستهدف المستخدمين. المستخدمون الذين سيقومون بتنزيل هذه التطبيقات ونسخها وتشغيلها. وفي المستقبل القريب عندما يقدم Net Core 3.0 الدعم لمكتبات واجهة المستخدم ، سيصبح نموذج التوزيع هذا شائعًا جدًا. ومع ذلك ، يجب أن أؤكد أن هذا النموذج لن يكون مناسبًا لأي تطبيقات. ستظل التطبيقات الرئيسية تستخدم المثبت.

السؤال الآن هو ، هذا النموذج من التجميعات المضمنة المنسوخة إلى مجلدات مؤقتة ، هل سيعمل بشكل جيد إذا أصبح شائعًا للغاية؟

في رأيي ، هذه بعض المشكلات المحتملة للنموذج الحالي:

  • تقوم العشرات من التطبيقات بإنشاء آلاف الملفات المؤقتة بتجميعات مكررة. هناك إمكانية لخلق فوضى هنا. (لم يلاحظها أحد من قبل المستخدمين ، لكنها ما زالت في حالة من الفوضى)
  • لا ضغط ، لا رابط. قد يؤدي ذلك إلى حدوث عيب في تطبيقات المرافق الصغيرة مقارنةً بـ FDD أو ضغط الأحداث.
  • قد يؤدي في الواقع إلى إعاقة عمليات نشر الخادم بدلاً من تسهيلها ، والسبب هو: نشر التكوين مع استبدال الرمز المميز. (إلى أين تذهب للعثور على مجلد temp للكتابة فوق ملفات التكوين؟ هل تمنح الخدمة حق الوصول للكتابة إلى المجلد الخاص بها لإنشاء ملف التكوين هناك؟ هذا رقم أمان لا)

لست هنا لأقول أن هذا النموذج دون المستوى الأمثل لجميع أنواع التطبيقات. لقد قمت بتطبيقه بنجاح واستخدمته بنفسي في الماضي بالكامل. NET Framework ، وهو مناسب تمامًا لتطبيقات معينة.

أعتقد فقط أن التطبيق الأمثل هو الإصدار حيث يقوم الرابط بدمج جميع التجميعات في ملف واحد.

@ popcatalin81 العالم الذي له وجهة نظر واحدة هو عالم فقير. ولست متعجرفًا بما يكفي لأعتقد أن نموذج النشر الخاص بي هو الوحيد الموجود هناك.

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

حول التكوين في ملفات temp. سأكون ضد ذلك بشدة. ملفات التكوين هي أشياء أخرى مرئية للمستخدم _must_ موجودة بجوار الملف الفعلي المستخدم ، وليست مخفية في مكان ما.
لقد رأينا بالفعل مدى سوء ذلك مع ملفات IsolatedStorage عندما يحتاجها المستخدمون.

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

هل ستستخدم هذه الميزة ILMerge؟ إذا لم يكن كذلك ، فلماذا؟ أود أن أعلم نفسي إذا كان هناك مأزق.

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

أعتقد أنه يجب أن يكون شيئًا مثل مترجم corert الأصلي أو Costura.Fody .

اختياريًا ، يجب أيضًا محاولة تقليل الحجم الثنائي (إزالة المراجع غير المستخدمة ، IL الميت).

يكرر

في الأشهر التي سبقت ظهور dotnet core 3.0 ، كنت أستخدم Fody.Costura لفعل ما تم وصفه هنا. التعبئة أثناء البناء والتفريغ عند بدء التشغيل!

لاحظ أن costura لا (افتراضيًا) "فك ​​الضغط إلى القرص". يقوم باستخراج (في الذاكرة) التجميعات المضمنة من الموارد وتحميلها عبر البايت

شكرًا على السياق SimonCropp ، نحن نستكشف كلا خياري فك الضغط إلى القرص والتحميل من التدفق. قد يكون من الممكن تغطية التحميل من تيار لـ IL النقي في التكرار الأول لدينا.

jeffschwMSFT راجع للشغل مجموعة ميزات الدمج السلس للتجمعات (وهز الشجرة الاختياري) هو شيء أحب أن أراه كمواطن من الدرجة الأولى. يعد costura أحد أكثر مشاريعي شهرة ، ولكنه أيضًا مشروع يستغرق وقتًا طويلاً لدعمه. لذلك إذا / عندما يخرج MS مع بديل (حتى كنسخة تجريبية) ، أخبرني وسأقضي بعض الوقت في مراجعته وإضافة بعض "هناك بديل لـ MS" إلى وصف costura التمهيدي والوصف nuget

في حين أنه من غير المحتمل ، إذا كنت بحاجة إلى إصدار أي من الكود في costura بموجب ترخيص مختلف ، فقط أخبرني بذلك.

شكرًا SimonCropp عندما نبدأ في دمج mono / illinker في سلسلة أدوات .NET Core ، سنأخذك في عرض المراجعة الخاص بك.

لاحظ أن costura لا (افتراضيًا) "فك ​​الضغط إلى القرص". يقوم باستخراج (في الذاكرة) التجميعات المضمنة من الموارد وتحميلها عبر البايت

والأفضل من ذلك ، أعتقد أنه يتم تحميله عند الطلب باستخدام حدث AppDomain.AssemblyResolve ، لذلك لا ينبغي أن يتأثر بدء التشغيل كثيرًا لأنه سيتم تحميل التجميعات (في الذاكرة) عند الحاجة فقط.

متأخر على المحادثة هنا. نعتذر إذا تم تغطية هذا بالفعل.

هل يمكننا أن نفترض أن الأداة هنا ستكون حتمية؟ لذلك فإن نفس البنية ستنتج دائمًا نفس الثنائي؟ بايت مقابل بايت. القدرة على توزيع ثنائي باستخدام المجموع الاختباري الكنسي سيكون مفيدًا أيضًا.

morganbr هناك الكثير من القراءة الضرورية هنا. هل سيكون من الممكن تسجيل القرارات التي اتخذت حتى الآن؟

edblackburn ، نحن نجمع تصميمًا محدثًا بناءً على التعليقات. @ swaroop-sridhar يقود التصميم الآن.

هل ستستخدم هذه الميزة ILMerge؟ إذا لم يكن كذلك ، فلماذا؟ أود أن أعلم نفسي إذا كان هناك مأزق.

simplejackcoder يجمع ILMerge بين IL من العديد من التجميعات في واحد ، ولكن في هذه العملية ، يفقد الهوية الأصلية للتجميعات المدمجة. لذلك ، ستفشل أشياء مثل استخدام الانعكاس بناءً على أسماء التجميع الأصلية.

الهدف من هذا الجهد ليس دمج التجميعات ، ولكن تجميعها معًا مع الحفاظ على هوية التجميع. علاوة على ذلك ، نحتاج إلى حزم ليس فقط التجميعات ، ولكن أيضًا الثنائيات الأصلية ، وملفات التكوين ، وربما وقت التشغيل ، وأي تبعيات أخرى يطلبها التطبيق.

يعد دمج IL ميزة مفيدة للتطبيقات التي يمكنها التكيف معها - إنها مجرد ميزة مختلفة عن هذه المشكلة.

يتم نشر مراجعة التصميم على https://github.com/dotnet/designs/pull/52
دعنا نواصل المناقشة حول العلاقات العامة من الآن فصاعدا.

لدي بعض الأسئلة للأشخاص الذين يرغبون في استخدام ملف واحد. ستساعدنا إجاباتك في تضييق خياراتنا:

  1. ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)
  2. هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟
  3. هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟
  4. هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟
  5. هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟
  6. ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟
  7. هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟
  8. هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟
  1. حالة استخدام dotnet / coreclr # 1 إلى حد بعيد هي تطبيقات وحدة التحكم التي تعد أدوات مساعدة. نرغب في إجراء نشر لنظام windows أو linux وتحديد --single-file للحصول على واحد قابل للتنفيذ. بالنسبة للنوافذ ، نتوقع أن ينتهي هذا بـ .exe ، بالنسبة لنظام Linux ، سيكون ملفًا ثنائيًا قابلاً للتنفيذ.
  2. ليس عادةً ، ولكن يمكن ذلك عبر حزمة NuGet غير معروفة لنا
  3. ليس في البداية ، لكنها ستكون ميزة مستقبلية رائعة
  4. نعم
  5. نعم
  6. أي شيء يعمل
  7. نعم ، إذا تم تحسين الحجم الناتج من الملف القابل للتنفيذ. من الناحية المثالية ، قد تكون علامة لتعيين مستوى التحسين باستخدام --optimizing-level=5
  8. نعم ، إلى حد ما

شكراBlitzkriegSoftware.
أعتقد أن التصميم المقترح هنا يغطي حالة الاستخدام الخاصة بك. يرجى إلقاء نظرة على التصميم - نحن نرحب بملاحظاتك.

لدي بعض الأسئلة للأشخاص الذين يرغبون في استخدام ملف واحد. ستساعدنا إجاباتك في تضييق خياراتنا:

  1. ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)
  2. هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟
  3. هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟
  4. هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟
  5. هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟
  6. ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟
  7. هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟
  8. هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟
  1. تطبيق WPF .Core 3.0
  2. ربما في حزمة nuget
  3. رقم
  4. نعم
  5. نعم 200-500 مللي ثانية كحد أقصى
  6. ليس مهمًا بمجرد أن لا يكون أكبر بمرتين أو ثلاث مرات من حجم مجلد النشر الأصلي
  7. إنها للإنتاج ، لذا فهي ليست مهمة حقًا
  8. نعم ولكن لديك إمكانية عدم القيام بذلك قد يكون مفيدًا إذا كان العمل يتعلق بمكتبة طرف ثالث

كانت التعليقات التي تلقيتها إلى حد كبير من أجل التطوير قبل عام 2019 ، والتي عادةً ما تكون خدمات الويب وتطبيقات وحدة التحكم وغيرها من الخدمات التي يتم إطلاقها في الخلفية. ولكن الآن مع .net core 3.0 ، نحتاج إلى حلول لتطبيقات WPF و UI. لن يدعم .Net Framework 4.8 .Net Standard 2.1 ونحتاج إلى حل لاستبدال ILMerge الذي استخدمناه حتى الآن لتطبيقات WPF حيث يتعين علينا ترقية تطبيقاتنا من .net framework (إطار عمل ميت) إلى .net core.

من الواضح أن حزمة الاستخراج الذاتي ليست حلاً جيدًا كما هو موضح في التعليقات الأخرى من قبل لهذا النوع من البرامج.

  1. تطبيقات CLI في الغالب. تعد خدمات Windows الصغيرة وتطبيق WPF العرضي مثيرًا للاهتمام أيضًا. بالنسبة إلى عناصر الويب ، يبدو توزيع الملف الفردي غير ذي صلة بشكل أساسي. لهذا السبب ، فإن ما تبقى من هذا هو في الغالب موجه نحو Windows ؛ تتمحور اهتماماتنا حول Linux .NET Core حول عناصر الويب.
  2. بعض الأحيان. عندما يحدث ذلك ، يكون دائمًا تقريبًا لمكتبات الضغط. إذا لم يتم حزم المواد الأصلية ، فلن تكون هذه نهاية العالم. سيكون الحل الجيد للأشياء المُدارة الخالصة التي تتطلب نشر تبعية أصلية كملف dll منفصل قيمة.
  3. لا ، ليس في الحالات التي نهتم فيها بملف واحد.
  4. نعم.
  5. 200 مللي ثانية هو الحد الأقصى تقريبًا قبل أن تصبح الأمور مزعجة لبدء CLI. > ثانية واحدة ونحن بالتأكيد نلتزم بـ .NET Framework (ILMerge + ngen) أو ننظر إلى اللغات الأخرى التي يتم تجميعها إلى ثنائي أصلي مع أي وقت تشغيل ضروري مرتبط بشكل ثابت. في كثير من الحالات نتحدث عن أشياء تم تنفيذه في C # لأن تطبيق C # المدمج ، ngen-ed يبدأ فعليًا بسرعة معقولة. بعض هذه الأشياء ، من حيث التعقيد ، معقولة للتنفيذ بلغة برمجة نصية ، ولكن هذه الأشياء غالبًا ما يكون لها تكاليف بدء تشغيل كبيرة ، خاصة إذا كنت بحاجة إلى استخدام مجموعة من الوحدات.
  6. يعتمد على. أكثر من 10 ميجابايت لعالم hello سيكون عملية بيع صعبة. تميل البرامج التنفيذية الضخمة أيضًا إلى أن يكون لها تكاليف بدء تشغيل غير بسيطة. حتى إذا كان نظام التشغيل قادرًا نظريًا على بدء التنفيذ دون قراءة كل شيء ، على الأقل على Windows ، فهناك دائمًا شيء ما يريد الحصول على تجزئة لبعض الأغراض الأمنية أولاً. عند الحديث عن ذلك ، فإن عملية فك حزمة مجموعة من الثنائيات لتعيين شيء مؤقت ستؤدي إلى تشغيل مكسرات AV (مضمنة تمامًا في Defender) ، من حيث استخدام الموارد والمسح بشكل محموم إذا لم يكن هناك شيء آخر.
  7. بالتأكيد. يسعدني إضافة دقيقة أو أكثر إلى إصدار الإصدار إذا كان ذلك يعني الحصول على شيء بحجم معقول وبدء التنفيذ بسرعة.
  8. بالتااكيد.

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

يبدو أن هناك الكثير من الأشياء ذات الصلة لسيناريوهات مثل عملنا والتي لم يتم تجميعها معًا في سلسلة أدوات يمكن استخدامها بالفعل / من المحتمل أن تستمر في العمل. ربما كان هذا مجرد جهل من جانبي ، لكني أحاول الانتباه وهو غير واضح بالنسبة لي. بين ILLink و Microsoft. خارج NET Core (وليس لـ UWP).

  1. سيكون توزيع الملف الفردي مفيدًا للغاية لتطبيقات https://github.com/AvaloniaUI/Avalonia (Windows و Linux و MacOS) وتطبيقات WPF (Windows). وجود ملف exe واحد يجعل التحديثات التلقائية سهلة على سبيل المثال ، وبشكل عام يكون أكثر ملاءمة أن يكون لديك ملف واحد مقارنة بمئات dlls.
  2. نعم (بمعنى أنه يشير إلى libs الأصلية التي تم إنشاؤها مسبقًا مثل sqlite و skia)
  3. رقم
  4. نعم
  5. 200 مللي ثانية ربما تكون جيدة. إن الحصول على وقت بدء تشغيل 5 ثوانٍ لتطبيق واجهة المستخدم الرسومية ليس جيدًا.
  6. لا يهم حقا
  7. لا يهم حقا. يمكننا إنشاء ملف واحد فقط لسيناريوهات الإنتاج.
  8. نعم

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

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

لا أستطيع أن أتفق أكثر. هناك بالفعل العديد من الأدوات المتاحة للقيام بذلك.

شكرا لملاحظاتك Safirion ، mattpwhite ، @ x2bool ،thegreatco.
من بينها ، أرى مجموعة من سيناريوهات الاستخدام (تطبيقات وحدة التحكم ، WPF ، تطبيقات واجهة المستخدم الرسومية ، إلخ) ، لكن المتطلبات الإجمالية تبدو متشابهة:

  • ركز على وقت التنفيذ / بدء التشغيل بدلاً من بناء الوقت.
  • القدرة على إعادة إنشاء التطبيقات لمزيد من الإصدارات / التصحيحات
  • القدرة على التشغيل مباشرة من الحزمة (خاصة للمكونات المُدارة تمامًا).

أعتقد أن هذه هي المتطلبات التي حاولنا معالجتها في مستند التصميم .

من فضلك لا تتبع نهج التعبئة والاستخراج

نعم ، كما هو موضح في هذا المستند المرحلي ، الهدف هو تقليل الاعتماد على استخراج الملف بشكل تدريجي.

عند قراءة الاقتراح ، فإنه لا يتناول أي سيناريو لدينا وأننا لن نستخدمه.

mattpwhite ، أردت توضيح ما إذا كنت تعتقد أن هذا الحل لا يناسبك بناءً على:

  • النهج القائم على الاستخراج الذاتي المقترح سابقًا في عنصر العمل هذا ، أو
  • تمت الإشارة إلى التصميم في هذا المستند
    أعتقد أن الوثيقة اللاحقة تحاول معالجة السيناريو الذي ذكرته بالتفصيل. شكرا.

يبدو أن هناك الكثير من الأشياء ذات الصلة لسيناريوهات مثل عملنا والتي لم يتم تجميعها معًا في سلسلة أدوات يمكن استخدامها بالفعل / من المحتمل أن تستمر في العمل.

mattpwhite ، هناك عمل مستمر لدمج ILLink (اهتزاز الشجرة) و Crossgen (إنشاء كود أصلي جاهز للتشغيل) وجوانب تجميع الملف الفردي في msbuild / dotnet CLI بطريقة مبسطة لـ net core 3. مرة واحدة يتم ذلك ، باستخدام هذه الأدوات يمكن أن يتم إنجازه بسهولة (على سبيل المثال: تعيين بعض خصائص msbuild).

كل هذه الأدوات ، تأتي مع المفاضلات. على سبيل المثال ، ينشئ crossgen كودًا أصليًا في وقت مبكر مما يساعد على بدء التشغيل ، ولكنه يميل إلى زيادة حجم الثنائيات. باستخدام خيار الملف الفردي ، يمكن نشر التطبيقات في ملف واحد ، ولكن هذا قد يؤدي إلى إبطاء بدء التشغيل ، لأن الثنائيات الأصلية تتسرب إلى القرص ، وما إلى ذلك.

@ swaroop-sridhar ، شكرًا على الوقت الذي استغرقته في الرد.

أردت توضيح ما إذا كنت تعتقد أن هذا الحل لا يعمل من أجلك بناءً على

يبدو أن الاستخراج لا يزال في الصورة لأي شيء قائم بذاته ، ولم يكن واضحًا بالنسبة لي حالة Crossgen (أو أي شيء آخر يجب تقليصه في وقت JIT عند الإطلاق). بدت قراءة المستند المرحلي الذي يرتبط به التصميم الحالي وكأنه الأشياء التي من شأنها أن تجعل هذا الأمر أكثر تشويقًا بالنسبة لنا هو أبعد من ذلك. بالنظر إلى ذلك ، كان تفكيري هو أننا سنظل عالقين في استخدام .NET Framework لهذه المنافذ لبعض الوقت في المستقبل. ربما أكون قد أسأت الفهم.

كل هذه الأدوات ، تأتي مع المفاضلات. على سبيل المثال ، ينشئ crossgen كودًا أصليًا في وقت مبكر مما يساعد على بدء التشغيل ، ولكنه يميل إلى زيادة حجم الثنائيات.

نعم ، فهمت أن بعضها سيوف ذات حدين. مع الطريقة التي يعمل بها JIT تقليديًا ، كان ngen دائمًا فوزًا لتطبيقات CLI / GUI. من المحتمل أن مزيجًا من التجميع المتدرج وحقيقة أن تحميل وقت التشغيل نفسه ليس بالضرورة مستهلكًا بواسطة الكثير من عمليات .NET Framework الأخرى التي تعمل في نفس المربع ، مما يجعل هذا الأمر أقل وضوحًا في Core.

@ swaroop-sridhar القلق الكبير الذي يساورني بشأن الاقتراح المقبول حاليًا هو هذه الخطوة

سيتم استخراج 216 ملفًا المتبقية إلى القرص عند بدء التشغيل.

بصرف النظر عن حقيقة أن "Hello World" يبدو أنه يتطلب 216 ملفًا للتشغيل ، فإن استخراجها على القرص في بعض المواقع يجعل إزالة تطبيق سطر أوامر بسيط أمرًا صعبًا. عندما يقوم الأشخاص بحذف أداة لم تأتي عبر المثبت ، فإنهم لا يتوقعون أن يحتاجوا إلى تعقب الملفات الأخرى لإزالتها تمامًا.

IMHO ، يجب أن نستهدف تجربة نشر مماثلة لتجربة golang. على الرغم من أن الأمر يتطلب crossgen ليكون في مكانه لمطابقة تجربة golang تمامًا (ويمكن للمرء أن يجادل بأن مباراة 1: 1 ليست _شيءًا جيدًا ، لأننا نخسر في JIT والتجميع المتدرج) ، يمكن تحقيق جزء جيد بدونه. لقد استخدمت العديد من الأدوات على مر السنين لتحقيق تجربة مماثلة ، وأكثرها فاعلية كانت الموارد المضمنة بخطاف على محمل التجميع (كان ILMerge صعبًا ولم يكن Costura.Fody موجودًا بعد). ما تم وصفه في الاقتراح لا يكرر هذه الوظيفة بشكل كامل. NET Core في مستقبل قوي حقًا ، ولكن استخدامه لتطوير أدوات سطر الأوامر محدود طالما أننا بحاجة إلى سحب حوالي 100 من التبعيات أو بصقها في مكان ما على القرص باستخدام بعض كود التمهيد المموج يدويًا.

حالة استخدام dotnet / coreclr # 1 الخاصة بي هي أدوات مساعدة لسطر الأوامر ، ملف واحد ، لن يكون الاستخراج هو المفضل لدي. لكن أود أن أشير إلى أن إعطاء خيارًا كجزء من مفاتيح التبديل للأوامر الكل في واحد مقابل الاستخراج الذاتي الكل في واحد. في حالة الاستخراج الذاتي ، يجب تضمين undo الذي ينظف الملفات غير المضغوطة. في الحالة الأولى ، تعني إزالة الأداة المساعدة حذف ملف واحد مما يجعله مناسبًا للتواجد في مجلد المرافق العامة ، حيث - كما في الحالة الثانية ، يجب أن يكون للتثبيت مجلد خاص به لتسهيل عملية التنظيف وتجنبها سيناريوهات حيث يزيل إلغاء التثبيت الملفات المشتركة. فقط بعض الأفكار. كما قلت ، فإن الأداة المساعدة للملف الواحد (لا حاجة إلى تثبيت) ، هي حالة الاستخدام الأساسية الخاصة بي لأنني أقوم بعمل أدوات مساعدة للمشاريع (كأداة حداد) بشكل متكرر. لكن يمكنني رؤية حالة استخدام لكلا السيناريوهين. لكنهم مختلفون .

لدي بعض الأسئلة للأشخاص الذين يرغبون في استخدام ملف واحد. ستساعدنا إجاباتك في تضييق خياراتنا:

  1. ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)
  2. هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟
  3. هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟
  4. هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟
  5. هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟
  6. ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟
  7. هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟
  8. هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟
  1. CLI (Windows و Linux و MacOS) و WPF و WinForms.
  2. بعض الأحيان.
  3. نعم ، مرات عديدة وأعتقد أنه يجب معالجة السيناريو الذي يمكن أن يعيد المكون الإضافي استخدام مكتبة مشتركة من التطبيق الرئيسي!
  4. نعم.
  5. 200-500 مللي ثانية على ما يرام!
  6. بالنسبة لتطبيق CLI بسيط بدون العديد من التبعيات ، فإن 10 ميجابايت كافية (مضغوطة)!
  7. نعم نهائيا! لا يهم بناء الوقت (خاصة بالنسبة لتركيبات الإصدار!)! يجب أن يكون حجم الضغط و / أو التبديل إلى نشر ملف واحد اختياريًا!
  8. نعم ، على سبيل المثال CoreRT!

IMHO ، يجب أن نستهدف تجربة نشر مماثلة لتجربة golang.

@ thegreatco : نعم ، يعد التجميع الكامل للرمز الأصلي خيارًا جيدًا لإنشاء تطبيقات ذات ملف واحد. تم تصميم لغات مثل GO باستخدام التجميع المسبق (AOT) كنموذج أساسي لها - والذي يأتي مع بعض القيود على ميزات اللغة الديناميكية التي يتم تحقيقها عبر تجميع JIT.

CoreRT هو الحل الصافي لتطبيقات AOT المجمعة. ومع ذلك ، حتى يتوفر CoreRT ، نحاول تحقيق تطبيقات ذات ملف واحد عبر وسائل أخرى في هذه المشكلة.

بصرف النظر عن حقيقة أن "Hello World" يبدو أنه يتطلب 216 ملفًا للتشغيل ،

هناك عدد قليل من الخيارات المتاحة لتقليل عدد الملفات المطلوبة لـ HelloWorld "

  • أنشئ تطبيقًا يعتمد على إطار العمل ، والذي يحتاج فقط إلى 3-4 ملفات
  • إذا احتجنا إلى إنشاء تطبيقات قائمة بذاتها ، فاستخدم ILLinker لتقليل عدد تبعيات الملف

استخراجها إلى القرص في بعض المواقع يجعل إزالة تطبيق سطر أوامر بسيط أمرًا صعبًا.

  • مع انتقال تطوير ميزة الملف الفردي إلى مراحل أخرى ، سينخفض ​​عدد الملفات المنسكبة على القرص ، وسيكون من الناحية المثالية صفرًا لمعظم التطبيقات. ولكن في المراحل الأولية ، سيتعين سكب عدة ملفات (تلك التي تحتوي على كود أصلية).
  • دائمًا ما يكون موقع الملفات المنسكبة على القرص محددًا وقابلًا للتكوين. لذلك ، يمكن تنظيف الملفات المنسكبة باستخدام برنامج نصي مباشر. لكنني أوافق على أن هذا ليس مثاليًا.

شكرا للتوضيحmattpwhite.

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

شكرا لردكم BlitzkriegSoftware.

لكن أود أن أشير إلى أن إعطاء خيارًا كجزء من مفاتيح التبديل للأوامر الكل في واحد مقابل الاستخراج الذاتي الكل في واحد

يعتمد ما إذا كان التطبيق المنشور كملف فردي يتطلب الاستخراج على محتويات التطبيق (على سبيل المثال: ما إذا كان يحتوي على ملفات أصلية). يوفر تصميم المجمّع بعض التكوينات لتقرير ما إذا كان يجب استخراج جميع الملفات. يمكننا إضافة خاصية لنقول أن التطبيق يجب ألا يستخدم الاستخراج إلى الملفات في وقت التشغيل.

<propertygroup>
    <SingleFileExtract> Never | Always | AsNeeded </SingleFileExtract>
</propertygroup>

الفهم هنا هو: عند تجميع SingleFileExtract = مطلقًا ، إذا كان التطبيق يحتوي على ملفات لا يمكن التعامل معها إلا من خلال الاستخراج (الثنائيات الأصلية) ، فسيفشل النشر في ملف واحد.

في حالة الاستخراج الذاتي ، يجب أن يتضمن التراجع الذي يقوم بتنظيف الملفات غير المضغوطة.

يبدو معقولا. الموقع الدقيق للاستخراج (إن وجد) محدد وقابل للتكوين. لذلك ، يمكن أن يكون لدينا برنامج نصي لإزالة أحد التطبيقات وجميع تبعياته المستخرجة.

شكرا لاستجابتكDoCode. السيناريو الخاص بك مثير للاهتمام لأنه يستخدم المكونات الإضافية.
إذا كانت المكونات الإضافية نفسها تحتوي على بعض التبعيات (التي لم تتم مشاركتها مع التطبيق الرئيسي) ، فهل تحتاج / تفضل نشر المكون الإضافي كملف فردي أيضًا (مع تضمين التبعيات)؟ شكرا.

نعم @ swaroop-sridhar ، هذا هو الهدف. نعتقد أنه في هذه الحالة يجب أن يتم تضمين تبعيات البرنامج المساعد. يجب أن تبقى التبعيات المشتركة فقط خارج التطبيق الرئيسي أحادي الملف.

اليوم ، شارك madskristensen توضيحًا جيدًا مع Visual Studio وحزمة Newtonsoft.Json NuGet الشهيرة.

نحن نفس المواقف في وضع مماثل احيانا!

DoCode شكرا. نحن نخطط لعنوان ميزة المكونات الإضافية ذات الملف الفردي ، بمجرد تنفيذ تطبيقات الملف الواحد واستقرارها. يتحدث مستند التصميم عن المكونات الإضافية هنا .

شكرًا على المشاركة المستمرة في هذه الميزة @ swaroop-sridhar ، فهي محل تقدير كبير. سيكون وجود أمر تراجع أمرًا رائعًا للمراحل الأصلية على وجه الخصوص.

  1. ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)
    - أدوات مساعدة لسطر الأوامر (تطبيقات وحدة التحكم)
  2. هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟
    -- رقم
  3. هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟
    -- ليس عادة
  4. هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟
    -- نعم
  5. هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟
    - <1 ثانية هو المفضل لدي
  6. ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟
    - الحجم غير مهم
  7. هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟
    -- 30 ثانية
  8. هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟
    - تأكد من إمكانية كتابتها أو تكوينها

1 - ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)

  • ألعاب
  • أدوات سطر الأوامر

2 - هل يشتمل تطبيقك على (غير .NET) C ++ / كود أصلي؟

نعم

3 - هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء تطبيقك؟

نعم ، لكن مع وجود رموز معروفة بالفعل ، لا أعتمد على الانعكاس لأنه بطيء

4 - هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟

نعم

5 - هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية ببطء أكثر؟ ماذا عن 5 ثوان؟

لا ، إنها بطيئة بعض الشيء بالفعل

6 - ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟

يعتمد على المشروع ، ولكن بالنسبة لأداة سطر أوامر بسيطة ، لا أتوقع أن تكون أكبر من رقم واحد ميغا بايت

7 - هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟

طالما أنه لا يؤثر على وقت التطوير / التكرار ، فأنا بخير مع وقت إنشاء الإصدار الأطول
لكن تذكر أن تطبيقات .net الأساسية تقوم بالفعل ببناء وقت أطول من تطبيقات إطار عمل .net التقليدية

إن ميل البرامج الأبطأ كل عام غير مقبول ، فلدينا أجهزة أفضل ، ولا يوجد سبب لهذا البطء

8 - هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟

نعم!

آمل حقًا أن يكون لدينا تجميع AOT مع CoreRT يعمل يومًا ما حتى نتمكن من تجميع تطبيقات مثل golang و rust وأنظمة AOT الأخرى المجمعة. على غرار الطريقة التي يعمل بها Unity3D مع IL2CPP.

morganbr إليكم بعض المدخلات مني ومن الأشخاص الذين أعمل معهم. أنا أستخدم الكثير من اللغات ، ولكن بشكل أساسي C # و Go و Python.

ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)

ASP.NET Core وبرامج Console ، في الغالب على Linux ، ومن المحتمل أن تكون بعض أحمال عمل Windows ، اعتمادًا على ما إذا كان ML.NET يلبي احتياجاتنا.

هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟

من غير المحتمل في هذه المرحلة.

هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟

هذا يعتمد. حاليًا يمكننا سحب جميع تبعياتنا كحزم ، لكن يمكنني رؤية موقف ندفع فيه مقابل مكتبة تجارية ، مما قد يعني استخدام مكتبات DLL خارجية.

هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟

إطلاقا. هذه أولوية قصوى بالنسبة لنا.

هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟

أود أن أقول إن أي شيء أقل من 10 ثوان هو أكثر من جيد بالنسبة لي. لا يهم وقت بدء التشغيل عمومًا طالما أنه غير فعال وقابل للتنبؤ - أي يتم تحميل المكتبات بنفس الترتيب ، ويتم تهيئة المتغيرات بنفس الترتيب ، وما إلى ذلك.

ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟

الأصغر هو الأفضل ، في الغالب لأغراض التوزيع. يمكن أن يكون التوزيع عبارة عن ثنائيات ينزلها المستخدم أو صور حاوية بها ثنائي ، إلخ.

هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟

بالتأكيد ، طالما أنها أسرع من C / C ++ و Java ، يجب أن تكون مقبولة.

ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟

من المحتمل أن تكون 30-90 ثانية مثالية ، ولكن من المحتمل أن يكون أي شيء أقل من 3 دقائق مقبولًا. أكثر من 3 دقائق للمشاريع الصغيرة / المتوسطة (1k-500k LOC) سيكون كثيرًا. يمكن قبول 5 دقائق للمشاريع الكبيرة جدًا (1M LOC).

هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟

هذا يعتمد. إذا كان العمل الإضافي يضيف رمز معياري يمكن تشكيله في قالب ، فمن المحتمل أن يكون ذلك جيدًا. إذا كان الأمر غير واضح ، وليس عملاً مباشرًا ، فمن المحتمل ألا يكون كذلك.

شكرا على الرد mxplusb ، @ dark2201 ، RUSshy ، BlitzkriegSoftware

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

فيما يتعلق بتقليل وقت بدء التشغيل ووقت التجميع:
سيكون للتطبيقات المعتمدة على إطار العمل وقت بدء تشغيل أقل إلى حد كبير (على الأقل في المراحل الأولى من عرض الميزة). وقت الترجمة أيضًا أصغر (لأنه يلزم تضمين عدد أقل من الملفات).
سأعود إليك بقياسات وقت بدء التشغيل ، وإنتاجية الترجمة ، وحجم الملف بمجرد اكتمال التكرار الأول لتطوير الميزة.

@ swaroop-sridhar ما هو الجدول الزمني لذلك؟

ayende التكرار الأول قيد التطوير النشط ، وأعتقد أننا سنحصل على النتائج في غضون أسابيع قليلة.

@ swaroop-sridhar

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

تشغيل: HelloWorld.exe

تتم معالجة ملفات التكوين والتطبيق المجمعة مباشرة من الحزمة.
سيتم استخراج 216 ملفًا المتبقية إلى القرص عند بدء التشغيل.

ماذا لو كنت بحاجة إلى الركض من قراءة fs فقط ، فهذا شائع لإنترنت الأشياء ، أو إذا كان exe يعمل داخل حاوية ro؟ لماذا لا يوجد خيار تشغيله مباشرة من exe أيضًا؟

etherealjoy المثال الموضح في هذا القسم هو الناتج المتوقع لـ HelloWorld المستقل ذاتيًا اعتبارًا من المرحلة 2 من تطوير هذه الميزة (كما هو مذكور في هذا القسم ). في هذه المرحلة ، التطبيقات الوحيدة التي يمكن تشغيلها مباشرة من EXE هي تطبيقات مُدارة تمامًا تعتمد على إطار العمل.

إذا كنا في المرحلة 4 أو المرحلة 5 ، فيمكن تنفيذ التطبيق المستقل أعلاه مباشرة من الحزمة.

ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)

في الأساس كل ما سبق. أدوات وحدة التحكم ، WPF ، asp.net ، الألعاب

هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟

نعم. سكلايت مثال جيد.

هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟

على الأرجح لا.

هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟

نعم.

هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟

net.core بطيء بعض الشيء بالفعل. لكن الزيادة بضع ثوانٍ مقبولة. 5 ثوان - بالتأكيد لا.

ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟

لا يهم في الوقت الحاضر

هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟

ما يصل إلى 5 دقائق يشعر أنه مقبول. 15-20 دقيقة من إصدارات الإصدار لـ UWP تدفع الجميع إلى الجنون.

هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟

بالتأكيد.

شكرا @ mjr27

اكتمل الآن تنفيذ المرحلة الأولى ، وهو متاح اعتبارًا من 3.0.100-preview5-011568 .

يمكن نشر التطبيقات في ملف واحد عن طريق تعيين خاصية PublishSingleFile إلى true كما هو موضح هنا .

في هذا الإصدار ، يتم استخراج جميع الملفات المضمنة إلى القرص عند التشغيل لأول مرة ، وإعادة استخدامها في عمليات التشغيل اللاحقة ، كما هو موضح هنا .

صبيب التجميع
لا يوجد فرق كبير في الوقت سواء تمت كتابة الملفات إلى دليل النشر كملفات فردية أو كملف واحد.

حجم الملف وبدء التشغيل
يوضح الجدول التالي أداء تطبيقين تم إنشاؤهما كملف واحد.

  • وحدة التحكم: تطبيق hello world. الوقت المُبلغ عنه هو وقت تشغيل التطبيق ، مُقاسًا من خلال علامات الساعة.
  • تطبيق WPF: تطبيق msix -atalog . الوقت الذي تم الإبلاغ عنه هو وقت بدء التشغيل على الشاشة الأولية ، ويتم قياسه عبر ساعة الإيقاف.
  • Fw: البنيات المعتمدة على الإطار
  • ذاتي: يبني مكتفية ذاتيا.
    تم توقيت جميع عمليات التشغيل عند إيقاف تشغيل فحوصات مكافحة الفيروسات لتقليل تأثير العوامل الخارجية.

القياس | وحدة التحكم Fw | وحدة التحكم الذاتية | WPF Fw | WPF الذاتي
- | - | - | - | -
حجم الملف (ميغا بايت) | 0.32 | 66.5 | 20.69 | 118.9
تشغيل عادي (ثانية) | 0.123 | 0.127 | 3.32 | 3.24
تشغيل أول واحد exe (ثانية) | 0.127 | 0.565 | 3.67 | 4.14
عمليات التشغيل اللاحقة أحادية exe (ثانية) | 0.124 | 0.128 | 3.30 | 3.29

سأستمر في تحديث الأرقام مع استمرار التنفيذ في المراحل اللاحقة من التطوير.

أخبارممتازه. شكرا لك

هل ستنتهي جميع المراحل المذكورة في مستند التدريج لـ 3.0 دورة في الدقيقة؟ أم سيتعين علينا الانتظار بعد 3.0 حتى يتم تنفيذها؟

كما هو مذكور هنا ، من المتوقع أن يتم تنفيذ .net core 3.0 المرحلة 2 بحيث يمكن تشغيل تطبيقات msil النقية المعتمدة على إطار العمل مباشرة من الحزمة. سيتم النظر في المراحل المتبقية لمزيد من الإصدارات.

كما هو مذكور هنا ، من المتوقع أن يتم تنفيذ .net core 3.0 المرحلة 2 بحيث يمكن تشغيل تطبيقات msil النقية المعتمدة على إطار العمل مباشرة من الحزمة. سيتم النظر في المراحل المتبقية لمزيد من الإصدارات.

:( كان يأمل أن يتمكن من الوصول إلى RTM.

cup اعتقدت أنه يمكنك القيام بذلك باستخدام dotnet publish -o out /p:PublishSingleFile=true /p:RuntimeIdentifier=win-x64 . لقد اختبرت للتو من خلال إنشاء تطبيق وحدة تحكم Vanilla وتشغيل هذا الأمر. عملت بنجاح.

يمكنك الذهاب إلى أبعد من ذلك من خلال تجميع ملف .pdb مع dotnet publish -o out /p:PublishSingleFile=true /p:RuntimeIdentifier=win-x64 /p:IncludeSymbolsInSingleFile=true

شكرًا seesharprun على الملاحظات التفصيلية. نعم cup ، الطريقة الموصى بها لنشر ملف فردي بسطر الأوامر هي تعيين الخاصية PublishSingleFile من سطر الأوامر.

etherealjoy سيتم إغلاق repos وقت تشغيل coreclr في الغالب مع عمل ميزة wrt في غضون شهر أو نحو ذلك. لا أعتقد أن هناك وقتًا كافيًا لجميع المراحل. آمل أن تأتي المراحل اللاحقة في الإصدار التالي.

لقد نجحت في هذا اليوم ولكن يبدو أن تغيير قاعدة الاستخراج dir لا يعمل. حسب هذا القسم . يجب أن أكون قادرًا على إضافة مفتاح تطبيق في runtimeconfig يسمى ExtractBaseDir لتغيير الموقع الذي يتم استخراج التطبيق إليه.

لدي runtimeconfig.template.json يشبه هذا

{
    "configProperties" : {
        "ExtractBaseDir": "C:\\"
    },
    "ExtractBaseDir": "C:\\"   
}

يبدو التطبيق app.runtimeconfig.json المُنتج كالتالي:

{
  "runtimeOptions": {
    "configProperties": {
      "ExtractBaseDir": "C:\\"
    },
    "ExtractBaseDir": "C:\\"
  }
}

عند التشغيل على الرغم من أن exe المنتج لا يزال يمتد إلى مجلد tmp.

أفترض أن هذه الميزة ليست جاهزة في Preview5 ولكني أردت التأكد من عدم وضوح المكان الذي من المفترض أن يذهب إليه "ExtractBaseDir" في runtimeconfig.json ولا توجد أمثلة.

@ igloo15 شكرًا على طرح هذا الأمر.

في المعاينة الحالية ، يتم تمكين متغير البيئة DOTNET_BUNDLE_EXTRACT_BASE_DIR فقط. هذا لأنه في المرحلة الحالية من التنفيذ ، يتم استخراج جميع الملفات - بما في ذلك runtimeconfig.json - إلى القرص قبل معالجتها.

أعمل على إضافة دعم ExtractBaseDir في المعاينة التالية.

هل هناك بعض الإرشادات حول كيفية جعل هذا يعمل مع مشاريع ASP.NET Core؟ هل يكون الأسلوب الموصى به هو استخدام الانعكاس للعثور على مكان تحميل أنواع النظام الخاصة بي وتعيين IHostingEnvironment ContentRootPath و WebRootPath بالنسبة لهذا الدليل؟

keithwill يمكنك استخدام AppContext.BaseDirectory للحصول على الموقع حيث يتم استخراج app.dll وجميع الملفات الأخرى إلى القرص. لذلك ، يمكنك استخدام هذا كـ ContentRootPath .

@ igloo15 : أشعر بالفضول إذا كان بإمكانك مشاركة السيناريو الخاص بك لاستخدام هذا الخيار.

  • هل تحاول استخدامه لسيناريو التصحيح أو الإنتاج-نشر؟
  • هل يكفي متغير البيئة في هذه الحالة ، أم أنك تتطلب إعداد runtimeconfig.json ؟

يسعدني أن أسمع من المطورين الآخرين أيضًا ، إذا كانت هناك حالات استخدام محددة لهذا الإعداد.

@ swaroop-sridhar

لدي وضع غريب نوعا ما. يتم تخزين البرنامج الخاص بي على مشاركة عبر الشبكة ثم يتم ربط مشاركة الشبكة بنظام windows vm عشوائي ويتم تشغيله مباشرة من مشاركة الشبكة. لا يمكن تعديل أو تغيير أي شيء على نظام التشغيل windows vm الذي تم تشغيله لتشغيل البرنامج من مشاركة الشبكة. يجب إنشاء السجلات وملفات التكوين وما إلى ذلك على مشاركة الشبكة.

الغريب أن هذا الإعداد يسمح للنظام العام بتخطيط أجزاء متعددة من البرامج في مجلد ثم استنساخ هيكل هذا المجلد لتكوينات / إصدارات مختلفة. ثم عندما يتعين على إصدار معين تشغيل برنامج الإدارة ، فإنه يقوم بتدوير محركات الأقراص الافتراضية (VMS) وخرائط محركات الأقراص الموجودة على أجهزة VMS إلى إصدار معين من مشاركة الشبكة وتشغيل البرنامج.

1.) إنه سيناريو نشر الإنتاج
2.) ستكون متغيرات البيئة صعبة لأن الكمبيوتر الذي يقوم بتشغيل البرنامج مختلف باستمرار ويتم تدميره / تجديده

cup لا أوافق حقًا على أن هذا الموضوع يتعلق بتنفيذ مستند التصميم ويقول مستند التصميم تحديدًا أن ExtractBaseDir يجب أن يعمل مع هذه الميزة.

إذا كانت هذه المشكلة لا تتعلق بتنفيذ مستند التصميم هذا ، فما موضوع هذه المشكلة؟

شكرا على الشرح @ igloo15.

أسأل عن خيار التكوين ، لأن هناك تكلفة لتحليل ملفات التكوين في وقت مبكر في كود AppHost. حاليًا لا يرتبط AppHost برمز تحليل ملفات json (يتم استخدامها بواسطة hostfxr / hostpolicy بدلاً من ذلك). ستؤدي إضافة هذه الميزة في الوقت الحالي إلى جعل AppHost أكبر / معقدًا. ومع ذلك ، بمجرد أن ينتقل التنفيذ إلى مراحل أخرى (حيث يتم ربط جميع رموز الاستضافة ووقت التشغيل معًا) ، لم تعد هذه مشكلة.

@ igloo15 يعد مستند التصميم جزءًا مهمًا منه ، ولكن جوهر هذه المشكلة هو الميزة نفسها. ExtractBaseDir هو معلمة اختيارية وأنا أفضل أن أرى الميزة الأساسية يتم تمريرها إلى الإصدار "الحالي" بدلاً من التعثر بالمعلمات الاختيارية.

cup ، سألت السؤال هنا ، لأنني لفتت انتباه المطورين المهتمين بهذا الموضوع.
على الرغم من أنني لا أعتقد أن السؤال خارج عن الموضوع ، إلا أنني أفهم قلقك بشأن طول هذا الموضوع. سأقوم بإنشاء مشكلة مرتبطة في المرة القادمة. شكرا.

تضمين التغريدة

هناك أمران أود أن أقولهما أولاً وهما أن هذه الميزة مهمة فقط للمرحلة 1 من وثيقة المرحلة . جميع المراحل الأخرى من 2 إلى 5 تدور حول تشغيل dlls من داخل الحزمة وليس الاستخراج. لذا فإن الإعداد لتحديد موقع استخراج قاعدة dir ليس مفيدًا حقًا للمراحل 2-5. نظرًا لأن NetCore 3.0 يعتزم تطوير المرحلة الأولى ، أتوقع أن تكون هذه الميزة موجودة لأن هذه هي المرة الوحيدة التي ستكون مفيدة فيها.

ثانيًا ، كيف نميز هذه الطريقة عن الطرق الأخرى مثل dotnet-wrap. بالنسبة لي ، تتمثل المزايا الرئيسية لهذه الطريقة في أننا نبني هذه العملية في سلسلة الإنشاء الأقرب إلى وقت تجميع الكود. بالإضافة إلى ذلك ، فهذه ميزة موجهة إلى .NET وبالتالي فهي تفهم الفروق الدقيقة في تطبيقات .NET Core مثل التكوينات وعملية الإنشاء وما إلى ذلك. لذلك آمل أن نركز على الميزات التي تميز هذه الأداة عن الأدوات الأخرى ليست موجهة على وجه التحديد إلى صافي الأساسية. قد تكون هذه ميزات مثل تكوين موقع الاستخراج الذي لا يمكن لـ dotnet-wrap القيام به.

فيما يتعلق بكيفية تنفيذها ، لست متأكدًا ولكني أعتقد أنه بدلاً من قراءة ExtractBaseDir من التكوين في وقت التشغيل ، لا يمكننا إدخال ذلك في حزمة exe في وقت الإنشاء؟ لم أر الكود الذي يجعل عملية الحزمة تعمل ولكن في رأيي يتم إنشاء / إنشاء ملف exe أصلي مع جميع ملفات dlls وما إلى ذلك بداخله. تعذر علينا أثناء إنشاء / إنشاء exe قراءة ملف runtimeconfig للتطبيقات المجمعة سحب ExtractBaseDir وتعيينه كخاصية على exe للحزمة الأصلية.

ثم لا يقرأ runtimeconfig مضمنًا في وقت التشغيل ولكن بدلاً من ذلك يستفيد من خاصية داخليًا لتحديد موقع الاستخراج. من المحتمل أن يكون ذلك أسرع بكثير.

@ igloo15 : قد يكون استخراج محتويات الحزمة إلى القرص مفيدًا لتطبيقات معينة تتجاوز المرحلة 2.
على سبيل المثال ، إذا كان التطبيق يحتوي على ثنائيات أصلية مخصصة في الحزمة ، فسيلزم استخراجها حتى المرحلة 5. قد يرغب التطبيق في تجميع ملفات محتوى من نوع غير معروف لاستخراجها إلى الملفات في وقت التشغيل.

أوافق على أن فائدة هذا الإعداد تقل كلما ننتقل إلى مراحل أخرى من التطوير. ومع ذلك ، بمجرد إضافة الخيار ، من المحتمل أن نضطر إلى الاحتفاظ به في جميع الإصدارات اللاحقة من أجل التوافق. لذلك ، فإنه يحتاج إلى دراسة متأنية الآن.

أوافق على أن جعل موقع الاستخراج إعدادًا لوقت البناء (على سبيل المثال: خاصية msbuild) بدلاً من خيار runtimeconfig هو تنفيذ كتابي أسهل وأكثر كفاءة. شكرا.

مرحبًا ، لدي سؤالان حول هذا الموضوع:

أرغب في استخدام ميزة توزيع الملف الفردي لتعبئة تطبيقات .NET Framework 4.7.2 (على سبيل المثال) في ملف تنفيذي واحد. هل هذا هو الغرض من هذه الميزة أم أنها تهدف فقط إلى دعم تطبيقات .NET Core؟

سؤالي الثاني يتعلق بكيفية عمل التغليف. عندما يتم إنشاء الملف القابل للتنفيذ ، هل سيتم تجميع وقت تشغيل الأطر المستهدفة في الملف القابل للتنفيذ؟ أم يجب تثبيته مسبقًا على الجهاز المستهدف الذي سيشغل التطبيق؟

gaviriar لا أعتقد أنه يدعم تطبيقات .NET Framework. ونعم ، يمكنه تجميع وقت تشغيل .NET Core في ملف تنفيذي (ما يسمى بالنشر "المستقل").

@ tomrus88 شكرا على الرد. هذا عار حقيقي فيما يتعلق بتطبيقات .NET Framework. هل هناك أي طريقة تنصح باستخدامها لتجميع وقت تشغيل .NET Framework في ملف تنفيذي؟

أرى قائمة بالأدوات في قسم العمل ذي الصلة من المستند. هل هناك أي منها على وجه الخصوص يمكن التوصية به لحالة الاستخدام المقترحة أعلاه؟

gaviriar .NET Framework جزء من نظام تشغيل Windows. لا توجد طريقة معتمدة لتجميعها في ملف قابل للتنفيذ.

gaviriar تعد الحاجة إلى تجميع وقت التشغيل أحد الأسباب الرئيسية للتبديل إلى .NET Core.

@ jnm2 و @ jkotas شكرًا على التوضيح ، مستجد هنا في عالم .NET. أوافق على أنني أرغب في التبديل إلى .NET Core. ومع ذلك ، أواجه حالة حيث يتعين علي التفاعل مع مكتبة قديمة تستهدف .NET Framework. في مثل هذه الحالة ، أفهم أنه لا يمكنني تبديل تطبيقي إلى .NET Core إذا كنت بحاجة إلى التفاعل مع هذه المكتبة. أم أن هناك طريقة بديلة مثل أن يكون تطبيقي هو .NET Core ولكن لا يزال بإمكانه التفاعل مع مكتبة .NET Framework القديمة؟

هذا يعتمد على المكتبة. تعمل الكثير من المكتبات التي تستهدف .NET Framework بشكل جيد على .NET Core أيضًا. هل حاولت استخدام المكتبة في .NET Core؟ إذا كنت قد تحققت من أنها لا تعمل ، فلا يمكنك التبديل حتى يتوفر لديك حل لها.

لقد جربته بالفعل ، لكن هذا لا يعمل لأننا نتحدث عن مكتبات خاصة بالنوافذ. أعتقد أنه ليس لدي خيار آخر سوى الاستمرار في استهداف .NET Framework وتفويت متعة .NET Core كما تقول: /

gaviriar هذا خارج عن الموضوع ولكن هل جربت حزمة NuGet للتوافق مع Windows فهي توفر windows apis لـ .NET Core للغرض المحدد الذي تصف Microsoft .

gaviriar : بعض التوضيحات الإضافية:

عندما يتم إنشاء الملف القابل للتنفيذ ، هل سيتم تجميع وقت تشغيل الأطر المستهدفة في الملف القابل للتنفيذ؟ أم يجب تثبيته مسبقًا على الجهاز المستهدف الذي سيشغل التطبيق؟

هذا يعتمد على البناء. يمكن نشر كل من التطبيقات المعتمدة على إطار العمل (يتم تثبيت وقت التشغيل على الهدف) ، والتطبيقات المستقلة (يتم حزم وقت التشغيل مع التطبيق) كملف واحد - ولكن فقط تطبيقات .net core 3.0.

أرى قائمة بالأدوات في قسم العمل ذي الصلة من المستند. هل هناك أي منها على وجه الخصوص يمكن التوصية به لحالة الاستخدام المقترحة أعلاه؟

بالنسبة إلى إطار عمل .net ، فإن أفضل حل يمكنني اقتراحه هو أن يتعامل التطبيق مع استخراج الملفات بنفسه. على سبيل المثال: قم بتضمين التبعيات كموارد مُدارة في ثنائي التطبيق ، ثم قم باستخراج الموارد بشكل صريح عند بدء التشغيل. يمكنك أيضًا استخدام مكتبة الحزم للتجميع والاستخراج (لأن المكتبة مبنية على معيار الشبكة) ، ولكن استخدام الموارد المُدارة يُعد حلاً أفضل.

@ igloo15 و @ swaroop-sridhar أقدر هذه المدخلات بالنظر إلى أنها خارج الموضوع. على الرغم من أنني أتمنى أن يجد شخص آخر هذه المناقشة مفيدة عند القراءة يومًا ما.

سأقيم الخيارات التي شاركتها معي وأعلمك بما يتضح أنه أفضل نهج لحالة الاستخدام الخاصة بي.

شكرا!

تحديث سريع!

لقد اختبرت تطبيق Hello World البسيط هذا. يمكنني إنشاء ملف واحد قابل للتنفيذ بنجاح. ومع ذلك ، كما ترى من تكوين المشروع ، فمن المفترض أن تكون قائمة بذاتها. ولكن عندما أحاول تشغيل هذا الملف القابل للتنفيذ على تثبيت جديد لنظام التشغيل Windows 7 دون تثبيت أي وقت تشغيل أساسي لـ .NET ، أرى الخطأ التالي:

Failed to load the DLL from [C:\Users\vagrant\AppData\Local\Temp\.net\HelloWorld
\muasjfkf.kyn\hostfxr.dll], HRESULT: 0x80070057
The library hostfxr.dll was found, but loading it from C:\Users\vagrant\AppData\
Local\Temp\.net\HelloWorld\muasjfkf.kyn\hostfxr.dll failed
  - Installing .NET Core prerequisites might help resolve this problem.
     https://go.microsoft.com/fwlink/?linkid=798306

ما يمكنني رؤيته هو أن إنشاء نشر التطبيق كـ dotnet publish /p:PublishSingleFile=true أو /p:PublishSingleFile=false لا يغير حجم الملف القابل للتنفيذ. هل هذا سلوك متوقع؟

خطوات التكاثر

  1. انشر المشروع لتوليد HelloWorld.exe

  2. انسخ الملف القابل للتنفيذ إلى تثبيت Windows 7 بدون تثبيت أي وقت تشغيل .NET Core

  3. قم بتشغيل HelloWorld.exe

gaviriar لقد جربت المثال الذي نشرته ، وعمل جيدًا بالنسبة لي.
أي أنه بنى exe منفردًا قائمًا بذاته لـ HelloWorld يعمل بشكل جيد.

ما يمكنني رؤيته هو أن إنشاء نشر التطبيق كنشر dotnet / p: PublishSingleFile = true أو / p: PublishSingleFile = false لا يغير حجم الملف القابل للتنفيذ. هل هذا سلوك متوقع؟

هذا بالتأكيد غير متوقع. يجب أن يكون حجم التطبيق أحادي الملف حوالي 70 ميغابايت (لإصدار تصحيح الأخطاء المشار إليه في صفحة gitlab الخاصة بك). خلاف ذلك ، فهو مضيف تطبيقات عادي ، والذي من المتوقع أن يفشل تمامًا كما أشرت أعلاه. هل تقوم بالنشر من دليل نظيف؟

ملاحظة أخرى حول ملف مشروعك - لديك إحدى الخصائص مكتوبة بشكل غير صحيح كـ IncludeSymbolsInFile بدلاً من IncludeSymbolsInSingleFile . لكن هذا ليس له صلة بالمشكلة التي أبلغت عنها.

gaviriar ما هي معرفات وقت التشغيل المستهدفة. إذا لم تقم بتعيينه بشكل صحيح ، فلن يقوم بتجميع الملف hostfxr.dll الصحيح. من المحتمل أن يتطلب hostfxr.dll ملف vc ++ معين قابل لإعادة التوزيع غير موجود على جهاز windows 7 الخاص بك. يمكنك التحقق من وجود dll في مسار معين وإذا كان يحاول تحميله في أداة المشاة التبعية لمعرفة ما إذا كان dll يعتمد عليه.

دمج IL: تجمع أدوات مثل ILMerge بين IL من العديد من التجميعات في واحدة ، لكنها تفقد هوية التجميع في العملية. هذا ليس هدفًا لميزة الملف الفردي.

تفقد هوية التجمع

هذه ليست مشكلة.
أنا دائما ضد استخدام zip / unzip أو غيرها من حلول الحزم لميزة واحدة قائمة بذاتها exe.
لأن هذا سوف يسبب المشاكل القادمة.
كيفية تصغير حجم ملف exe المفرد! ؟؟ أو لماذا ملف exe كبير جدًا ولكنه عالم مرحبًا فقط! ؟؟

هناك دائمًا مشكلة ، وتحتاج إلى معالجة ، فلماذا لا تقوم بعمل شامل.
في الواقع ، منذ البداية يجب استخدام IL-Merge بطرق مماثلة.

في الواقع ، الناس ليسوا مهووسين حقًا بـ EXE واحد.
exe (1) + dll (1-2) موافق أيضًا ، لكن ليس 400 mount dlls.
لن يرغب ppl في إحضار الكود أبدًا إلى قرص الخادم وتشغيله يأخذ ذاكرة الخادم.
الناس يريدون فقط تقليل تكلفة النشر (القرص ، الذاكرة ، النطاق الترددي ، إلخ ...)

لقد قمت بإزالة الإصدار 3.0 ، بحيث تتعقب هذه المشكلة تنفيذ ميزة الملف الفردي من خلال المراحل الموضحة في هذا المستند ، والتي تتجاوز نطاق الإصدار 3.0.

sgf ، أوافق على وجود عمل مطلوب لتقليل حجم الملف. إن فرص تقليل الحجم من شكلين ، فهي غير مرتبطة بشكل خاص بـ exe الفردي:
1) تقليل كمية المحتوى المطلوب نشره. علي سبيل المثال:
* استخدم ILLinker مثل الأدوات لقص الثنائيات غير الضرورية وأجزاء التجميعات وما إلى ذلك.
يتم تعقب هذا العمل بشكل منفصل من خلال مشكلات مثل dotnet / coreclr # 24092 و mono / linker # 607
* يمكننا النظر في تدابير أخرى مثل وجود وضع "قدرة منخفضة" حيث لا يتم دعم JITting لتقليل
2) إضافة ميزة ضغط لنشر ملف واحد.

يمكن أن تعمل الميزات المذكورة أعلاه معًا لتقليل حجم تطبيقات الملف الفردي (وغير الملف الفردي):
على سبيل المثال ، لتطبيق HelloWorld console ،
حجم النشر العادي = 67.4 ميجا بايت
الحجم المقتطع = 27 ميغا بايت
مقصوص ، ملف فردي ، مضغوط (عبر النموذج الأولي) = 12 ميغا بايت

@ swaroop-sridhar هل هناك أي طريقة للحصول على مسار ملف exe الفردي داخل التطبيق الخاص بك؟
سيؤدي استخدام Assembly.GetExecutingAssembly().Location إلى إخراج دليل الاستخراج في \ AppData \ Local \ Temp.net.

@ chris3713 أفضل طريقة للوصول إلى موقع exe حاليًا هي عن طريق PInvoke-ing إلى واجهات برمجة التطبيقات الأصلية. على سبيل المثال: GetModuleFileNameW (Null, <buffer>, <len>)

@ chris3713 أفضل طريقة للوصول إلى موقع exe حاليًا هي عن طريق PInvoke-ing إلى واجهات برمجة التطبيقات الأصلية. على سبيل المثال: GetModuleFileNameW (Null, <buffer>, <len>)

شكرًا ، انتهيت باستخدام Process.GetCurrentProcess().MainModule.FileName .

يعمل بشكل جيد مع asp .net core worker / web api مثل Windows Service المنشورة مع PublishSingleFile = true.

عند تسجيل الخدمة وتشغيلها عبر sc create testwk binPath="[...]/MyAspNetCoreWorker.exe" ثم sc start testwk تلقيت رسالة النجاح هذه:

[...]\bin\publish\x64>sc start testwk

SERVICE_NAME: testwk
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 5060
        FLAGS              :

[...]\bin\publish\x64>sc stop testwk

SERVICE_NAME: testwk
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

لا أطيق الانتظار لرؤية المرحلة 2 مع التشغيل في الحزمة😀
بالمناسبة ، هل سيستمر التخطيط للمرحلة الثانية لتكون جزءًا من NET Core 3.0؟

شكرًا لك على عملك ، أصبحت خدمة النشر في .net core الآن بسيطة جدًا 👍

CoreRT : (2.5 ميجابايت)

image

image

لا يوجد قرصنة مضغوطة ، ولا توجد تكلفة مخفية ، ويحتوي المحرك على ما هو مطلوب فقط ، ويتم تعطيل الميزات غير المستخدمة باستخدام تكوين csproj (الانعكاس)

هذا ما تحتاجه dotnet ، فهي تتنافس مع GO وتتفوق عليها من حيث الحجم والأداء

لأي شخص مهتم ، تحقق من الريبو:

https://github.com/dotnet/corert

هناك عينات من لعبة MonoGame:

https://github.com/dotnet/corert/tree/master/samples/MonoGame

لا يمكن لأي من الحلول المقترحة تحقيق هذه النتيجة ، CoreRT هو الأفضل حقًا ، MS ترتكب خطأً فادحًا من خلال عدم التركيز عليها

لقد اختبرت هذه الميزة على macOS dotnet-sdk-3.0.100-preview8-013656-osx-x64.tar.gz . إذا قمنا بتبديل التكوين ، من Debug إلى Release أو العكس وقمنا بالبناء مرة أخرى ، فإنه يضيف 10 ميغابايت إلى الحجم القابل للتنفيذ. لا تؤدي إعادة التحويل البرمجي باستخدام التكوين القديم إلى استعادة هذه الزيادة في الحجم ما لم نحذف الدليل bin .

mkdir /tmp/dotnet-preview8
curl -s https://download.visualstudio.microsoft.com/download/pr/a974d0a6-d03a-41c1-9dfd-f5884655fd33/cf9d659401cca08c3c55374b3cb8b629/dotnet-sdk-3.0.100-preview8-013656-osx-x64.tar.gz | tar -xvz -C /tmp/dotnet-preview8
export PATH=/tmp/dotnet-preview8:$PATH

dotnet new console -o /tmp/myApp
pushd /tmp/myApp

# publish with Debug
dotnet publish /p:PublishSingleFile=true,RuntimeIdentifier=osx-x64,Configuration=Debug -o bin/a/b/c/d

bin/a/b/c/d/myApp
# outputs: Hello World!

du -sh bin/a/b/c/d
# outputs  70M  bin/a/b/c/d

# publish with Release
dotnet publish /p:PublishSingleFile=true,RuntimeIdentifier=osx-x64,Configuration=Release -o bin/a/b/c/d

du -sh bin/a/b/c/d
# outputs:  80M bin/a/b/c/d

# publish with Debug again
dotnet publish /p:PublishSingleFile=true,RuntimeIdentifier=osx-x64,Configuration=Debug -o bin/a/b/c/d
# still outputs:  80M   bin/a/b/c/d

حتى بدون تغيير تكوين الإنشاء ، إذا استدعينا هدف إعادة الإنشاء لاحقًا ( /t:Rebuild ) بعد الإنشاء الأولي ، فإن حجم المخرجات يزيد.

شكرا @ am11 لإلقاء نظرة. يعد نشر الاحتفاظ بالثنائيات القديمة مشكلة معروفة (ccnguerrera).

منذ معاينة Net Core 3 8 ، لا يمكنني تشغيل تطبيقي المنشور بملف واحد.
في حالة عارض الحدث لدي هذا الخطأ:

image

أنا على Windows Server 2019

تحرير: حدث هذا الخطأ بعد تحديث. Net Core SDK Preview 7 إلى. Net Core SDK Preview 8. بعد إعادة تشغيل الخادم ، يمكنني تشغيل تطبيقي بشكل صحيح مرة أخرى.

Safirion أجرينا تغييرًا على التنسيق الداخلي الأساسي حول هذه المعاينات. من الممكن أن تكون قد قمت بتبديل إخراج من معاينة واحدة وبنائها بمعاينة أخرى. لا توجد فواصل بين المعاينة 8 و 9.

في نظام التشغيل Linux ، يبدو أن مسار الاستخراج الافتراضي هو /var/tmp/.net. في AWS lambda ، لا يكون المسار / var قابلاً للكتابة ، لذا يفشل عمل هذا المجلد. للخروج من الصندوق ، قابلية التشغيل دون ضبط DOTNET_BUNDLE_EXTRACT_BASE_DIR ، أقترح تغيير هذا إلى /tmp/.net. أو ربما يجب أن تكون هناك محاولات متعددة في مواقع مشتركة (/ var / tmp ، / tmp ، نفس الدليل مثل ثنائي ، إلخ)

@ stevemk14ebr شكرًا للإبلاغ عن هذه المشكلة. هل يمكنك تقديم مشكلة جديدة لتتبع هذا العمل؟ https://github.com/dotnet/core-setup

jeffschwMSFT تم طرح نفس الخطأ بالمرور من Net Core P9 إلى RC1.

Description: A .NET Core application failed.
Application: Setup.exe
Path: C:\Users\Administrateur\Desktop\Setup.exe
Message: Failure processing application bundle.
Failed to determine location for extracting embedded files
A fatal error was encountered. Could not extract contents of the bundle

Safirion شكرا للإبلاغ عن هذه المشكلة. هل يمكنك إنشاء إصدار منفصل لإعادة بحث هذا؟ https://github.com/dotnet/core-setup
سم مكعب @ سواروب-سريدهار

Safirion هل يمكنك إرسال تعليمات Repro؟ هل هذا الفشل حتمية؟
يرجى تقديم مشكلة في مستودع الإعداد الأساسي ، كما اقترح jeffschwMSFT أعلاه.

نظرت إلى هذا ولن يحدث هذا إلا إذا كان التطبيق يعمل في بيئة لا يمكن الوصول إلى الدليل المؤقت فيها. على سبيل المثال ، إذا قمت بهذا:

set "TMP=wrong_path"
myapp.exe

فشل مع

Failure processing application bundle.
Failed to determine location for extracting embedded files
A fatal error was encountered. Could not extract contents of the bundle

لاحظ أن الحزمة تبحث عن دليل مؤقت باستخدام GetTempPath win32 API. الذي يستخدم البيئة. متغير TMP متبوعًا بـ TEMP وهكذا. إذا احتوت الأولى ذات القيمة على مسار غير صالح ، فسوف تفشل على هذا النحو.

يمكنك إصلاح هذا إما عن طريق التأكد من تعيين المسار المؤقت بشكل صحيح ، أو يمكنك تعيين DOTNET_BUNDLE_EXTRACT_BASE_DIR صراحةً إلى موقع تريد أن يحدث الاستخراج فيه.

Safirion هل يمكنك إرسال تعليمات Repro؟ هل هذا الفشل حتمية؟
يرجى تقديم مشكلة في مستودع الإعداد الأساسي ، كما اقترح jeffschwMSFT أعلاه.

لا يمكنني إعادة إظهار هذه المشكلة بعد تحديث .Net Core إلى RC1 وإعادة تشغيل الخادم. (لقد حاولت إلغاء تثبيت RC1 وتثبيت Preview 9 مرة أخرى للترقية مرة أخرى إلى RC1 ولكن يتم تشغيل تطبيقي جيدًا هذه المرة)

حدث هذا الخطأ مع المرور من SDK 3.0 P7 إلى SDK 3.0 P8 و SDK 3.0 P9 إلى SDK 3.0 RC1.
وفي الحالتين ، تؤدي إعادة التشغيل البسيطة للخادم إلى إصلاح المشكلة.

أستخدم .Net Core Windows Service (العامل الذي يستخدم المجلد C:\Windows\Temp\.net لاستخراجه منذ بدء تشغيله بواسطة النظام) وتطبيق Net Core WPF (التشغيل بواسطة البرنامج النصي لجلسة بدء تشغيل المستخدم) عندما أقوم بالترقية إلى RC1. ربما يكون هذا الخطأ ناتجًا عن .Net core worker يعمل أثناء تثبيت Net Core SDK ، لا أعرف ...

لاحظ أنني أقوم بتثبيت SDK وليس وقت التشغيل لأنني يجب أن أقوم بنشر 3. المثبت "(لم أجد حتى أداة تثبيت Desktop Runtime لذا ، لا يوجد خيار) ...

تحديث: فما باللك ، وجدت الوثائق .

مرحبًا ، شكرًا على عملك الشاق!

كيف يتم توزيع ملفات التكوين (App.config على سبيل المثال)؟ لقد قمت للتو بإنشاء تطبيق وحدة تحكم على RHEL 7.6 باستخدام تسلسل الأوامر الدقيق:

dotnet restore -r win-x64 --configfile Nuget.config
dotnet build Solution.sln --no-restore -c Release -r win-x64
dotnet publish --no-build --self-contained -c Release -r win-x64 /p:PublishSingleFile=true -o ./publish ./SomeDir/SomeProj.csproj

حيث تم تمكين <PublishTrimmed>true</PublishTrimmed> في SomeProj.csproj ، وحصلت على ملفين نتيجة لذلك: SomeProj.exe و SomeProj.pdb ، لكن ليس SomeProj.config

catlion للحصول على السلوك الافتراضي لملفات * .config ، يجب استبعادها من الحزمة. بشكل افتراضي ، يتم تضمين جميع الملفات التي ليست pdb في الحزمة.
ما يلي سوف يستبعد التكوين من الملف الفردي:

<ItemGroup>
    <Content Update="*.config">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
    </Content>
  </ItemGroup>

https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md#build -system-interface

تضمين التغريدة

ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)

تطبيقات بدون رأس و WPF لنظام التشغيل Windows

هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟

نعم ، نحن P / استدعاء لمجموعة متنوعة من dlls الأصلية ، وبعض عناصر الجهات الخارجية التي ليس لدينا سيطرة عليها ، وبعضها داخلي من فرق أخرى.

هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟

نعم ولكننا نستخدم CompilerServices لتجميعها من المصدر.

هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟

نعم

هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟

نعم ، يتم ترك تطبيقنا مفتوحًا بشكل عام لفترات طويلة من الوقت.

هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟

نعم ، يمكننا الانتظار عدة دقائق.

هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟

نعم

شكرا @ جون كولين

ربط عدد قليل من العلاقات العامة بفرع exe المفرد لتنفيذ نموذج أولي لتشغيل تطبيقات الملف الفردي دون استخراج ( المرحلة 4 ).

https://github.com/dotnet/coreclr/pull/26197
https://github.com/dotnet/coreclr/pull/26504
https://github.com/dotnet/coreclr/pull/26697
https://github.com/dotnet/coreclr/pull/26904

اسمح لي أيضًا بتقديم بعض الإجابات لـ @ morganbr :) لا أعرف ما إذا كنت لا تزال تقرأ هذه :)

  1. ما نوع التطبيق الذي من المحتمل أن تستخدمه معه؟ (على سبيل المثال WPF على Windows؟ ASP.NET في حاوية Linux Docker؟ شيء آخر؟)

مغامرات نصية (تطبيقات وحدة التحكم) ليتم تشغيلها على منصات مختلفة (Linux و MacOS و Windows)

  1. هل يشتمل تطبيقك على (بخلاف .NET) C ++ / رمز أصلي؟

رقم.

  1. هل سيقوم تطبيقك بتحميل المكونات الإضافية أو ملفات dll الخارجية الأخرى التي لم تقم بتضمينها في الأصل في بناء التطبيق الخاص بك؟

ليس حاليًا ، ولكن سيكون من الرائع على المدى الطويل دعم سيناريوهات معينة.

  1. هل أنت على استعداد لإعادة بناء وإعادة توزيع تطبيقك لدمج إصلاحات الأمان؟

نعم.

  1. هل ستستخدمه إذا بدأ تطبيقك 200-500 مللي ثانية بشكل أبطأ؟ ماذا عن 5 ثوان؟

نعم.
(سيكون من الرائع توفير بعض مخرجات النص أو مربع الرسائل لإعلام المستخدم بحدوث شيء ما)

  1. ما هو الحجم الأكبر الذي تعتبره مقبولاً لتطبيقك؟ 5 ميغا بايت؟ 10؟ 20؟ 50؟ 75؟ 100؟

10-20 ميغا بايت.

  1. هل تقبل إطالة وقت إصدار الإصدار لتحسين الحجم و / أو وقت بدء التشغيل؟ ما هي أطول مدة تقبلها؟ 15 ثانية؟ 30 ثانية؟ 1 دقيقة؟ 5 دقائق؟

1+ دقيقة على ما يرام.

  1. هل ستكون على استعداد للقيام بعمل إضافي إذا كان سيقلص حجم تطبيقك إلى النصف؟

ربما.

شكرا على الرد ، lenardg.

تتعقب هذه المشكلة التقدم المحرز في ميزة توزيع ملف واحد .NET Core 3.0.
إليك مستند التصميم وخطة التدريج للميزة.

هذه ميزة مفيدة جدًا لتسهيل النشر وتقليل الحجم.
القليل من أفكار التحسين على التصميم خاصة لعمليات النشر المؤسسية حيث يتم التحكم في البيئة بإحكام عبر سياسات المجموعة.

  1. هل من الممكن الضغط بشكل مشروط أثناء تعبئة الملف التنفيذي الفردي؟
    على سبيل المثال ، أضف Wrap like logic ، لذلك لا نحتاج إلى تكامل أدوات أخرى.
    سوف ينتج الملف المضغوط exe أصغر.

  2. عند بدء تشغيل exe ، فإنه يوسع محتوياته إلى مجلد مؤقت. بالنسبة لمنتجنا ، في بعض مواقع المستخدمين ، يتم التحكم بإحكام في أجهزة العملاء ولا تسمح بتشغيل الملفات التنفيذية من مجلد temp أو حتى مواقع٪ userprofile٪.

هل من الممكن تحديد / التحكم في مكان الاستخراج أو "استخراج في مكانه" في ". \ extract" أو مجلد فرعي؟
يسمح هذا بالامتثال لسياسات المجموعة بالإضافة إلى القدرة على استخدام ميزة exe الفردية.

  1. قبل التعبئة ، هل من الممكن التوقيع على المجلد ثم يختار الملفات لحزمها؟
    يمكننا التوقيع على exe المنفرد ، لكن ملفات الاستخراج غير موقعة ، وبالتالي في مواقع عملاء أخرى معينة ، لا يسمح بالتنفيذ ، ما لم يتم توقيع الثنائيات.

أردت فقط أن أخبرك ، رأيت نفس المشكلة مثل Safirion اليوم. لدي تطبيق dotnetcore 3.0 يستهدف ubuntu ، وذهبت لتشغيله على خادم Synology الخاص بي. لن يتم الاستخراج - استمر في الفشل مع ظهور الخطأ "حدث خطأ فادح. تعذر استخراج محتويات الحزمة". أعيد بناؤها عدة مرات ، ولكن نفس الشيء. بعد إعادة تشغيل المضيف ، عملت بشكل جيد مرة أخرى.

سيكون من المفيد معرفة ما إذا كان هناك قفل ملف أو شيء ما هنا ، وما إذا كانت هناك أوقات حول كيفية تصحيحه.

RajeshAKumar dotnet / core-setup # 7940

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

وقد أعطيتك الحل لأحدهم. ليس لدي أي فكرة عن الآخر 2

وقد أعطيتك الحل لأحدهم. ليس لدي أي فكرة عن الآخر 2

لا يعمل مستخلص درجة الحرارة بالنسبة لنا ، وبالتالي ليس هذا هو الحل. كان طلبي هو القدرة على التحكم في مكان استخراجها أو قد يتم استخراجه في مكانه في مجلد فرعي.
لا يسمح مسؤولو تكنولوجيا المعلومات في العديد من أجهزة الكمبيوتر العميلة لدينا بتشغيل الملفات القابلة للتنفيذ من مجلدات مؤقتة أو من ملف تعريف المستخدم.
يرجى إعادة قراءة المنشور https://github.com/dotnet/coreclr/issues/20287#issuecomment -542497711

RajeshAKumar : يمكنك تعيين DOTNET_BUNDLE_EXTRACT_BASE_DIR للتحكم في المسار الأساسي حيث يستخرج المضيف محتويات الحزمة.
يرجى الاطلاع على مزيد من التفاصيل هنا: https://github.com/dotnet/designs/blob/master/accepted/single-file/extract.md#extraction -location

RajeshAKumar : ضغط ملف exe المفرد المجمع هو ميزة قيد الدراسة لـ .net 5: https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md#compression

في الوقت الحالي ، ستحتاج إلى استخدام أدوات مساعدة أخرى لضغط ملف exe الذي تم إنشاؤه.

RajeshAKumar ، فيما يتعلق بالتوقيع ، يمكنك التوقيع على جميع الملفات / الثنائيات التي يتم نشرها وتجميعها في ملف exe المفرد. عندما يستخرج المضيف المكونات المضمنة إلى القرص ، سيتم توقيع الملفات الفردية نفسها. يمكنك أيضًا توقيع الملف الفردي المدمج نفسه ، كما ذكرت.

هل هذا يلبي متطلباتك؟

Webreaper إذا كان بإمكانك حل المشكلة ، فهل يمكنك تشغيل التطبيق مع تشغيل COREHOST_TRACE (اضبط متغير البيئة COREHOST_TRACE على 1 ) ومشاركة السجل الذي تم إنشاؤه؟ شكرا.

@ swaroop-sridhar
هذه ميزة رائعة جدا. هل لديك رابط حول وقت توفر مراحل مختلفة في أي إصدار من إصدارات dotnet؟

RajeshAKumar : يمكنك تعيين DOTNET_BUNDLE_EXTRACT_BASE_DIR للتحكم في المسار الأساسي حيث يستخرج المضيف محتويات الحزمة.
يرجى الاطلاع على مزيد من التفاصيل هنا: https://github.com/dotnet/designs/blob/master/accepted/single-file/extract.md#extraction -location

شكرا لك سواروب سريدهار

RajeshAKumar ، فيما يتعلق بالتوقيع ، يمكنك التوقيع على جميع الملفات / الثنائيات التي يتم نشرها وتجميعها في ملف exe المفرد. عندما يستخرج المضيف المكونات المضمنة إلى القرص ، سيتم توقيع الملفات الفردية نفسها. يمكنك أيضًا توقيع الملف الفردي المدمج نفسه ، كما ذكرت.

هل هذا يلبي متطلباتك؟

أحاول معرفة كيفية كسر "التجميع" ونشر الأجزاء.
أستخدم الأمر التالي حاليًا ، لذا فهو لا يمنحني القدرة على التوقيع.
عيّن publishargs = -c Release / p: PublishSingleFile = True / p: PublishTrimmed = True / p: PublishReadyToRun = false
dotnet publish -r win-x64 -o bin \ Output \ Win64٪ publishargs٪

نظرًا لأن المجموعات المذكورة أعلاه بالإضافة إلى الديكورات والحزم ، لست متأكدًا من كيفية كسرها.
من الناحية المثالية لاستخدام نهجك ، سيتعين علي تجميعه ثم التوقيع عليه ثم نشره أخيرًا.

Webreaper إذا كان بإمكانك حل المشكلة ، فهل يمكنك تشغيل التطبيق مع تشغيل COREHOST_TRACE (اضبط متغير البيئة COREHOST_TRACE على 1 ) ومشاركة السجل الذي تم إنشاؤه؟ شكرا.

شكرا. لقد اختفى الآن لأنني أعدت التشغيل ، لكن من المفيد ملاحظة ذلك إذا حدث مرة أخرى!

RajeshAKumar ، ستحتاج إلى وسم التوقيع لهدف يتم تشغيله قبل التجميع مباشرة.
نظرًا لأنك تستخدم PublishReadyToRun و PublishTrimmed فلا يمكنك استخدام أهداف Afterbuild أو BeforePublish .

يمكنك إضافة هدف يتم تشغيله قبل BundlePublishDirectory مباشرة ويقوم بالتوقيع.

@ swaroop-sridhar
هذه ميزة رائعة جدا. هل لديك رابط حول وقت توفر مراحل مختلفة في أي إصدار من إصدارات dotnet؟

شكراetherealjoy. العمل للملفات الفردية التي يتم تشغيلها مباشرة من الحزمة قيد التقدم ، ويستهدف إصدار .net 5 بأفضل ما أفهمه.

RajeshAKumar ، ستحتاج إلى وسم التوقيع لهدف يتم تشغيله قبل التجميع مباشرة.
نظرًا لأنك تستخدم PublishReadyToRun و PublishTrimmed فلا يمكنك استخدام أهداف Afterbuild أو BeforePublish .

يمكنك إضافة هدف يتم تشغيله قبل BundlePublishDirectory مباشرة ويقوم بالتوقيع.

شكرا لك.
يبدو الارتباط الذي قدمته مثل مهام MS Build.
كيف أقوم بإنشاء معالج لـ "BundlePublishDirectory"؟ هل هذا في Studio / Project Props / Build Events أو هل يجب علي إنشاء شيء ما من البداية.

RajeshAKumar في هذه الحالة ، ستحتاج إلى شيء أكثر دقة من أحداث ما قبل الإنشاء.
لذا ، أعتقد أنه يجب عليك تعديل ملف المشروع وإضافة شيء مثل:

<Target Name="Sign" BeforeTargets="BundlePublishDirectory">
    ... 
</Target>

ما هو السلوك المتوقع لأمر dotnet pack مع هذا؟ لنفترض أن لدينا قطعة أثرية أحادية exe تم دفعها إلى مستودع nuget المحلي. إذا حاولت تثبيته باستخدام chocolatey ، فإنه يحاول استعادة جميع أقسام nuget المدرجة في ملف المشروع. وهو ما كان متوقعا في السابق ولكني أشك في صحة هذا السلوك للصندوق الاجتماعي للتنمية.

هل من الممكن إضافة بعض شريط التقدم أو مؤشر التحميل أثناء استخراج ملف واحد من تطبيق WPF المستقل ذاتيًا ، فقد يستغرق الأمر بعض الوقت دون حدوث أي شيء.
تطبيق WPF الأساسي القائم بذاته أكثر من 80Mo ويمكن أن يستغرق الاستخراج أكثر من 5 ثوانٍ. إنها ليست سهلة الاستخدام وقد تلقيت شكاوى من المستخدمين النهائيين.

تحرير: هل من طريقة لتنظيف الإصدار القديم تلقائيًا عند الإطلاق؟

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

ProfessionalNihilist أعتقد أنك لا تفهم وجهة نظري.
يستخدم تطبيق WPF الفارغ المستقل ذاتيًا 80m من مساحة تخزين القرص عند تجميعه. لا يمكنك الحصول على تطبيق WPF أصغر من 80mo بدون تجميعه كتطبيق يعتمد على إطار العمل 😉
تكمن المشكلة في وقت استخراج إطار العمل المضمن قبل بدء تشغيل التطبيق. لذلك يجب أن يتم ذلك بواسطة .Net Core وهو مرتبط كليًا بهذه الميزة.

ربما تضيف القدرة على الحصول على png الذي سيظهر أثناء فك ضغط التطبيق؟

Safirionayende يتم تتبع عدم وجود "ملاحظات على واجهة المستخدم" أثناء بدء التشغيل هنا: https://github.com/dotnet/core-setup/issues/7250

ما هو السلوك المتوقع لأمر dotnet pack مع هذا؟ لنفترض أن لدينا قطعة أثرية أحادية exe تم دفعها إلى مستودع nuget المحلي. إذا حاولت تثبيته باستخدام chocolatey ، فإنه يحاول استعادة جميع أقسام nuget المدرجة في ملف المشروع. وهو ما كان متوقعا في السابق ولكني أشك في صحة هذا السلوك للصندوق الاجتماعي للتنمية.

catlion الخاصية PublishSingleFile مدعومة فقط بواسطة الأمر dotnet publish . لذلك ، ليس له أي تأثير على dotnet pack . هل هناك دافع لاستخدام كل من الملف الفردي والتعبئة والتغليف؟

تحرير: هل من طريقة لتنظيف الإصدار القديم تلقائيًا عند الإطلاق؟

Safirion في الإصدار الحالي ، التنظيف يدوي ، المضيف لا يحاول إزالة الملفات المستخرجة ، لأنه من المحتمل إعادة استخدامها في عمليات التشغيل المستقبلية.

حسنًا ، سأصنع منظف بنفسي 😉
شكرا لك على الرد.

cup ليس شيئًا مميزًا حول mono ، هذا مجرد تجميع قياسي ، أضف الآن مرجع nuget وهذا الحل لم يعد ملفًا واحدًا. لدى Mono mkbundle على الرغم من تحقيق ملف واحد

Suchiman هل أنت متأكد؟ ينتج عن المثال أعلاه ملف واحد بحجم 3 كيلوبايت. بينما يبدو أن الحد الأدنى لحجم dotnet هو 27 ميغابايت:

https://github.com/dotnet/coreclr/issues/24397#issuecomment -502217519

@ كأس نعم

C:\Users\Robin> type .\Program.cs
using System;
class Program {
   static void Main() {
      Console.WriteLine("sunday monday");
   }
}
C:\Users\Robin> C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe .\Program.cs
Microsoft (R) Visual C# Compiler version 4.8.3752.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240

C:\Users\Robin> .\Program.exe
sunday monday
C:\Users\Robin> dir .\Program.exe


    Verzeichnis: C:\Users\Robin


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       10.11.2019     18:36           3584 Program.exe

Suchiman هل أنت متأكد؟ ينتج عن المثال أعلاه ملف واحد بحجم 3 كيلوبايت. بينما يبدو أن الحد الأدنى لحجم dotnet هو 27 ميغابايت:

# 24397 (تعليق)

ملف 3k الخاص بك لا يعمل إلا لأنه تم تثبيت mono بالفعل. بيت القصيد من توزيع الملف الفردي dotnetcore هو أنك لست بحاجة إلى تثبيت clr ، إنه ملف exe فردي مستقل بما في ذلك وقت التشغيل.

Webreaper في الواقع أعتقد أنه استخدم فقط mcs من mono إلى compile ، لأنه لم يكتب mono sun-mon.exe فمن المحتمل أنه تم تشغيله على .NET Framework.

لكن NET Core يدعم سيناريو وقت التشغيل الذي يتم تثبيته مسبقًا أيضًا ، ويعرف أيضًا باسم النشر المعتمد على إطار العمل. لا يزال نشر ملف واحد فقط في هذه الحالة على الرغم من وجود بعض الملفات الإضافية لـ .NET Core مثل .deps.json و .runtimeconfig.json

@ chris3713 أفضل طريقة للوصول إلى موقع exe حاليًا هي عن طريق PInvoke-ing إلى واجهات برمجة التطبيقات الأصلية. على سبيل المثال: GetModuleFileNameW (Null, <buffer>, <len>)

يبدو أن Environment.CurrentDirectory هو حل أفضل ، على الرغم من أنني لم أجرب كلا الأسلوبين على شيء آخر غير Windows حتى الآن.

تحرير: كلا. هذا المسار عرضة للتغيير في نقاط الدخول المختلفة في التطبيق. ليس جيد.

في ملاحظة ذات صلة قليلاً ، وجدت هذا الانحدار في نشر ملف واحد لتطبيقات Blazor في أحدث معاينة لـ VS لنظام التشغيل Mac: https://github.com/aspnet/AspNetCore/issues/17079 - لقد أبلغت عنه ضمن AspNeCore / Blazor ، ولكن قد يكون هذا أكثر صلة بمجموعة coreclr - لست متأكدًا. سوف اتركها لكم يا رفاق للتحرك!

Suchiman حذرا ، هذا المترجم لديه مشاكل:

https://github.com/dotnet/roslyn/issues/39856

cup فيما عدا ذلك باستخدام مسار الملف الذي قمت بتسميته ، فأنت تستخدم مترجم C # 5 القديم المكتوب بلغة C ++ ، وهذا ليس roslyn ومن المحتمل أنهم سيغلقون هذه المشكلة لهذا السبب. لكن روزلين يمكنها أن تفعل الشيء نفسه ، فقط مسار مختلف ...

في ملاحظة ذات صلة قليلاً ، وجدت هذا الانحدار في نشر ملف واحد لتطبيقات Blazor في أحدث معاينة لـ VS لنظام التشغيل Mac: aspnet / AspNetCore # 17079 - لقد أبلغت عنه ضمن AspNeCore / Blazor ، ولكن قد يكون هذا هو أكثر صلة بمجموعة coreclr - لست متأكدًا. سوف اتركها لكم يا رفاق للتحرك!

Webreaper نشكرك على الإبلاغ عن المشكلة ، والتي تبدو وكأنها مشكلة ASP.net تتعلق بالأصول الثابتة. لذلك ، هذا هو المكان المناسب لتقديمه.

* نقل المنشور من قضية أخرى إلى هنا.

@ swaroop-sridhar ،

أوقات بدء تشغيل تطبيقات DotNet Core Single File WPF أبطأ بكثير من تطبيق ILMerge-ed WPF الأصلي المبني على .net 4.7. هل هذا متوقع أم سيتحسن في المستقبل؟

تأتي الأبنية من ImageOptimizer الخاص بي: https://github.com/devedse/DeveImageOptimizerWPF/releases

| اكتب | الوقت المقدر لبدء التشغيل | وقت بدء التشغيل الثاني المقدر | الحجم | رابط التحميل |
| - | - | - | - | - |
| NET 4.7.0 + ILMerge | ~ 3 ثوانٍ | ~ 1 ثانية | 39.3 ميجابايت | رابط |
| dotnet publish -r win-x64 -c الإصدار - محتوي ذاتيًا = خطأ / p: PublishSingleFile = صحيح | ~ 10 ثوانٍ | ~ 3 ثوانٍ | 49 ميجابايت | |
| dotnet publish -r win-x64 -c Release / p: PublishSingleFile = true | ~ 19 ثانية | ~ 2 ثانية | 201 ميجابايت | |
| dotnet publish -r win-x64 -c Release / p: PublishSingleFile = true / p: PublishTrimmed = true | ~ 15 ثانية | ~ 3 ثوانٍ | 136 ميغا بايت | رابط |
| dotnet publish -r win-x64 -c الإصدار | ~ 2.5 ثانية | ~ 1.5 ثانية | 223 كيلوبايت لـ exe (+ 400 ميجابايت في dlls) | |

devedse ، للتأكد ، هل "بدء التشغيل الثاني" هو متوسط ​​عدة أشواط (بخلاف الأولى)؟
لدي فضول ، لكني أفتقر إلى أي تفسير لماذا يجب أن يكون تشغيل /p:PublishSingleFile=true /p:PublishTrimmed=true أبطأ من ` /p:PublishSingleFile=true run.

لذا ، قبل التحقيق ، أريد التأكد من أن الأرقام الواردة في "بدء التشغيل الثاني" ثابتة وأن الاختلاف في بدء التشغيل قابل للتكرار ،

أيضًا ، هذه المشكلة تتعلق بالمكونات الإضافية ذات الملف الفردي ، هل يمكنك من فضلك نقل مناقشة الأداء إلى إصدار جديد ، أو إلى dotnet / coreclr # 20287؟ شكرا.

@ swaroop-sridhar ، ردًا على سؤالك حول كونها المتوسط:
من الصعب بعض الشيء بالنسبة لي تحديد توقيت دقيق للغاية ، لذلك تم تحديد التوقيت من خلال العد أثناء بدء التطبيق ثم تجربته عدة مرات لمعرفة ما إذا كان هناك فرق كبير في وقت بدء التشغيل. إذا كنت على دراية بطريقة أفضل ، فيمكنك إعادة إنتاجها بسهولة من خلال بناء الحل الخاص بي: https://github.com/devedse/DeveImageOptimizerWPF

سؤالي الرئيسي يتعلق لماذا يستغرق تطبيق مجمع (ملف واحد) وقتًا أطول مقارنةً بملف exe غير المجمّع.

قد أكون مخطئًا هنا ولكن هذا منطقي بالنسبة لي نظرًا لوجود عبء مع ملف واحد. في الأساس ، لديك تطبيق يبدأ تطبيقًا آخر. بينما يبدأ ILMerge مباشرة. قامت ILMerge بدمج ملفات dll المشار إليها فقط في ملف exe ، ولم تقم بتغليف كل شيء في طبقة أخرى وهو ما يتم إجراؤه حاليًا باستخدام PublishSingleFile.

devedse الملف الفردي هو في الأساس استخراج وفحص المجاميع الاختبارية وما إلى ذلك قبل بدء تشغيل dotnet.
أعتقد أن هذا هو السبب في أن الأمر استغرق ذلك الوقت.
الاستخراج "مخبأ" ، لذا عند التشغيل التالي ، لا يوجد حمل إدخال / إخراج (IO).

RajeshAKumar ، حسنًا ، هل استخرج حقًا الطريق للذهاب في هذا السيناريو؟ ألن يكون من الأفضل السير بطريقة ILMerge ودمج DLL في حزمة واحدة؟

خاصة بالنسبة لملفات exe الكبيرة ، فأنت أيضًا تحفز تكلفة مساحة القرص لتخزين جميع الملفات مرتين بعد ذلك.

devedse نحن جميعًا ننتظر المراحل التالية من هذه الميزة (Run from Bundle) لكنها في الوقت الحالي هي الحل الوحيد. 😉

https://github.com/dotnet/designs/blob/master/accepted/single-file/staging.md

هذا ما تحصل عليه عند استخدام JIT في سطح المكتب ، بدء التشغيل البطيء ، يبدو أن Apple فقط فهمت ذلك

(في الغالب يرددون ما سبق):
من المتوقع أن تكون البداية الأولى أبطأ بكثير - فهي تستخرج التطبيق على القرص - الكثير من الإدخال / الإخراج. يجب أن تكون عمليات البدء الثانية واللاحقة مطابقة تقريبًا لإصدار التطبيق غير ذي الملف الفردي. في قياساتنا الداخلية لم نلحظ أي فرق.

كيفية القياس: استخدمنا التتبع (ETW على Windows) - هناك أحداث تبدأ عند بدء العملية ثم توجد أحداث وقت تشغيل يمكن استخدامها لهذا الغرض - ليس الأمر سهلاً تمامًا.

كما ذكر من قبل Safirion ، نحن نعمل على التحسين التالي للملف الفردي والذي يجب أن يشغل معظم الكود المدار من. exe مباشرة (بدون استخراج إلى القرص). لا يمكن أن أعد قطار إطلاق حتى الآن.

JIT: يجب تجميع كل إطار العمل مسبقًا باستخدام Ready2Run (CoreFX ، WPF) ، لذلك عند بدء التشغيل ، يجب أن يكون رمز التطبيق فقط JITed. إنها ليست مثالية ، لكن يجب أن تحدث فرقًا كبيرًا. بالنظر إلى زمن بدء التشغيل ~ 1-2 ثانية ، أعتقد أنه يستخدم ذلك بالفعل في جميع الاختبارات.

شكرًا لكم جميعًا ، لم أكن على دراية بالخطوات التالية المخطط لها. هذا يوضحها.

من المتوقع أن تكون البداية الأولى أبطأ بكثير - فهي تستخرج التطبيق على القرص - الكثير من الإدخال / الإخراج.

كان من المفترض ألا يحدث هذا أبدًا ، فأنت تجعل تجربة المستخدم مروعة بالتصميم ، واختيارًا مروعًا ، وهذا هو ما تجعل المستخدمين يكرهون التكنولوجيا التي يستخدمها المطور لهم

كما ذكر من قبل Safirion ، نحن نعمل على التحسين التالي للملف الفردي والذي يجب أن يشغل معظم الكود المدار من. exe مباشرة (بدون استخراج إلى القرص). لا يمكن أن أعد قطار إطلاق حتى الآن.

لماذا يتم إصدار هذا رسميًا الآن إذا كان سيتغير قريبًا؟ يجب وضع علامة معاينة / تجريبية

في رأيي ، هذا مضيعة للوقت والموارد ، ركز على تجميع AOT وهز الأشجار ، ضع كل مواردك هناك ، توقف عن الاختراقات

RUSshy لماذا كل هذا الكراهية؟ إذا كنت لا تريد تأخير بدء التشغيل عند بدء التشغيل لأول مرة ، فلا تستخدم نشر ملف واحد.

أجد أن بدء التشغيل أقل بكثير من 10 ثوانٍ ، وبما أنها المرة الأولى التي تعمل فيها فقط ، فلا مشكلة على الإطلاق. أقوم بنشر تطبيق ويب من جانب الخادم مما يعني في معظم الحالات أنه سيبدأ مرة واحدة ثم يعمل لأيام / أسابيع ، لذا فإن الاستخراج الأولي لا يكاد يذكر في مخطط الأشياء - لذلك أفضل هذا كثيرًا باعتباره توقف الفجوة حتى تكون هناك صورة مجمعة واحدة ، لأنها تجعل النشر أسهل بكثير من نسخ مئات مكتبات DLL في جميع أنحاء المكان.

+1 في حالتي ، لدينا عامل بناء ينشئ exe واحدًا ، و docker منفصل لتشغيل التطبيق (باستخدام صورة عامل إرساء جبال الألب العادية بدون dotnet). بعد خطوة البناء ، نقوم بتحميل حاوية وقت التشغيل مرة واحدة و docker-commit الطبقة. بعد ذلك ، لم نلاحظ أي تراجع في الأداء مقارنة بالنشر المعتمد على إطار العمل. بمجرد تنفيذ آلية تحميل الملف من الحزمة وشحنها ، سنزيل خطوة التحميل الساخن الوسيطة.

@ vitek-karas ، هل هناك مشكلة في تتبع ميزة "تحميل أصول وقت التشغيل من الحزمة"؟ مهتم بفهم نوع العوائق الموجودة. :)

@ am11 نقوم حاليًا بتجميع الخطة التفصيلية. يمكنك إلقاء نظرة على النموذج الأولي الذي تم إجراؤه في https://github.com/dotnet/coreclr/tree/single-exe. من المحتمل ألا يكون التنفيذ الحقيقي مختلفًا جدًا (من الواضح أن العوملة أفضل وما إلى ذلك ، ولكن يبدو أن الفكرة الأساسية سليمة).

Webreaper بالنسبة لتطبيقات الويب ، فهي ليست مشكلة على الإطلاق ولكن ربما لأن NET Core 3 موصى به لتطوير WPF / WinForm الآن ، وأن مشاركة تطبيق سطح المكتب. فهم الإحباط المرتبط بالمرحلة الأولى من هذه الميزة.
؛)

ولا ينتظر أي مستخدم 10 ثوانٍ (أو أكثر من 3 ثوانٍ) قبل إعادة النقر فوق exe اليوم. حقيقة عدم وجود مؤشر تحميل هي المشكلة الثانية الكبيرة لهذه الميزة. لسوء الحظ ، يبدو أن مؤشر التحميل لن يكون جزءًا من .Net Core 3.1 لذلك سيتعين على المستخدمين التحلي بالصبر ...

ينتظر مطورو سطح المكتب بالفعل المرحلة 2 ، وأتوقع أن يكون ذلك جزءًا من .Net 5 لأن تطوير سطح المكتب في .Net Core يعد تجربة سيئة حقًا للمستخدمين النهائيين.

RUSshy لماذا كل هذا الكراهية؟ إذا كنت لا تريد تأخير بدء التشغيل عند بدء التشغيل لأول مرة ، فلا تستخدم نشر ملف واحد.

هذه ليست كره ، هذه ردود فعل بناءة وصادقة ، أنا مهتم بـ C # و. net ، أستخدم كليهما كل يوم ، لا أريد استبداله بـ GO أو أي شيء آخر

مؤخرا:
https://old.reddit.com/r/golang/comments/e1xri3/choosing_go_at_american_express/
https://old.reddit.com/r/golang/comments/ds2z51/the_stripe_cli_is_now_available_and_its_written/

ردود الفعل السلبية مفيدة مثل ردود الفعل الإيجابية ، ولكن إذا كنت تعتبرها "كره" فلا يمكنني مساعدتك

مجتمع .net هو الطريق إلى الصمت والسلبي والمنحاز ، والاضطراب هو السبيل الوحيد للذهاب

يعد .NET أفضل منصة بشكل موضوعي لمعظم التطبيقات هذه الأيام. أتمنى أن يدرك المزيد من الناس ذلك.

قصص الحرب التي أسمعها من منصات أخرى مثل Java و Go و Rust و Node ... مزعجة بصراحة. هذه المنصات قاتلة للإنتاجية.

في رأيي ، هذا مضيعة للوقت والموارد ، ركز على تجميع AOT وهز الأشجار ، ضع كل مواردك هناك ، توقف عن الاختراقات

أنا موافق. يحتوي .Net على نظام كتابة رائع. في كثير من الأحيان يتم التحايل عليه باستخدام الانعكاس. تحتاج الأدوات إلى التركيز على AOT ولكن أيضًا على تقليل التفكير. https://github.com/dotnet/corert/issues/7835#issuecomment -545087715 ستكون بداية جيدة جدًا. يتم الآن التخفيف من خطأ المليار دولار الخاص بالقيم الخالية ؛ يجب أن يتم نفس الشيء مع الانعكاس باستخدام إعداد أو علامة لرمز خالٍ من الانعكاس (أو بطريقة أخرى رمز متوافق مع رابط أو محكم).

القضاء على التفكير سيكون رائعا. يمكن تجنب الكثير من المعاناة إذا تم حظر التفكير. كانت آخر قصة رعب لدي هي اكتشاف أنني لا أستطيع نقل الكود لأن الإطار المستخدم (خدمة النسيج SDK) وجد أنه من الحكمة ربط وحدات البايت المتسلسلة باسم تجميع تنفيذ المسلسل دون إمكانية تجاوز.

أي تقدم نحو تثبيط التفكير سيكون تقدمًا.

كانت Btw تبحث عن طريقة لدمج التجميعات لتقليل حجم الحزمة وأوقات التحميل ، والسماح بتحسين البرنامج بالكامل. أجمع أن هذه المشكلة لا تستهدف ذلك حقًا.

تحرير: نظرًا لأن هذا المنشور جمع بعض ردود الفعل للتوضيح فقط. أعتقد أن البرمجة الوصفية يجب أن تحدث في وقت التصميم ، حيث الرمز هو البيانات ، وهو تحت سيطرتي.

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

ومن ثم أود استبدال انعكاس وقت التشغيل ببرمجة وصفية لوقت التصميم. حيث يمكن أن يكون أيضًا تداخلًا أكثر قوة مع حالات الاستخدام مثل أجهزة التحليل والإصلاحات السريعة وإعادة البناء.

وسم المشتركين في هذه المنطقة: @ swaroop-sridhar
قم بإخطار danmosemsft إذا كنت تريد الاشتراك.

تصميم ميزة الملف الفردي موجود في هذا المستند: https://github.com/dotnet/designs/blob/master/accepted/2020/single-file/design.md
تتبع تقدم تطبيقات الملف الفردي في هذه المشكلة: https://github.com/dotnet/runtime/issues/36590.
شكرا للجميع على ملاحظاتكم واقتراحاتكم في هذا الموضوع.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات