MSI와 EXE의 차이점


MSI 파일은 최신 Microsoft Windows 시스템에서 소프트웨어를 설치, 유지 관리 및 제거하는 데 사용되는 실행 파일입니다. 
EXE 파일은 '실행 파일'의 줄임말이며 확장명은 .exe입니다. 
실행 파일의 주된 목적은 컴퓨터에 이미 설치되어있는 파일을 설치하거나 실행하는 것입니다.

컴퓨터에 소프트웨어를 설치하려면 인터넷을 통해 구매하거나 무료로 다운로드하여 설치 프로그램을 다운로드해야합니다. 
소프트웨어, MIS 또는 EXE를 설치하는 동안 발생할 수있는 두 가지 유형의 파일이 있습니다. 
이 두 파일은 실행 가능 확장 파일입니다. 
이 두 파일은 동일한 기능을 수행하지만 설치 및 실행 프로그램은 다른 방식으로 수행합니다.

MSI 파일은 최신 Microsoft Windows 시스템에서 소프트웨어를 설치, 유지 관리 및 제거하는 데 사용되는 실행 파일입니다. 
'MSI'라는 용어는 Microsoft Installer라는 이름에서 파생되었으며 Windows Installer로 변경되었습니다. 
MSI 파일에 대한 정보는 설치 패키지에 저장되며 파일의 확장자는 .msi입니다. 
MSI 파일은 windows installer와 함께 사용되며 프로세스를 시작하거나 응용 프로그램을 실행하기 위해 EXE 파일이 필요합니다. 
MSI 파일은 Windows 업데이트 또는 응용 프로그램에 Microsoft에서 가장 일반적으로 사용됩니다.

MSI 파일을 두 번 클릭하면 Windows Installer가 화면에 팝업으로 나타나 패키지에서 파일 추출을 시작하고 사용자가 지정한 드라이브에 필요한 폴더와 파일을 만들고 패키지에 언급 된 바로 가기도 만들 수 있습니다 . MSI 파일은 MAC 컴퓨터에서 실행되지 않으며 적절한 변환 소프트웨어를 사용하여 EXE 파일로 변환해야합니다. MSI 파일 사용의 이점은 무인 설치를 위해 설계되었으므로 설치 관리자가 파일 다운로드를 위해 할당 된 키 입력 또는 클릭 기록을 유지할 수 있다는 것입니다. MSI 파일을 사용하면 얻을 수있는 또 다른 이점은 표준 GUI를 사용할 수 있다는 것입니다. 표준 GUI는 특정 수준으로 사용자 지정할 수 있으며 자신의 인터페이스를 만드는 복잡성을 제거합니다. MSI는 또한 주문형 설치 옵션을 제공합니다.
이 옵션은 컴퓨터에 부 파일 만 다운로드하고 응용 프로그램을 처음 실행할 때 나머지 파일을 다운로드합니다.

EXE 파일은 '실행 파일'의 줄임말이며 확장명은 .exe입니다. 
실행 파일의 주 목적은 다음과 같은 파일을 설치하거나 실행하는 것입니다.
컴퓨터에 이미 설치되어 있습니다. 
컴퓨터에 설치된 MSI 파일조차도 특정 파일을 실행하기 위해 하나 또는 두 개의 EXE 파일이 있습니다. 
EXE 파일을 사용하면 개발자가 설치 프로그램이 사용자와 상호 작용하는 방법에 대한 모든 자유를 얻을 수 있습니다. 
이러한 파일은 최신 게임 파일을 실행하는 데 가장 일반적으로 사용됩니다. 
이 게임 설치 프로그램은 대화식의 다채로운 인터페이스를 사용하여 패키지를 설치하는 동안 사용자를 즐겁게합니다.
EXE 파일은 거의 모든 운영 체제와 호환되지만 DOS, OpenVMS, Microsoft Windows, Symbian 및 OS / 2에서 가장 일반적으로 사용됩니다. 
실행 가능한 프로그램과 함께 많은 EXE 파일은 리소스라고하는 다른 구성 요소도 포함합니다. 
여기에는 실행 가능 프로그램이 GUI 용으로 사용할 수있는 비트 맵 및 아이콘이 포함될 수 있습니다. 
설치하는 동안 선택 사항을 기억할 수있는 MSI 파일과 달리 EXE 파일은 설치하는 동안 사용자가 '확인'또는 '다음'을 클릭해야 할 수 있습니다. 
EXE 파일은 위험한 파일로 간주되어 알려지지 않은 파일은 바이러스 또는 기타 악의적 인 루틴을위한 전송 시스템으로 사용할 수 있으므로 다운로드하지 않아야합니다.
소프트웨어 설치 프로그램을 개발할 때 선택할 실행 파일 유형을 결정하려면 설치 프로그램에 넣으려는 프로그램의 양과 노력 정도에 따라 결정하십시오. 
EXE를 사용하면 사용자 지정 가능한 옵션으로 설치 프로그램을 만들 수 있지만 MSI는 미리 설정된 표준을 준수하여 작업을 단순화합니다.




using System.Runtime.InteropServices;

class UAPDBMQ0010 : Form
{
IntPtr tailHandle = IntPtr.Zero;
System.Timers.Timer tm = new System.Timers.Timer();
string qryText = "";

[DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string strClassName, string strWindowName);
        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

public UAPDBMQ0010(IntPtr prmHandle, string qryFileName)
{
tailHandle = prmHandle;

tm.Elapsed += new ElapsedEventHandler(____time_tick);
qryText = System.IO.File.ReadAllText(qryFileName);
}
void ____time_tick(object sender, ElapsedEventArgs e)
{
try
                {
                    byte[] dataByte = Encoding.UTF8.GetBytes(qryText);

                    COPYDATASTRUCT copyData = new COPYDATASTRUCT();
                    copyData.dwData = (IntPtr)0;
            copyData.cbData = dataByte.Length;
                    copyData.lpData = Marshal.AllocHGlobal(dataByte.Length);
                    Marshal.Copy(dataByte, 0, copyData.lpData, dataByte.Length);

                    IntPtr sendData = Marshal.AllocHGlobal(Marshal.SizeOf(copyData));
                    Marshal.StructureToPtr(copyData, sendData, true);

                    IntPtr _result = SendMessage(tailHandle, APMApiPublic.WM_COPYDATA, (IntPtr)index, sendData);

                    Marshal.FreeHGlobal(copyData.lpData);
                    Marshal.FreeHGlobal(sendData);
                }
                catch (Exception exp)
                {
                    Console.WriteLine(exp.Message);
                }
}
}

class APMCommManage : Form
{
IntPtr currentHandle = IntPtr.Zero;

public APMCommManage()
        {
            currentHandle = Handle;
        }
protected override void WndProc(ref Message m)
{
const int WM_PAINT=0x000f;

base.WndProc(ref m);

switch(m.Msg)
{
case WM_PAINT:
break;
default:
break;
}
}
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
const int WM_KEYDOWN=0x0100;

if(m.Msg==WM_KEYDOWN)
{
switch(keyData.ToString())
{
case "Return":
Console.WriteLine("HANDLE:" + "[" + currentHandle.ToString() + "]");
break;
case "Right":
break;
case "Left":
break;
case "Space":
DBMS2022FRM dbms2022frm  = new DBMS2022FRM(currentHandle, "QUERY.567342.001");
dbms2022frm.Show();
break;
case "Escape":
Application.Exit();
break;
default:
break;
}
}
return base.ProcessCmdKey(ref m, keyData);
}
}


class Program
{
public static void Main()
{
DebugManage nm = new DebugManage();

nm.running();
}
}

public struct COPYDATASTRUCT
{
public IntPtr dwData {get; ste;}
public int cbData {get; ste;}
public IntPtr lpData {get; ste;}
}

public class RcvDefaultResult
{
public string code { get; set; }
public string text { get; set; }
public List<List<string>> data { get; set; }
}
public class PWInterface
{
private RcvDefaultResult _result;
public string id { get; set; }
public string sender { get; set; }
public string proto { get; set; }

public RcvDefaultResult result
{
get { return _result; }
set { _result = value; }
}
}
class DebugManage
{
class dataInterface
{
public List<List<string>> data {get; set;}
}

public void running()
{
int ii,kk;
string formatText="";

COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
byte[] recvData = new byte[cds.cbData];
Marshal.Copy(cds.lpData, recvData, 0, cds.cbData);
FormatText = Encoding.UTF8.GetString(recvData);


try
{
PWInterface ifRecieve = JsonConvert.DeserializeObject<PWInterface>(formatText);

//ifRecieve.result.code
//ifRecieve.result.text
//ifRecieve.result.data.Count
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
try
{
JObject jobject = JObject.Parse(formatText);

string screen = jobject["id"].ToString().Substring(0+1+5+1, 10);
string mmm = jobject["result"].ToString();

dataInterface data;
data = JsonConvert.DeserializeObject<dataInterface>(mmm);

for(kk=0; kk<data.data.Count; kk++)
{
List<string> mmm_mmm = data.data[kk];

for(ii=0; ii<mmm_mmm.Count; ii++)
{
Console.WriteLine(mmm_mmm[ii].ToString());
}
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}

protected override void WndProc(ref Message m)
{
base.WndProc(ref m);

switch (m.Msg)
{
case WM_COPYDATA:
break;

default:
break;
}
}







/*
//JSON FORMAT

{
"teamname": "My Team",
"etc": "master group",
"members": [{
"name": "Mad Dog",
"age": 36,
"job": "Engineer",
"sex": "male",
}, {
"name": "Angry Bird",
"age": 30,
"job": "self-employment",
"sex": "female",
}]
}

json parsing - JsonConvert.DeserializeObject
json 문자열을 클래스로 바로 파싱을 하려면 JsonConvert 객체의 DeserializeObject 함수를 이용하면 됩니다.

json 변환 - JsonConvert.SerializeObject
클래스를 json 문자열로 변환할때는 JsonConvert의 SerializeObject 를 이용하면 됩니다.

string json = JsonConvert.SerializeObject(Teams, Formatting.None);
*/



using System;
using System.Linq;
using System.Collections.Generic;


#if(true)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
#endif

class Program
{
public static void Main(string[] args)
{
DeserializeObjectManage nm = new DeserializeObjectManage();
nm.running();
}
}
class DeserializeObjectManage
{
public class clTeams
{
public string teamname;         //json 항목명과 동일해야함 (대소문자 구분)
public string etc;              //json 항목명과 동일해야함 (대소문자 구분)

public List<clMember> members;  //json 항목명과 동일해야함 (대소문자 구분)
}

public class clMember
{
public string name;
public int age;
public string job;
public string sex;
}

public void running()
{
string jsontext = "{ \"teamname\": \"My Team\", \"etc\": \"master group\", \"members\": [{ \"name\": \"Mad Dog\", \"age\": 36, \"job\": \"Engineer\", \"sex\": \"male\", }, { \"name\": \"Angry Bird\", \"age\": 30, \"job\": \"self-employment\", \"sex\": \"female\", }]}";

clTeams Teams; //선언해준 클래스

Teams = JsonConvert.DeserializeObject<clTeams>(jsontext);

Console.WriteLine(Teams.members.Count);

for (int kk = 0; kk < Teams.members.Count; kk++)
{
Console.WriteLine(Teams.members[kk].name);
Console.WriteLine(Teams.members[kk].age);
Console.WriteLine(Teams.members[kk].job);
Console.WriteLine(Teams.members[kk].sex);
}
}
}

/*
csc /reference:Newtonsoft.Json.Net20.dll /out:form_6.exe form_6.cs
csc /reference:Newtonsoft.Json.Net20.dll /out:form_6.exe form_6.cs
csc /reference:Newtonsoft.Json.Net20.dll /out:form_6.exe form_6.cs
*/

1. SendMessage.cs(Timer, Background)
- 데이타를 Title을 Handle로 잡아서, 송신한다.

2. ReceiveMessage.cs
- 데이타를 Title을 Handle로 잡아서, 수신한다.

send_msg.cs
0.01MB
send_msg_2.cs
0.01MB
recv_msg.cs
0.00MB

 

KEY POINT)주고 받는, 메세지의 길이가 명확해야 한다.

/*Singletone Pattern sample*/

using System;
using System.Drawing;

public class APMMemory
{
    private static APMMemory apmMemory=null;
    string ____processid;
    System.Drawing.Color ____bgColor;

    public static APMMemory GetInstance
    {
        get
        {
            if(apmMemory == null)
            {
                apmMemory=new APMMeory();
                Console.WriteLine("Singletone Pattern sample");
            }
        }
    }
    public string processid
    {
        get{return ____processid;}
        set{___processid=value;}
    }
    public System.Drawing.Color bgColor
    {
        get{return ____bgColor;}
        set{____bgColor=value;}
    }
}
class SampleManage
{
    public void running()
    {
        Console.WriteLine("" + APMMemory.GetInstance.processid);
        Console.WriteLine("" + APMMemory.GetInstance.bgColor);
    }
}
class Program
{
    public static void Main()
    {
        APMMemory.GetInstance.processid = "9999";
        APMMemory.GetInstance.bgColor=System.Drawing.Color.SteelBlue;

        SampleManage nm = new SampleManage();
        nm.running();
    }
}

C Pattern(C로 만드는 Interface)

Java에서는 객체지향, 패턴, Interface을 빼놓고는 아무것도 아닙니다. Interface를 사용해야 언제든지 교체가능한 모듈형태의 프로그래밍을 할 수 있습니다.
Interface의 필요성에 대해서는 다른 곳에도 많이 나와 있기때문에 따로 설명하지 않겠습니다. C로 Interface를 만들어 보겠습니다. 이번에 만들 Interface는 UART입니다.
UART는 MCU와 Device와의 커뮤니케이션 도구로 많이 사용합니다. 예를 들면 GPS Module, RS232를 통한 PC와의 통신 등등에서 사용되므로 Interface를 설명하기에 적합합니다. 

typedef struct
{
    InitFunction Init;
    OpenFunction Open;
    TxHandlerFunction TxHandler;
    RxHandlerFunctioin RxHandler;
    //....(필요시 추가)

}UartInterface;



우선 UART interface를 만들었습니다. 이 interface를 이용해서 GPS Device Interface를 만들어 보겠습니다.

GpsUart.c 에는 다음과 같은 코드가 들어가야 합니다.

void CreatGpsUart(UartInterface *uart)
{
  uart->Open = GpsUartOpen;
  uart->TxHandler = GpsTxHandler;
  uart->RxHandler = GpsRxHandler;
}
void GpsUartOpen()
{
//
}
void GpsTxHandler()
{
//
}

void GpsRxHandler()
{
//
}

Rs232.c 에는 다음과 같은 코드가 들어가야 합니다.

CreatRs232Uart(UartInterface *uart)
{
  uart->Open = Rs232UartOpen;
  uart->TxHandler = Rs232TxHandler;
  uart->RxHandler = Rs232RxHandler;
}
void Rs232UartOpen()
{
//
}

void Rs232TxHandler()
{
//
}

void Rs232RxHandler()
{
//
}

이제 Main.c를 살펴보겠습니다.

UartInteface gGpsUart;
UartInteface gRs232Uart;

void main(void)
{
    CreatGpsUart(&gGpsUart);
    CreatRs232Uart(&gRs232Uart);

    //...
}

UartInterface를 통해 두가지 기능을 만들어 냈습니다. 



c# using문 입니다.

MSDN을 인용하여 using문을 설명 드리자면 IDisposable 객체의 올바른 사용을 보장하는 편리한 구문을 제공해 주는 것이 바로 using문 입니다.

File및 Font와 같은 클래스들은 관리되지 않는 리소스에 액세스 하는 대표적인 클래스들입니다. 
File및 Font와 같은 클래스들은 관리되지 않는 리소스에 액세스 하는 대표적인 클래스들입니다.
File및 Font와 같은 클래스들은 관리되지 않는 리소스에 액세스 하는 대표적인 클래스들입니다.
File및 Font와 같은 클래스들은 관리되지 않는 리소스에 액세스 하는 대표적인 클래스들입니다.
File및 Font와 같은 클래스들은 관리되지 않는 리소스에 액세스 하는 대표적인 클래스들입니다.
File및 Font와 같은 클래스들은 관리되지 않는 리소스에 액세스 하는 대표적인 클래스들입니다.

이 말은 해당 클래스들을 다 사용한 후에는 적절한 시기에 해제(Dispose)하여 해당 리소스(자원)을 다시 반납해야 하는 것입니다.

프로그래머가 프로젝트를 하면서 매번 관리되지 않는 리소스에 액세스 하는 클래스들을 체크하여 Dispose 하는 것을 많은 시간과 실수를 야기합니다..이때 바로 using문을 이용하면 해당 리소스 범위를 벗어나게 되면 자동으로 리소스(자원)을 해제(Dispose)하여 관리를 쉽게 도와 줍니다.

Using문 사용한 경우

using (Font font1 = new Font("Arial", 10.0f)) 
{
    byte charset = font1.GdiCharSet;
}

Using문 사용하지 않은 경우

{
  Font font1 = new Font("Arial", 10.0f);
  try
  {
    byte charset = font1.GdiCharSet;
  }
  finally
  {
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  }
}

Using문 사용한 경우

void Create()
{
int result;
using (StreamReader rdr = new StreamReader("CreateDB.sql"))
{
string sql = rdr.ReadToEnd();
SQLiteCommand cmd  = new SQLiteCommand(sql, Conn);

try
{
result = cmd.ExecuteNonQuery();
}
catch(SQLiteException ae)
{
Console.WriteLine(ae.ToString());
}
}
}

using문을 사용하면 프로그래머가 일일이 Dispose를 해주지 않아도 되고 로직도 간단해지는 것을 확인 하실 수 있습니다.







+ Recent posts